All posts by Thiyagu

How to write data to an xml file using Powershell

Recently, I came up with a requirement of updating an config file (Xml data) in our PROD environment without login in to the sever to avoid the manual error, which lead to create this post. Let we start this implementation by step by step, here I’m using the XmlDocument .Net object here but it is possible to utilize other .Net classes, e.g. XPath and/or XDocument.

Sample XML file (web.config) 

This is the sample Web.config file which is going to be use for this whole post. 

<configuration xmlns:patch="https://www.dotnet-helpers.com/xmlconfig/">
  <dotnet-helpers-tutorials>
    <tutorials name="tutorial:start">
      <Topics hint="list">
        <Topic>MVC</Topic>
        <Topic>Jquery</Topic>
        <Topic>OOPS</Topic>
      </Topics>
    </tutorials>
  </dotnet-helpers-tutorials>
</configuration>

STEP: #1 Creating XML Elements

Here my goal is to add the “Powershell” tutorial topic at end of all other topic (ie., after OOPS) in the above xml file (extension is .config file). First we need to load the XML document (physical location of web.config) as like below,

[xml]$XmlDocument = Get-Content -Path $FilePath

STEP: #2 Searching the XML Element in the XmlDocument:

Next we need to search for the element for updating our value in the .config file. Based on the input parameter $Selector, it applies the specified pattern-matching operation to this node’s context and returns the first matching node. If no nodes match the expression, the method returns a null value.

#$Selector : //tutorials[@name=’tutorial:start’]
$events = $XmlDocument.SelectSingleNode($Selector)
$topic = $events.Topics

After execution of the first line of code, the $events variable will hold the below elements (filtered based on the input value $Selector). In the next execution it filter with Topics and sassing to the @sites variable.

<tutorials name="tutorial:start">
<Topics hint="list">
<Topic>MVC</Topic>
<Topic>Jquery</Topic>
<Topic>OOPS</Topic>
</Topics></tutorials>

STEP: #3 Creating New XML Elements

Now we can create our new element/node (ie., <Topic>Powershell</Topic>) and append it to the parent reference. Then you an append the value for the New Element with help of InnerText.

$child = $XmlDocument.CreateElement(“Topic”)
$child.InnerText = $NewTutorialTopic

STEP: #4 Adding Nested XML Elements

Finally we need to add elements by appending and save to the loaded XML file

$topic.AppendChild($child)
$XmlDocument.Save($FilePath)

Final Code

#################################################################
#Project : How to write xml data to an xml file using powershell 
#Developer : Thiyagu S (dotnet-helpers.com)
#Tools : PowerShell 5.1.15063.1155 
#E-Mail : mail2thiyaguji@gmail.com 
##################################################################
function AddEntryInConfig($Selector, $FilePath , $NewTutorialTopic)
   {
      #Get the content of the file using the path
      [xml]$XmlDocument = Get-Content -Path $FilePath
      #Selecting all the childs by finding its parent with $Selector value
      $events = $XmlDocument.SelectSingleNode($Selector)
      #Assigning the chilld elements to variable
      $topics = $events.Topics
      #creating new Element with heading as "Topic"
      $child = $XmlDocument.CreateElement("Topic")
      #Assinging the value to the Element "Topic"
      $child.InnerText = $NewTutorialTopic
      #The appendChild method is used to add the data in the newly created XmlElement to the XmlDocument.
      $topics.AppendChild($child)
      #Save in to the file
      $XmlDocument.Save($FilePath)
      Write-Host "Saved into " $Selector -ForegroundColor Green        
   }

#Calling the Function and passing the required parameter
AddEntryInConfig  "//tutorials[@name='tutorial:start']"  'C:\PowerShell\web.config' "PowerShell"

OUTPUT 

Use PowerShell to create compressed ZIP files

In many scenarios, we will have a requirements for handling to create zip archives or extract files from existing archives with programmatically .  From PowerShell 5.0, it provided two cmdlet for creating and extracting zip files. The Compress-Archive cmdlet enables you to create new archives from folders or individual files to add files to archives; Extract-Archive can be used to unzip files. Let we get in to this with very two simple example.

Example #1 : Create an Simple archive file

