This PowerShell tutorial is based on my book with the same title. You can get the book on Amazon.
There are 4 articles with a total of 7 tutorials. This is PowerShell Tutorial 5 & 6 of 7. If you have not read PowerShell tutorials 1, 2, 3 & 4, I recommend you read them before reading these tutorials.
PowerShell Tutorial 5: Commenting and Breaking Scripts
When writing PowerShell scripts, it is a good practice to add comments to your scripts. Comments are not executed by PowerShell – they are usually for information purposes.
Moreover, comments allow you to explain why you added a particular command in a certain way.
Comments might be for you or for any other person reviewing your scripts. PowerShell tutorial 5 teaches you how to add comments and different ways you can do this.
Additionally, this tutorial will also teach you how to break your scripts. ‘Breaking’ a script means to stop execution.
There are so many reasons you might want to break a script. You might test a condition and if that condition is not met, you might decide to stop executing the script.
At the end of this tutorial, you will discover reasons you might want to break your scripts and learn how to break PowerShell scripts.
You will also lean about the Escape (‘backtick’) character; its applications in PowerShell scripting and how to use them. Finally, this tutorial will teach you how to use comments to add help to your Functions.
Commenting in PowerShell Script
If you need to add a comment to a PowerShell script, start the line with the hash sign (#). PowerShell will treat anything you add after the hash sign as a comment.
This means that any line in your PowerShell script preceded by the hash sign (#) will not be executed as a command.
Different Methods to Add Comments in PowerShell
In PowerShell, there are two methods you can add comments. You can use a single hash sign (#) for a single line comment. For example, if I want to add ‘This is a comment, I will add the following lines to my PowerShell ISE editor #This is a comment.
To different a comment line from other codes, the scripting editor displays the comment in green. To demonstrate this difference, I will add a comment line to the CreateMyPSModulePath script we created in PowerShell Tutorial 4.
As shown in the screenshot above, the two comments lines are displayed in green. However, the PowerShell codes are displayed in other colors.
The method of adding comments is used to add one comment per line. If you want to add a comment block, start the block enter the less than key (<), followed by a hash sign.
<#
Then, add your comments. It is neater to add the comments from the next line…
<# This script checks if the path, \WindowsPowerShell\Modules exisist If the path does not exist, it will be created
Finally, close the comment block by adding another hash sign (#), followed by a greater than sign (>).
<# This script checks if the path, \WindowsPowerShell\Modules exisist If the path does not exist, it will be created #>
To make it real, I will enter the above comment to the CreateMyPSModulePath script.
Like comments in a single line, comments in a comment block are also displayed in green. One major difference though is that you can minimize comments in a block.
To minimize comments in a block, click the minus sign on the top left of the block. The comments in the block will be hidden – see the second screenshot below.
Hiding comments in a comment block can be very useful if you wish to minimize the number of texts displayed in a long PowerShell script.
How to Conditionally Break a PowerShell Script
There are circumstances when you may need to stop a script from executing if a condition is met. When PowerShell is executing a script and gets to the reserved word ‘Break’, the script will be exited.
Without breaking a script, it will continue to execute to the end of the script. You might need to break a script if the next set of commands depend on the output of a command to continue successfully.
I have used ‘Break’ in several scripts and functions. Typically, I use ‘Break’ to stop my script executing if I need to call inputs from a text file. I will normally check whether the file the user entered is a valid text file.
If the user specifies a valid text file, the script will continue. Otherwise, if the user specifies an invalid text file for example a folder path, the script will exit and an error message will be displayed on the console explaining why the script exited.
To illustrate how conditional PowerShell script breaking works, I have created a text file called websites. If you want to practice this demo, create a text file with the same name.
The first step to adding a conditional break is to get the text file with the Get-ChildItem command and add the result to a variable.
$TextFile = Get-ChildItem D:\PS-Tutorial\websites.txt -ErrorAction SilentlyContinue
Then, use this final script to test if the file is a valid text file (has a .txt file extension). In the final parts of the script, if the text file is a valid text file, we list the content with the Get-Content command.
If ($TextFile.Extension -eq '.txt') {$WebsiteNames = Get-Content $TextFile } Else { Write-Host "The text file you entered is not a valid text file." -ForegroundColor Red Break }
Otherwise, if the text file is not valid, the script will execute the Else block. Within the Else block, we display an error message explaining why the script will not continue – then we add our Break.
Here is the final script. To run the script, copy it to a new PowerShell ISE document and click Run.
$TextFile = Get-ChildItem D:\PS-Tutorial\websites.txt -ErrorAction SilentlyContinue If ($TextFile.Extension -eq '.txt') {$WebsiteNames = Get-Content $TextFile } Else { Write-Host "The text file you entered is not a valid text file." -ForegroundColor Red Break }
How to Use the Escape (Backtick) Character in PowerShell
As you script in PowerShell, you will discover that sometimes a line of code might become too long to stay in a single line.
In such circumstances, you may decide to move parts of the code to the next line. The backtick character (`) is used to accomplish this. The backtick character is the key just below the Esc key on your keyboard.
In Windows PowerShell, the backtick (`) is called the escape character. This character can be used to indicate a literal, to indicate line continuation, or to indicate special characters.
The escape character tells Windows PowerShell that the command continues on the next line.
To show you how this works, I will use the first line of the last script…
$TextFile = Get-ChildItem D:\PS-Tutorial\websites.txt -ErrorAction SilentlyContinue
I want to move everything after Get-ChildItem to the next line. To do this, I will add the backtick (`) after Get-ChildItem, then press the enter key to move every other thing to the next line.
$TextFile = Get-ChildItem ` D:\PS-Tutorial\websites.txt -ErrorAction SilentlyContinue
When you run this script, it will script execute as a single command. Without the backtick, both lines may throw errors because none of them is a valid PowerShell command.
How to Use Comments to Add Help to Functions
In PowerShell tutorial 4.1, we discussed PowerShell functions. Additionally in tutorial 1, we saw how the Get-Help command can provide information about Cmdlets.
In PowerShell tutorial 5.0, we said that the symbol <# #> is used to add block comments. These same symbols can be used to add help information to a POwerShell function.
This tutorial will teach you how to add help information to your functions. When you add help to your function – when a user runs Get-Hell Your-Function-Name – the help information is displayed for the user.
As discussed in tutorial 4.1, the simplified form of the syntax of a PowerShell function is:
Function <name> { [type]$parameter1, [type]$parameter2, [type]$parameter3 <statement list> }
When we discussed the Get-Help command, we said that the help information is displayed under the following sections: NAME, SYNOPSIS, SYNTAX, DESCRIPTION, RELATED LINKS and REMARKS.
To proceed with this tutorial, I will add help information to my CreateMyPSModulePath script. First, let’s convert the script into a function.
Here is the original script:
$PSModulePath = [environment]::getfolderpath("mydocuments") + "\WindowsPowerShell\Modules" If ((Test-Path $PSModulePath) -eq $false) {New-Item -Path "$PSModulePath" -ItemType Directory -Force | Out-Null }
To convert it into a function, I will start with the word “Function”, followed by the name of the function. I will name the function Create-PSModulePath.
The function will look like this…
Function Create-PSModulePath { $PSModulePath = [environment]::getfolderpath("mydocuments") + "\WindowsPowerShell\Modules" If ((Test-Path $PSModulePath) -eq $false) {New-Item -Path "$PSModulePath" -ItemType Directory -Force | Out-Null } }
To make it easy to spot the difference between this last modification and the original script, I boldened the new lines added. The final step is to add the help information to the function.
Follow the steps below to add the help block:
- Just after the opening bracket ‘{‘ of the function, enter a comment block – <# #>.
Function Create-PSModulePath { <# #> $PSModulePath = [environment]::getfolderpath("mydocuments") + "\WindowsPowerShell\Modules" If ((Test-Path $PSModulePath) -eq $false) {New-Item -Path "$PSModulePath" -ItemType Directory -Force | Out-Null } }
- Next, add the NAME section of the help. To do this, within the comment block, add a period (.), followed by the word NAME. Finally, beneath NAME, add Create-PSModulePath.
Function Create-PSModulePath { <# .NAME Create-PSModulePath #> $PSModulePath = [environment]::getfolderpath("mydocuments") + "\WindowsPowerShell\Modules" If ((Test-Path $PSModulePath) -eq $false) {New-Item -Path "$PSModulePath" -ItemType Directory -Force | Out-Null } }
- Repeat step 2 to add the SYNOPSIS section of the help. Note that this section gives the user a short description of what the function does.
Function Create-PSModulePath { <# .NAME Create-PSModulePath .SYNOPSIS Creates the Modules Folder if it does not exist #> $PSModulePath = [environment]::getfolderpath("mydocuments") + "\WindowsPowerShell\Modules" If ((Test-Path $PSModulePath) -eq $false) {New-Item -Path "$PSModulePath" -ItemType Directory -Force | Out-Null } }
Hopefully, you get the gist. When you finish adding all the sections of the help block, save the function as Create-PSModulePath.
References and Further Reading for PowerShell Tutorial 5
This tutorial is based on my book with the same title. You can get it from Amazon.
PowerShell Tutorial 6: PowerShell Operators
As you progress with PowerShell, you will need to perform some simple arithmetic operations. You will also definitely need to perform some comparison operations.
When performing arithmetic and comparison operations you will almost certainly require a third set of operators – logical operators.
This tutorial will introduce you to PowerShell operators. These operators help you perform comparisons, simple calculations, and more.
Comparison Operators
Let’s start this section by running the command below:
Get-WmiObject win32_logicaldisk
The command lists all the disk partitions on my PC. Unfortunately, the information is not very helpful.
To explain Comparison Operators (this tutorial), Arithmetic And Logical Operators (next tutorial), I will use the previous command as a baseline to create a PowerShell script that reports free disk space on a computer.
PowerShell comparison operators allow you to specify conditions for comparing object values. Furthermore, comparison operators are used to filter PowerShell results that match specified patterns.
Take another look at the output of the last command. Each listed drive has a value called DriveType.
In the screenshot, I highlighted DriveType with a value of 3. I also highlighted another DriveType with a value of 4.
The DriveType with a value of 3 is a local disk partition. However, the DriveType with a value of 4 is a mapped drive.
When you run a disk report, you want to return only local drive partitions in your report. To accomplish this, I will use a comparison operator, ‘eq’ to display only disks with DriveType of 3.
Here is the command that does this job:
Get-WmiObject win32_logicaldisk | Where-Object {$_.DriveType -eq '3'}
The first portion of the command (before the pipeline ‘|’) is the original command we ran earlier. The second part uses the Where-Object Cmdlet display disks with DriveType equals 3.
Here is the result of the command in PowerShell:
If you read this PowerShell Tutorial from the beginning, you will recognize the pipeline ‘|’ and the automatic variable ‘$_’.
Moving on, let me introduce two more comparison operators (le and -match). We can use these two operators in the last command to produce the same result.
Here are the two commands:
Get-WmiObject win32_logicaldisk | Where-Object {$_.DriveType -le '3'}
Get-WmiObject win32_logicaldisk | Where-Object {$_.DriveType -match '3'}
The first command tells PowerShell to display drives with DriveType less than or equal to 3. However, the second command says to display drives with DriveType value that match 3.
For the purpose of this tutorial, let’s stick with the original command.
Get-WmiObject win32_logicaldisk | Where-Object {$_.DriveType -eq '3'}
Before you proceed, enter the command into a new PowerShell ISE document and save the script as Get-FreeDiskSpace.
Arithmetic and Logical Operators
Open the script you saved in the previous tutorial (Get-FreeDiskSpace.psm1) in the PowerShell ISE editor. Then, amend it as shown below:
Get-WmiObject win32_logicaldisk | Where-Object {$_.DriveType -eq '3' ` -and ($_.FreeSpace/$_.Size) -le '0.1' }
The difference between this command and the previous one is this line:
-and ($_.FreeSpace/$_.Size) -le '0.1'
This bit of the command introduced two more PowerShell operators – the arithmetic operator ‘/’ and the logical operator ‘and’.
The ‘and’ logical operator combined the first command within the original Where-Object block – $_.DriveType -eq ‘3’ – and the newly introduced command – ($_.FreeSpace/$_.Size) -le ‘0.1’.
The final result is the Where-Object block with the two commands joined by the ‘and’ the logical operator:
Where-Object {$_.DriveType -eq '3' -and ($_.FreeSpace/$_.Size) -le '0.1' }
The ‘and’ the logical operator tells PowerShell that the TWO conditions MUST be TRUE to return the result. I suppose by now, you would have guessed that there is another PowerShell logical operator, ‘or’.
If you did, you will be right. The PowerShell ‘or’ the logical operator returns any result that meet either of the conditions.
If if we replaced ‘and’ with ‘or’, we would get a different output. For now, though we will stick with the command with the ‘and’ operator.
Modify your script to look like this:
Get-WmiObject win32_logicaldisk | Where-Object {$_.DriveType -eq '3' -and ($_.FreeSpace/$_.Size) -le '0.1' }
You may also move the Where-Object block to the next line by adding a backtick.
Get-WmiObject win32_logicaldisk | ` Where-Object {$_.DriveType -eq '3' -and ($_.FreeSpace/$_.Size) -le '0.1' }
So far, I have explained the command on the left side of the ‘and’ operator. I will not explain the command on the right side of the ‘and’ operator –
($_.FreeSpace/$_.Size) -le '0.1'
The command uses the arithmetic operator ‘/’ to divide the FreeSpace in each drive with the total Size of the drive – turning it into a percentage value.
Then, the less than or equal ‘le’ comparison operator compares the result of the FreeSpace divided by the total Size – with ‘0.1’ (10%) – and only returns partitions with percentage free space greater than or equal 10%.
In conclusion, Arithmetic operators calculate numeric values (add, subtract, multiply, or divide) while Logical operators connect expressions and statements.
On the contrary, Logical operators allow you to test multiple conditions in a single command.
As I explained earlier, in our previous command, the ‘and’ logical operator connected the statements “$_.DriveType -eq ‘3’” and “($_.FreeSpace/$_.Size) -le ‘0.1’”.
Without the use of the ‘and’ operator, we would have had to execute two separate commands to achieve the same objective.
Split and Join Operators
While the ‘Split’ operator breaks one or more strings into substrings (parts), the ‘Join’ operator links a set of strings into a single string.
To help explain PowerShell ‘Split’ operator, I will share my experience with a script I build sometime ago.
The script updates an Active Directory user’s attributes using values in a CSV file. One of the attributes updated is the user’s manager’s filed. However, the ‘Manager’ column in the CSV file is provided in ‘FirstName LastName’ format.
To be able to update a user’s ‘Manager’ attribute in Active Directory, the manager name must be converted to DistinguishedName (DN) format.
However, to convert the manager’s name from ‘FirstName LastName’ to DistinguishedName format, I had to use the Get-ADUser command. Here is a sample command:
Get-ADUser -Server ServerName -Filter {name -like 'managername*'} -Credential DomainName\administrator
Unfortunately, when I executed the command, some of the names in the manager column on the CSV were not found. It turns out that some of the names were in ‘FirstName LastName’ format, while others were in ‘LastName FirstName’ format.
However, the manager column in the CSV was in ‘FirstName LastName’ format.
To fix this problem, I needed to create different potential combinations of manager names as they may likely appear in Active Directory.
However, the first step was to separate the name in the Manager column into FirstName and the LastName. To do this, I used the PowerShell ‘Split’ operator.
I started by creating two variables – using these commands:
$ManagerFirstname =‘FirstName LastName’.Split("")[0] $ManagerLastname =‘FirstName LastName’.Split("")[-1]
The commands effectively split the name into the manager’s first name and last name. This was made possible by the PowerShell ‘Split’ operator.
Next, I defined three variables ($ManagerDN1, $ManagerDN2 and $ManagerDN3) using the arithmetic operator ‘+’ to produce different combinations of potential names as they may likely appear in Active Directory. This is demonstrated by the commands below:
$ManagerDN1 = "$ManagerFirstname" + "$ManagerLastname" $ManagerDN2 = "$ManagerFirstname" + " $ManagerLastname" $ManagerDN3 = "$ManagerLastname" + "$ManagerFirstname"
If you look closely at these commands, the second command has a space just before the $ManagerLastname variable. Unfortunately, if you are reading this book in Kindle, this may not be properly formatted.
To appreciate the difference between the first and the second command, run $ManagerDN1 and $ManagerDN2.
$ManagerFirstname =‘FirstName LastName’.Split("")[0] $ManagerLastname =‘FirstName LastName’.Split("")[-1]
Here are the results of the command in PowerShell.
Finally, to find a user’s manager’s name, I modify the first command below to look like the second command:
Get-ADUser -Server ServerName -Filter {name -like 'managername*'} -Credential DomainName\administrator
Get-ADUser -Server ServerName -Filter {(name -like $ManagerDN1) -or (name -like $ManagerDN2) -or (name -like $ManagerDN3)} -Credential DomainName\administrator
This last command fixed my problem an my script worked as expected!
At the beginning of this section of PowerShell tutorial 6, I said that while the ‘Split’ operator breaks one or more strings into substrings (parts), the ‘Join’ operator links a set of strings into a single string.
We have seen an example of how the ‘Split’ operator may be used. Let’s examine some applications of the ‘Join’ operator.
Execute the following commands, one line at a time on your PowerShell console:
$FirstName = "John" $LastName = "Pipper" -Join ("$FirstName", " $LastName")
I have highlighted the final result of the command in the screenshot below.
The ‘Join’ operator combined the first name, John, and last the last name, Pipper into a Full name, John Pipper. Note that there is a space between the final Full name?
That space was added in the ‘Join’ command – -Join (“$FirstName”, ” $LastName”). There is a space after the first (“), before $LastName.
Redirection and Assignment Operators
Redirection operators are used to send the output of a command or expression to a text file. The table below lists the common PowerShell redirection operators and what they are used for.
S/N | Operator | What it does |
1 | > | Sends output to a specified file. |
2 | >> | Appends output to a specified file |
3 | 2> | Sends errors to a specified file. |
4 | 2>> | Appends errors to a specified file. |
5 | 2>&1 | Sends errors (2) and success output (1) to the success output stream. |
Out-File and Add-Content cmdlets can perform some of the tasks accomplished by some of the redirection operators. For instance, Out-File sends output to a specified text file while Add-Content with ‘Append’ parameter appends the output to a specified file.
Here are some examples of Redirection operators –
To send the results of the Get-Process command to a text file called Get-Process.txt, run this command:
Get-Process > D:\PS-Tutorial\Get-Process.txt
Furthermore, to append the result of another Get-Process command to the same text file, run the commands below:
Get-Process >> D:\PS-Tutorial\Get-Process.txt
Here is a screenshot of the text file. The last command appended the result of the Get-Process command to the end of the file.
You can use the same principle for the other 3 commands in the PowerShell redirection operators table above.
Assignment Operators
When we discussed variables earlier in PowerShell tutorial 3, we used assignment operators. Assignment operators assign one or more values to a variable.
Additionally, assignment operators can also perform numeric operations. Let’s take some examples.
First, create a variable called AOp.
$AOp = 5
In the previous command, ‘=’ is an assignment operator. It assigned the value of ‘5’ to the variable AOp.
Next, let’s add another value to the existing value in the variable:
$AOp += 2
The second command adds 2 to 5, making the value of the variable 7. To see the result, run the variable after the second command.
$AOp
Here is the result in PowerShell:
One benefit of this operator is in PowerShell scripts used to perform incremental tasks.
Special Operators
Special Operators perform tasks that cannot be performed by the other types of operators. One very important special operator is the array subexpression operator, ‘@( )’.
Array subexpression operator returns the result of one or more statements as an array.
An array is a data structure that is designed to store a collection of items. You can create an array by assigning values to a variable as shown below:
$ArrayOp = “Group1”, “Group2”
Sometimes, you may want to return the result of a command in an array. For example, to return Get-WMIObject win32_logicalDisk in an array, enclose it in the command in the Array subexpression special operator, ‘@( )’.
Here the command in an array:
@(Get-WMIObject win32_logicalDisk)
An array separate the results of a command into a collection of items. This allows you to loop through the collection and perform a specific task on each item if you wanted to.
References and Further Reading for PowerShell Tutorial 6
- About Operators
- About Comparison Operators
- About Arithmetic Operators
- about_Logical_Operators
- About Split
- About join
- About Redirection
- About Type Operators
- About Assignment Operators
This tutorial is based on my book with the same title. You can get it from Amazon.
I hope you found this article helpful. If you did,
we would love to hear from you. Kindly spare two minutes to share your thoughts with our community using the comments form below.
Alternatively, simply respond to the “Was this page helpful” question below and provide us with your feedback.
Also, Read tutorial 7 of 7