Similar to programming language, in powershell, if condition will check the given condition and if it is true,
it will execute the statements within the first set of braces(from '{' to the next '}').
If the condition is not true, it will check the next condition and so on.
If no given condition is true, the 'else' statements are executed.
Here is the list of all comparing operator with examples.
Operator Description |
---|
-eq Equal to |
-lt Less than |
-gt Greater than |
-ge Greater than or Eqaul to |
-le Less than or equal to |
-ne Not equal to |
When comparing text strings, by default PowerShell is not case-sensitive.
But here we have another option to force case-sensitivity.
By appending an "i" to the any operator, you can force PowerShell to be "case-insensitive."
Appending a "c" you can force PowerShell to compare as "case-sensitive."
Use of if else. Only if statement is required, everything else is optional. Powershell doent care of spaces, position of "{" and "}" and formatting. There is not limitation on elseif statements.
As with other programming languages, PowerShell is a dynamic scripting language. Script code can be executed based on conditions that exist or occur. For example, a script might prompt for user input and run a block of code based on the data supplied by the user. A process or application may stop running, triggering an action within a script. Conditional Logic allows us to write scripts in a complex environment, it adds the intelligence required to create decision-making scripts.
Launch PowerShell and let's get started...
We are going to compare data using the following PowerShell Comparison and Logical Operators.
Table 1: PowerShell Comparison Operators:
Operator |
Description |
-eq |
Equal to |
-lt |
Less than |
-gt |
Greater than |
-ge |
Greater than or Eqaul to |
-le |
Less than or equal to |
-ne |
Not equal to |
I'm not going to join in the great debate over why these operators where chosen, they exists within PowerShell and must be used. Special note: When comparing text strings, by default PowerShell is not case-sensitive. "TOM" and "tom" would compare "equal to" (-eq). However, you can force PowerShell to compare values based on case-sensitivity. By appending an "i" to the operator, you're telling PowerShell to be "case-insensitive." Appending a "c" forces PowerShell to compare as "case-sensitive."
Examples:
Tom -eq TOM. The result is "True"
Tom -ieq TOM. The result is "True"
Tom -ceq TOM. The result is "False"
Table 2: PowerShell Logical Operators:
Operator |
Description |
-not |
Not |
! |
Not |
-and |
And |
-or |
Or |
Now that we have the table listings of Operators, let's do some examples to show their use and results.
7 -eq 7<enter>
Result is "True"
7 -ne 7<enter>
Result is "False"
7 -lt 10<enter>
Result is "True"
7 -gt 10<enter>
Result is "False"
"Tom" -eq "tOm"<enter>
Result is "True"
"Tom" -ceq "tOm"<enter>
Result is "False"
I'm going to skip the logical operators for now, we'll get back to them in a moment. What's important to understand is each code snippet is providing a result, either True or False. The results are used in the decision-making process within PowerShell scripts.
Now that we have results, what do we do with them? We need a way to apply comparison results with conditional logic (the decision-making process). PowerShell supports two logic statements to help out:
1. if - evaluates a comparison, then either executes or sidesteps code blocks based on the result. if statements require result of the comparison to be Trueto execute it's associated code block.
2. switch - Does the same as the if statement with the exception that it can evaluate multiple comparisons, each having the ability to execute code blocks. This is the same as a " select case" or "case" statements in VBScript and other programming languages.
Using the "if" Statement
The if statement syntax:
if (condition) {code block}
elseif (condition) {code block}
else (condition) {code block}
Let's do a simple script that shows the if statement in action. Copy the code into clogic.ps1 file and save it to the "MyScripts" directory. Run the script: "C:\MyScripts\clogic.ps1<enter>" -or- type ".\clogic.ps1 if you are currently working in the MyScripts directory.
$x = 2 #creates a variable x and assigns 2 as the value
if ($x -eq 5) {Write-Host "Hello my name is Bob"}
elseif ($x -eq 4) {Write-Host "Hello, my name is Sue"}
elseif ($x -eq 2) {Write-Host "Hello, my name is Troy"}
elseif ($x -gt 1) {Write-Host "Hello, my name is Mary"}
else {"I have no idea what my name is?"}
The result should be Hello, my name is Troy as the condition ($x -eq 2) resulted in a True value and executed the script block {}. But I purposely threw you a curve ball. Notice that the last elseif statement ($x -gt 1) would also result in a True condition, so why doesn't it's script block get executed? This is by design, once an if statement conditionresults in a True value the associated script block is executed and PowerShell stops testing subsequent conditions. The way around this is to use a switch statement which we will discuss in this PowerShell training session.
Real-World Example:
Sometimes different Operating Systems use different WMI classes and/or
properties. I ran into this difference when attempting to enumerate
printers on Windows XP, Windows 2003, and Windows 2000. I used an if statement to test the OS version and based on the
version, PowerShell would run the code block associated for each OS. Here's
the code I used:
Copy the following code into a .ps1 script file. Name it PrintReport.ps1 and execute the script.
$strComputer = Read-Host "Printer Report - Enter Computer Name"
$OS = Get-WmiObject -Class win32_OperatingSystem -namespace "root\CIMV2" `
-ComputerName $strComputer
# if statement to run code for Windows XP and Windows 2003 Server.
if (($OS.Version -eq "5.1.2600") -or ($OS.Version -eq "5.2.3790"))
{
write-host "Computer Name: " $strComputer
#nested if statement
if ($OS.Version -eq "5.1.2600") {write-host "OS Version: Windows XP"}
elseif ($OS.Version -eq "5.2.3790") {write-host "OS Version: Windows 2003"}
$colPrinters = Get-WmiObject -Class win32_Printer -namespace "root\CIMV2" `
-computerName $strComputer
foreach ($objPrinter in $colPrinters) {
write-host "Name: " $objPrinter.Name
write-host "Description: " $objPrinter.Description
write-host
}
}
# if statement to run code for Windows 2000 Server
elseif ($OS.Version -eq "5.0.2195")
{
write-host "Computer Name: " $strComputer
write-host "OS Version: Windows 2000 Server"
$colPrinters = Get-WmiObject -Class win32_PrintJob -namespace "root\CIMV2"
`
-computername $strComputer
foreach ($objPrinter in $colPrinters) {
write-host "Name: " $objPrinter.Name
write-host "Description: " $objPrinter.Description
write-host
}
}
# if OS not identified
else {write-host "The OS for: $strComputer is not supported."}
write-host "-END OF REPORT-"
When the script is executed, you are prompted to enter the computer name you wish to enumerate. By adding the "Read-Host" cmdlet, you're now able to enumerate other computers on your network. Pretty cool stuff going on here, let's break it down.
Step 1. $strComputer = Read-Host "Printer Report - Enter Computer Name"
Creates a variable called $strComputer and assigns a value supplied from
user input.
Step 2.
$OS = Get-WmiObject -Class win32_OperatingSystem -namespace
"root\CIMV2"
`
-ComputerName $strComputer
Creates the variable "$OS" and assigns the win32_OperatingSystem class
object. Something else to look at. Even though it looks like two lines of
code, it's actually one line of code. The "`" escape character means to
continue as one line. Used for keeping scripts legible should you run out
of space. PowerShell reads the line as:
$OS = Get-WmiObject -Class win32_OperationSystem -namespace "root\CIMV2"
-Computername $strComputer
Step 3.
if (($OS.Version -eq "5.1.2600") -or ($OS.Version -eq "5.2.3790"))
Here is where we talk about Logical Operators.
Operator |
Description |
-not |
Not |
! |
Not |
-and |
And |
-or |
Or |
What you need to know. The Not operators -not and ! (both mean NOT) allow you to modify the results of a
condition. For example:
if (1 -eq 1) - results in a True value and runs the script
block.
if (!(1 -eq 1) - results in a False value and skips the
script block.
The -or operator means at least one of the conditions must
be True to execute the script block.
For example:
if ((1 -gt 2) -or (2 -gt 1)) - One of the conditions are True so, it's associated script block will execute.
The -and operator means that all
conditions must be True to execute the script block.
Example:
if ((1 -ge 1) -and (2 -ge 1)) - Both conditions are True,
script block executes.
if ((1 -ge 1) -and (2 -le 1)) - The first condition is True, whereas the second is False. The
script block is skipped.
Step 4.
{
write-host "Computer Name: " $strComputer
#nested if statement
if ($OS.Version -eq "5.1.2600") {write-host "OS Version: Windows XP"}
elseif ($OS.Version -eq "5.2.3790") {write-host "OS Version: Windows
2003"}
$colPrinters = Get-WmiObject -Class win32_Printer -namespace
"root\CIMV2" `
-computerName $strComputer
foreach ($objPrinter in $colPrinters) {
write-host "Name: " $objPrinter.Name
write-host "Description: " $objPrinter.Description
write-host
}
}
In step 3. if one of the conditions are True the script
block in step 4. is executed. The script block writes the following
information to the screen:
· The OS Type - Note, in RED, we can nest additional if statements within code blocks. Now you are stating to see how complex PowerShell, as a scripting language, can be.
· The script block then enumerates the win32_Printer class and sends the requested property information to the screen.
· Once the block completes, PowerShell skips to Step 8. and writes "-END OF REPORT-" to let the end user know it has completed.
If none of the conditions are True in step 3. PowerShell moves to the next if statement, in this example that would be...
Step 5.
elseif ($OS.Version -eq "5.0.2195")
If this condition results in a True value, the script
block in step 6. is executed.
Step 6.
{
write-host "Computer Name: " $strComputer
write-host "OS Version: Windows 2000 Server"
$colPrinters = Get-WmiObject -Class win32_PrintJob -namespace
"root\CIMV2" `
-computername $strComputer
foreach ($objPrinter in $colPrinters) {
write-host "Name: " $objPrinter.Name
write-host "Description: " $objPrinter.Description
write-host
}
}
The result of the script block outputs the following information to the screen:
· Once the block completes, PowerShell skips to Step 8. and writes "-END OF REPORT-" to let the end user know it has completed.
If the result in step 5. is False, PowerShell continues reading the script and finds the "else" statement.
Step 7.
else {write-host "The OS for: "$strComputer" is not supported."}
Outputs " The OS is not supported." Step 7. runs when all
conditions in the script end with a False value.
Step 8.
write-host "-END OF REPORT-"
Let's you know the script has completed.
This example shows just how dynamic our scripts can be, based on conditions that exist in our environment. And how we can write if statements to test those conditions and run script blocks according to the results of those tests.
Using the Switch Statement for Multiple Comparisons
Since we can use elseif statements to test multiple conditions, there may come a time when too many additional tests lend to difficult script writing and down-right ugliness. There are other times where you want to test multiple conditions that result in multiple True values and you don't want the script to stop testing when it receives the first Truevalue (as it does with an if statement). The option that allows you to accomplish this is the switch statement. The PowerShell switch statement organizes a collection of tests that are evaluated using the same expression.
The Switch statement syntax:
switch (expression)
{
(test) {code block}
value {code block}
default {code block}
}
Here is an example from Ed Wilson's PowerShell book: "Windows PowerShell Step by Step." Save the script code as ComputerRoles.ps1 and run the script:
$objWMI = Get-WmiObject -Class win32_ComputerSystem -namespace "root\CIMV2"
"Computer "+ $objWMI.name + " is a: "
switch ($objWMI.domainRole)
{
0 {Write-Host "Stand alone workstation"}
1 {Write-Host "Member workstation"}
2 {Write-Host "Stand alone server"}
3 {Write-Host "Member server"}
4 {Write-Host "Back-up domain controller"}
5 {Write-Host "Primary domain controller"}
default {Write-Host "The role can not be determined"}
}
In this example I used a number value which correlates to the value of the domainrole property within the win32_ComputerSystem WMI class. When the value was returned as True, the script block output the role using the "Write-Host" cmdlet.
Modify the script to prompt user for "Computer Name:"
$strComputer = Read-Host "Enter Computer Name"
$objWMI = Get-WmiObject -Class win32_ComputerSystem -namespace "root\CIMV2"
`
-computername $strComputer
Write-Host "Computer: $strComputer is a:"
switch ($objWMI.domainRole)
{
0 {Write-Host "Stand alone workstation"}
1 {Write-Host "Member workstation"}
2 {Write-Host "Stand alone server"}
3 {Write-Host "Member server"}
4 {Write-Host "Back-up domain controller"}
5 {Write-Host "Primary domain controller"}
default {Write-Host "The role can not be determined"}
}
Now that we can input the $strComputer value, we can run this script on any remote computer in the environment, as long we have local admin rights.
This next example has no real purpose other than demonstrating how the switchstatement works using the (test) expression with multiple True value results. Unlike if statements, switch statements continue running when True value matches are found. So it is possible that more than one code block will be executed. Copy and Paste the code into the PowerShell shell. The results should be obvious, test expressions that correctly equal 10 will run:
switch (10)
{
(1 + 9) {Write-Host "Congratulations, you applied addition correctly"}
(1 + 10) {Write-Host "This script block better not run"}
(11 - 1) {Write-Host "Congratulations, you found the difference correctly"}
(1 - 11) {Write-Host "This script block better not run"}
}
Conditional logic is the foundation for dynamic PowerShell script writing. We successfully demonstrated how we can control the flow of a script base on conditional responses. In the next PowerShell training session we are going to build on what we have learned and introduce Loops, which takes flow control to the next level. See you in the next PowerShell tutorial...