The below command will zip the Dotnethelpers_PowershellArticles folder and create an archive called PowershellArticles.zip in the Archives folder:

–Path : Parameter to specify the folder/file path which you want to compress.
–DestinationPath : Parameter to specify the name of the archive.

############################################################ 
#Project : Simple Compress example
#Developer : Thiyagu S (dotnet-helpers.com) 
#Tools : PowerShell 5.1.15063.1155 
#E-Mail : mail2thiyaguji@gmail.com 
############################################################
Compress-Archive -Path C:\PowerShell\ZipTest\Dotnethelpers_PowershellArticles -DestinationPath C:\PowerShell\ZipTest\PowershellArticles.zip

Example: 2 : Create an archive file using -LiteralPath

The below command creates PowerShellMVCArticles.Zip file by compressing two folders that is Dotnethelpers_PowershellArticles and PowerShellMVCArticles.Zip specified by the LiteralPath parameter instead of -path cmdlet.

############################################################ 
#Project : Create an archive file using -LiteralPath and -Update 
#Developer : Thiyagu S (dotnet-helpers.com) 
#Tools : PowerShell 5.1.15063.1155 
#E-Mail : mail2thiyaguji@gmail.com 
############################################################
Compress-Archive -LiteralPath 'C:\PowerShell\ZipTest\Dotnethelpers_PowershellArticles', 'C:\PowerShell\ZipTest\Dotnet-helpers_MVC_Articles' -CompressionLevel Optimal -Update -DestinationPath CPowerShellMVCArticles.Zip
  • -LiteralPath: Instead of -Path cmdlet, here we can use multiple paths, and include files in multiple locations in your output zipped file
  • -Update : If you are not using the -update cmdlet for compressing the existing zip files, which having same name then poweshell will throw the below error. In this scenario we need to use -Update which will command the script to overwrite, if file is already existing in the same destination location and update compression with newer versions of existing files.
Compress-Archive : The archive file C:\PowerShell\ZipTest\PowerShellMVCArticles.Zip already exists. Use the -Update parameter to update the existing archive file or use the -Force 
parameter to overwrite the existing archive file.
At line:2 char:1
+ Compress-Archive -LiteralPath 'C:\PowerShell\ZipTest\Dotnethelpers_Po ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (C:\PowerShell\Z...MVCArticles.Zip:String) [Compress-Archive], IOException
    + FullyQualifiedErrorId : ArchiveFileExists,Compress-Archive
  • -CompressionLevel : Here i had mentioned the compression level as Optimal, this indicate how much compression to apply when you are creating the archive file. If compression level parameter is not specified in our script the the command uses the default value as Optimal.

Fastest: This method available to decrease processing time; this can result in larger file sizes.
NoCompression: Do not compress the source files.
Optimal: Processing time is dependent on file size.

OUTPUT

What do you think?

I hope you have an idea of  How to Use PowerShell to create compressed ZIP files. I would like to have feedback from my posts readers. Your valuable feedback, question, or comments about this article are always welcome.

How to Use Multidimensional arrays in Powershell

Before I show you how multi-dimensional arrays work, let we start what is an array. By default, PowerShell assumes that the elements of an array are of the type variant. This means that you can mix different data types—that is, combine numerical values, dates, or strings in a single variable. The data elements of a PowerShell array need not be of the same type, unless the data type is declared (strongly typed). However, if you think to restrict an array to a certain data type then you can declare the array as like below:

In simpler as like other languages, PowerShell arrays store one or more items. An item can be any data type like string, integer, another array or a generic object.

Multidimensional arrays are one of the complex data types supported by PowerShell. In simple let you imagine a multidimensional array like a table, with columns and rows, where each cell has its own index like [1,16). Each time we put a comma, we are like telling Powershell to start a new row in the multidimensional array

Here let we discuss about the Two dimensional array with example. As shown above, the Elements in two-dimensional arrays are commonly referred by x[i][j] where i is the row number and ‘j’ is the column number. A two-dimensional array can be seen as a table with ‘x’ rows and ‘y’ columns where the row number ranges from 0 to (x-1) and column number ranges from 0 to (y-1). A two – dimensional array ‘x’ with 3 rows and 3 columns is shown below:

Note:

The Powershell start a new row in the multidimensional array when we apply the comma in starting of new row as shown below.

$scoreDetails = @( @(‘Aadharsh’, ‘200’), @(‘Rakshu’, ‘199’) )
$scoreDetails+= ,(@(“Anitha”,150))

Example

############################################################
#Project : How to Use Multidimensional arrays in Powershell
#Developer : Thiyagu S (dotnet-helpers.com)
#Tools : PowerShell 5.1.15063.1155 
#E-Mail : mail2thiyaguji@gmail.com 
############################################################

#For working with a large collection of items i would recommend using the ArrayList type from .NET as this is not a fixed size array so PowerShell will not destroy it every time you add an item to it and i've found this to work better in my projects.

System.Collections.ArrayList]$scoreDetails = @()
$scoreDetails = @( @('Aadharsh', '200'), @('Rakshu', '199') )

#Get user input and ADD to multi-dimensional array
Write-Host "Enter NEXT person score details"
$name = Read-Host "Name"
$score = Read-host "Score"
#Each time we put a comma, we are like telling Powershell to start a new row in the multidimensional array
$scoreDetails+= ,(@($name,$score))

for($parentLoop=0; $parentLoop -lt 3; $parentLoop++)
{
for($childLoop=0; $childLoop -lt 2 ; $childLoop++)
{
"The value of [$parentLoop][$childLoop] ---> " +$scoreDetails[$parentLoop][$childLoop]
}

}

OUTPUT:

What do you think?

I hope you have an idea of  How to Use Multidimensional arrays in Powershell. I would like to have feedback from my posts readers. Your valuable feedback, question, or comments about this article are always welcome.

Reading XML Files With PowerShell

Handling XML with PowerShell is very simple. It converts XML elements to properties on .NET objects without the need to write any parsing code. So it is very easy to use XML with PowerShell. Here we are going to discuss how to read the XML file values in different ways.

You can also read  How to add values to the string array from xml using Powershell and  How to write data to an xml file using Powershell 

A Quick Example

XML File : MyXM.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<EmpDetails>
	<Person>
		<Id>E00023</Id>
		<mailId>Aadharsh@dotnet-helper.com</mailId>
		<empName>Aadharsh G.K</empName>		
	</Person>
	<Person>
		<Id>E00042</Id>
		<mailId>Rakshu@dotnet-helper.com</mailId>
		<empName>RakshaNivasini S.T</empName>		
	</Person>
</EmpDetails>

Method 1:

Once you’ve run Get-Content to read the raw text from the XML document and cast the output to type [XML], you now have a variable called $XmlDocument that contains the entire XML node tree which we can process.

STEP  #1: Assign the XML file location into the variable.

$XMLfile = ‘C:\donet-helpers\Demo\MyXM.xml’

STEP  #2: Read the xml file using get-content cmdlet and assign to variable. The [xml] casts the variable as an XML object.

[XML]$empDetails = Get-Content $XMLfile

STEP  #3: Looping the child node to get the value.

foreach($empDetail in $empDetails.EmpDetails.Person){ }

Final Code:

############################################################
#Project : Reading XML files with PowerShell
#Developer : Thiyagu S (dotnet-helpers.com)
#Tools : PowerShell 5.1.15063.1155 
#E-Mail : mail2thiyaguji@gmail.com 
############################################################
$XMLfile = 'C:\D_EMS Drive\Personal\LBLOG\testpath.xml' [XML]$empDetails = Get-Content $XMLfile foreach($empDetail in $empDetails.EmpDetails.Person){ Write-Host "Employee Id :" $empDetail.Id Write-Host "Employee mail Id :" $empDetail.mailId Write-Host "Employee Name :" $empDetail.empName Write-Host '' }

OUTPUT:

Method 2:

STEP  #1: Assign the XML file location into the variable.

$Path = “C:\donet-helpers\Demo\MyXM.xml”

STEP  #2: The below command saves the XML path to the AliasProperty node in the $XPath variable.

$XPath = “/EmpDetails/Person”

STEP  #3: The Select-Xml cmdlet lets you use XPath queries to search for text in XML strings and documents. Enter an XPath query, and use the Content, Path, or Xml parameter to specify the XML to be searched.

Select-Xml -Path $Path -XPath $Xpath | Select-Object -ExpandProperty Node

Final Code:

############################################################
#Project : Reading XML files with PowerShell
#Developer : Thiyagu S (dotnet-helpers.com)
#Tools : PowerShell 5.1.15063.1155 
#E-Mail : mail2thiyaguji@gmail.com 
############################################################
$Path = "C:\D_EMS Drive\Personal\LBLOG\testpath.xml" $XPath = "/EmpDetails/Person" Select-Xml -Path $Path -XPath $Xpath | Select-Object -ExpandProperty Node

 

What do you think?

I hope you have an idea of how to Reading XML Files With PowerShell. I would like to have feedback from the readers of my posts. Your valuable feedback, question, or comments about this article are always welcome.

Creating HTML report with CSS (Cascading Style Sheet) using Powershell

All Tech/non Tech peoples loves a nice HTML report for reviewing. Creating these type of reports in PowerShell is very easy and simple. These type of nice HTML reports can be generate with the help ConvertTo-HTML cmdlet. Converts Microsoft .NET Framework objects into HTML that can be displayed in a Web browser. The ConvertTo-HTML does not create an actual file, just the HTML code.This means that we can modify the HTML on the fly and save the file when finished. 

For this simple report i had used only few properties like -CssUri , -Postcontent and -PreContent from the ConvertTo-HTML cmdlet.

Pre/Post Content

Usually we will create table and generate content with the help of ConvertTo-HTML cmdlet. But if you want to insert additional HTML directives to put in before and after the main code. This can be achieve using “-PreContent” and “-PostContent” cmdlet.

-PreContent : Specifies text to add before the starting tag. By default, there is no text in that position

-PostContent : Specifies text to add after the closing tag. By default, there is no text in that position

CssUri

Specifies the Uniform Resource Identifier (URI) of the cascading style sheet (CSS) that is applied to the HTML file. The URI is included in a style sheet link in the output.

Final code:

Here i had wrote the required CSS code for the report and placed the below code in notepad and saved with the name C:\dotnet-helpers\design.css. The same CSS will be called during the report generation. So the style will be applied to the final HTML report.

body { background-color:#E5E4E2;
font-family:Monospace;
font-size:10pt; }
table,td, th { border:1px solid black;}
th { color:#00008B;
background-color:white; 
font-size: 12pt;}

table { margin-left:30px; }
h2 {
font-family:Tahoma;
color:#6D7B8D;
}
h1{color:#DC143C;}
h5{color:#DC143C;}

In the below script I’m adding style from an external CSS file with help of -CssUri parameter (-CssUri ‘C:\temp\design.css’) and generating the HTML report in the destination location. The CSS from the file will applied to the HTML element during the execution and generate the report as like below.

Get-Eventlog -List | Select @{Name="Logs";Expression = {$_.LogDisplayname}} , 
@{Name="Entries";Expression = {"{0:n0}" -f $_.entries.count}} |
#Converts Microsoft .NET Framework objects into HTML that can be displayed in a Web browser.
#the Title, Body, PreContent, and PostContent parameters of ConvertTo-Html to customize the output..
convertto-html -Title "Daily Log Report" -PreContent "<H1>Daily Event Log Report : $($env:COMPUTERNAME)</H1>" -PostContent "<H5><i>Copy right @ dotnet-helpers.com</i></H5>" -CssUri 'C:\dotnet-helpers\design.css' |
Set-Content C:\dotnet-helpers\DailyLogReport.htm

Output:

Move files to another directory Based on Filename with Powershell

Where this code required?

In many scenario, we will got the requirement for moving the specific files from the large number of files from one location to another location based some filter  on the file name. This code will helps with same situation. The below code will split the filename before “-” and compare the existing list “filterLists” to find 

STEP #1

Declare the souce and target path locations.

$srcpath = “C:\Powershelltest\Source”
$dstpath = “C:\Powershelltest\Destination”

STEP #2

Fetch all the child file list to make the loop to start the validation of each files.

$fileList = Get-ChildItem -Path $srcpath -Force -Recurse
foreach ($file in $fileList)
{
}

STEP #3

Second level of loop for validating whether filename is mathing with our input

foreach($filelist in $filterLists)
{
#Our Logic
}

Complete Code

############################################################
#Project : Move files to another directory by File name filter
#Developer : Thiyagu S (dotnet-helpers.com)
#Tools : PowerShell 5.1.15063.1155 
#E-Mail : mail2thiyaguji@gmail.com 
############################################################
#set Source and Destination folder location
$srcpath = "C:\Powershelltest\Source"
$dstpath = "C:\Powershelltest\Destination"
#Set the files name which need to move to destination folder
$filterLists = @("70022333","70022867")

#Get all the child file list with source folder
$fileList = Get-ChildItem -Path $srcpath -Force -Recurse
#loop the source folder files to find the match
foreach ($file in $fileList)
{
#checking the match with filterlist
foreach($filelist in $filterLists)
{
#$key = $file.BaseName.Substring(0,8)
#Spliting value before "-" for matching with filterlists value
$splitFileName = $file.BaseName.Substring(0, $file.BaseName.IndexOf('-'))

if ($splitFileName -in $filelist)
{
$fileName = $file.Name

Move-Item -Path $($file.FullName) -Destination $dstpath
}
}
}

Output

After Execution

What do you think?

I hope you have an idea of  Move files to another directory Based on Filename with Powershell. I would like to have feedback from my posts readers. Your valuable feedback, question, or comments about this article are always welcome.

How to Find Out Specifications of Server Using PowerShell

When you are running a Windows server and you need to find out the specification of your servers  then this tutorial will helps you to achieve with the help of PowerShell script.

Step 1#: Open PowerShell with secific privileges.

Step 2#: Execute below script to get the specifications of the Servers

Get-wmiobject win32_computersystem
Get-WmiObject win32_processor

Explanation :

Get-wmiobject : Gets instances of WMI classes or information about the available classes.
win32_computersystem: The Win32_ComputerSystem WMI class represents a computer system running Windows.
win32_processor : Its WMI class represents a device that can interpret a sequence of instructions on a computer running on a Windows operating system.

OUTPUT:

What do you think?

I hope you have an idea of  How to Find Out Specifications of Server Using PowerShell. I would like to have feedback from my posts readers. Your valuable feedback, question, or comments about this article are always welcome.

Upload files with Powershell GUI

In many scenarios, we will get the requirement to upload the reports, tracker from one location to another location , so i decided to write this post to explain how to upload files like excel, txt… with the help of Powershell GUI. Instead of thinking high level, here i had split the three simple task to achieve the file upload functionality in the Powershell.

  1. Create Simple PowerShell UI for browsing the location of files  with one textbox and two button type (upload & cancel) with help of system.Windows.Forms
  2. In Browse button click event, you can perform the browse with the specific file that need to be upload to destination folder using New-Object -TypeName System.Windows.Forms.OpenFileDialog. These make the selection of files or folders easy for users and prevent mistakes being made in file paths.
  3. In upload button click event, you can perform the Move action on the selected file to place on Target location.

When designing PowerShell scripts, I have often found it useful to incorporate a file or folder dialogue to select files or folders. These make the selection of files or folders easy for users and prevent mistakes being made in file paths.

Example:

####################################################### 
#Project      :    Upload the files using Powershell 
#Developer    :    Thiyagu S (dotnet-helpers.com)
#Tools        :    PowerShell 5.1.15063.1155 
#E-Mail       :    mail2thiyaguji@gmail.com 
####################################################### 
#Form class
$Forms = 'system.Windows.Forms.Form'
#Button class
$Button = 'system.Windows.Forms.Button'
#Getting the font details for applying the fields
$FontStyle = 'Microsoft Sans Serif,10,style=Bold'
$SysDrawPoint = 'System.Drawing.Point'
# setting InitialDirectory which open as intially during the click of browse button
$InitialDirectory = "C:\New folder"
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()

#The New-Object cmdlet creates an instance of a .NET Framework or COM object.
#Specifies the fully qualified name of the .NET Framework class. You cannot specify both the TypeName parameter and the ComObject parameter.

$TrackerFileUpload = New-Object -TypeName $Forms
$TrackerFileUpload.ClientSize = '400,114'
$TrackerFileUpload.text = 'dotnet-helpers.com - Please upload Daily Tracker'
$TrackerFileUpload.TopMost = $false

$txtFileName = New-Object -TypeName system.Windows.Forms.TextBox
$txtFileName.width = 280
$txtFileName.height = 20
$txtFileName.location = New-Object -TypeName $SysDrawPoint -ArgumentList (107,39)
$txtFileName.Font = $FontStyle

$btnFileBrowser = New-Object -TypeName $Button
$btnFileBrowser.BackColor = '#1a80b6'
$btnFileBrowser.text = 'Browse'
$btnFileBrowser.width = 96
$btnFileBrowser.height = 30
$btnFileBrowser.location = New-Object -TypeName $SysDrawPoint -ArgumentList (200,78)
$btnFileBrowser.Font = $FontStyle
$btnFileBrowser.ForeColor = '#ffffff'

$btnUpload = New-Object -TypeName $Button
$btnUpload.BackColor = '#00FF7F'
$btnUpload.text = 'Upload'
$btnUpload.width = 96
$btnUpload.height = 30
$btnUpload.location = New-Object -TypeName $SysDrawPoint -ArgumentList (291,78)
$btnUpload.Font = $FontStyle
$btnUpload.ForeColor = '#000000'

$lblFileName = New-Object -TypeName system.Windows.Forms.Label
$lblFileName.text = 'Choose File'
$lblFileName.AutoSize = $true
$lblFileName.width = 25
$lblFileName.height = 10
$lblFileName.location = New-Object -TypeName $SysDrawPoint -ArgumentList (20,40)
$lblFileName.Font = $FontStyle

#Adding the textbox,buttons to the forms for displaying
$TrackerFileUpload.controls.AddRange(@($txtFileName, $btnFileBrowser, $lblFileName, $btnUpload))

#Browse button click event
$btnFileBrowser.Add_Click({
Add-Type -AssemblyName System.windows.forms | Out-Null
#Creating an object for OpenFileDialog to a Form
$OpenDialog = New-Object -TypeName System.Windows.Forms.OpenFileDialog
#Initiat browse path can be set by using initialDirectory
$OpenDialog.initialDirectory = $initialDirectory
#Set filter only to upload Excel file
$OpenDialog.filter = '.xlsx (*(.xlsx)) | *.xlsx | *.txt'
$OpenDialog.ShowDialog() | Out-Null
$filePath = $OpenDialog.filename
#Assigining the file choosen path to the text box
$txtFileName.Text = $filePath 
$TrackerFileUpload.Refresh()
})
#Upload button click eventy
$btnUpload.Add_Click({
#Set the destination path
$destPath = 'C:\EMS\Destination'
#$txtFileName.Text = ""
Copy-Item -Path $txtFileName.Text -Destination $destPath
})

$null = $TrackerFileUpload.ShowDialog()
$txtFileName.Text = ""

Output:

What do you think?

I hope you have an idea of  How To upload the files with help of PowerShell GUI. I would like to have feedback from my posts readers. Your valuable feedback, question, or comments about this article are always welcome.

How To Create Progress Bars in PowerShell

Mostly No one have interest to wait for some time to complete the work/task/execution.But in certain situation, that’s is not always possible to completed the task without waiting for few seconds/Minutes. In Powershell if you wrote some automation and if sometimes it will to be take more time to execution due to gathering lot of information from then, reality, the script will take a time to complete.

In this scenario the script writer need to show some progress bar to indicate the user about the progress instead of blinking cursor at the delay. This can be achievable by using Write-Progress cmdlet which Displays a progress bar within a Powershell command window.

Syntax:

Write-Progress
[-Activity] <String>
[[-Status] <String>]
[[-Id] <Int32>]
[-PercentComplete <Int32>]
[-SecondsRemaining <Int32>]
[-CurrentOperation <String>]
[-ParentId <Int32>]
[-Completed]
[-SourceId <Int32>]
[<CommonParameters>]

Example:

############################################################
#Project : How To Create Progress Bars in PowerShell
#Developer : Thiyagu S (dotnet-helpers.com)
#Tools : PowerShell 5.1.15063.1155 
#E-Mail : mail2thiyaguji@gmail.com 
############################################################

$progressTimes = 20
$ioop_index = 0
for ($ioop_index=0;$ioop_index -lt $progressTimes; $ioop_index++) {

$completeStatus = ($ioop_index / $progressTimes) * 100
#Write-Progress: Displays a progress bar within a PowerShell command window.
#-Activity: Specifies the first line of text in the heading above the status bar. This text describes the activity whose progress is being reported.
#-Status: Specifies the second line of text in the heading above the status bar. This text describes current state of the activity.
#-PercentComplete: This command displays the progress of a For loop that counts from 1 to 20. 
Write-Progress -Activity 'in Progress' -Status "Did thing $ioop_index times" -PercentComplete $completeStatus -SecondsRemaining ($progressTimes-$ioop_index)
#Suspends the activity in a script or session for the specified period of time.
Start-Sleep 1

}

Output:

What do you think?

I hope you have an idea of  How To Create Progress Bars in PowerShell. I would like to have feedback from my posts readers. Your valuable feedback, question, or comments about this article are always welcome.

Add text to Word Using PowerShell

For most of the automation and report we will prefer and use Excel , instead of excel her we look at how you can use Word with PowerShell to create a document.One of the first things that you need to do is ensure that you have Word installed on your computer. Once you have that verified, we can begin by creating a COM object connection to Word.Application, which will help us to begin the interacting with Word.

Running the below script that was just looking to create the document without showing anything, and making Visible property on the object to True. So after creating this object ($word) which will help to interacting with Word and its ready for our operations.

$word=new-object -ComObject “Word.Application”
$Word.Visible = $True

Before using edit on the word document before that, we need to add a document to our Word object and then select it so we can being adding text to it.

$doc = $word.documents.Add()
$myDoc = $word.Selection

Now we are ready to begin to edit and start writing in our Word document.Here i am going to generate the comments document from the PowerShell script, so you can achieve this using the TypeText() method, which is available on $myDoc object.

If we use of the TypeText method, the we need to understand the text will appear on the same line as the rest of the text. So we need to use the TypeParagraph method which use to start on a new line like break tag in HTML and then you use TypeText to begin writing on a brand-new line.

$myDoc.Style=”Strong”
$myDoc.TypeParagraph()
$myDoc.TypeText(“Hi All, “)
$myDoc.TypeParagraph()
$myDoc.TypeText(“This is Message from dotnet-helpers.com “)

Final Code:

####################################################### 
#Project : Writing in Word doc using Powershell 
#Developer : Thiyagu S (dotnet-helpers.com)
#Tools : PowerShell 5.1.15063.1155 
#E-Mail : mail2thiyaguji@gmail.com 
####################################################### 

$savepath="C:\dotnet-helpers\ReviewCommends.docx" 

$word=new-object -ComObject "Word.Application"
$Word.Visible = $True

$doc = $word.documents.Add() 
$myDoc = $word.Selection

$myDoc.Style="Strong" 
$myDoc.Font.Bold = 1
$myDoc.TypeParagraph()
$myDoc.TypeText("Hi All, ") 
$myDoc.TypeParagraph()
$myDoc.TypeText("This is Message from dotnet-helpers.com ")

$myDoc.Style="Normal" 
$myDoc.Font.Italic = 1
$myDoc.TypeParagraph() 
$myDoc.TypeText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor.Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes,nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu,
pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel,aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae") 

$myDoc.TypeParagraph() 
$myDoc.TypeParagraph() 
$myDoc.TypeText("Thanks") 
$myDoc.TypeParagraph() 
$myDoc.Style="Strong" 
$myDoc.TypeText("Thiyagu S") 
$myDoc.TypeParagraph() 
$Date = Get-Date 
$myDoc.TypeText("Date: $($Date)") 

$doc.SaveAs([ref]$savepath) 
$doc.Close() 

$word.quit() 
Invoke-Item $savepath

#Here you want to release all of these objects, so here we call the ReleaseComObject method, so we doing this each of objects which created. 
#then you need to call garbage collection to scavenge memory, and I remove the variables.

[System.Runtime.Interopservices.Marshal]::ReleaseComObject($doc) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($word) | Out-Null
Remove-Variable doc,Word
[gc]::collect()
[gc]::WaitForPendingFinalizers()

OUTPUT