Windows PowerShell Basics: Part 2

Overview: In the previous lesson, we looked at use of the Where-Object cmdlet.  The example we looked at was:

Get-Service | Where-object {$_.status -like "running"}

We observed that this cmdlet made use of variables, comparison operators and object properties.  In this lesson we'll look at each of these topics in more detail.

Variables

Variables in Powershell are preceded by a dollar sign.  They don't require typecasting, as is found in other languages. 

Examples of variable assignment:

  • $var1 = 1    
  • $var2 = "string"     
  • $var3 = "Red","Blue",3,4,"J","K"   
  • $var4 = Get-Service

In the first example, $var1 is assigned the value of 1.  It can now be used in math formulas:

Prompt > $var1 (show the value of $var1)
1
Prompt > $var1 + 10 (add 10 to the value of $var1)
11

In the next example, $var2 is assigned the string value "string".  We can use this string, and also append to it:

Prompt > $var2 (show its value)
String
Prompt > $var2 + ".txt" (append to display only)
String.txt
Prompt > $var2 (show its value is unchanged)
String
Prompt > $var2 = $var2 + ".txt" (append to value of the variable)
Prompt > $var2
String.txt

$var3 is assigned an array consisting of strings and numbers.  We can find members of the array by calling the variable and the member number (starting with 0):

Prompt > $var3[0]
Red (The first element of the array is returned)
Prompt > $var3[2] + $var3[3]
7 (The values of the 3rd and 4th elements are added together)
Prompt > $var3[4] + $var3[5]
JK (The last two elements are treated like single character strings and appended in the display only)
Prompt > $var3[4] + $var3[2]
J3 (A number can't be added to a string, so it is appended in the display as if it were a string)

Lastly, $var4 is assigned an array consisting of the collection of objects obtained by the Get-Service cmdlet.  We can get members of this collection the same way we get elements of an array.  Also, we have full access to the properties and methods of the object through the array variable.

Prompt> $var4[20]
Status Name DisplayName
------ ---- -----------
Running RemoteRegistry Remote Registry

Prompt> $var4[20].status
Running

User-defined variables only persist during the current session.  If you were to bring up a new PowerShell session, none of the variables in these previous examples would have defined values.  In fact, you could create a new set of variables with the same names that had different values in each PowerShell session.  Though perfectly acceptable from a technical point of view, this could be very confusing and should be avoided.

Two variables that are always populated when PowerShell starts are $True and $False.  These have the Boolean values of True and False, and can be used in comparison operations.  This is to avoid confusion with the strings "true" and "false" being assumed to represent 0 and 1, instead of string values.

Comparison Operators

Comparison operators allow you to compare values in parameters within a command. At their most fundamental level, each comparison creates a condition that evaluates to true or false. From that comparison, specific actions can be taken. For example, you can use comparison operators along with statement blocks to test for specific conditions. The result of that test determines which actions to take (in other words, which code blocks to run).

PowerShell supports the following comparison operators:

image

The comparison operators listed above are case insensitive. In other words, "abc" is treated the same as "ABC." However, you can specify that a comparison be case-sensitive simply by preceding the operator name with the letter c, as in -ceq. When the c is used, comparisons take into account the case of the letters being compared. You can also specify that the operator be case-insensitive by preceding the operator with the letter i, as in -ieq. However, this has the same effect as not specifying either c or i. Still, you might want to use the i to delineate when you want a comparison to be case-insensitive.

To use a comparison operator, you must specify the values that are to be compared, along with an operator that separates these values. For example, the following command shows the -gt comparison operator used in an if statement:

if ($varA -gt $varB)
{ Write-Host "Condition evaluates to true." }
else
{ Write-Host "Condition evaluates to false." }

In the example, the -gt operator is used to determine whether the value in $varA is greater than the value in $varB. If this condition evaluates to true, the first code block runs. If the condition evaluates to false, the second code block runs.

More detailed information can be found in the help file about_comparison_operators.

Regular Expressions

Regular expressions are used quite commonly in Powershell.  The help file, about_regular_expressions, gives a good explanation, but I'll expand on the examples presented in more detail.

image

Object properties and methods

Most objects you use in Powershell will inherit methods and properties, based on the class of object they derive from.  Try the following two commands in a Powershell session.

$file = (get-childitem c:\autoexec.bat)
$file

By default, Powershell will only display a subset of the available properties of an object.  To view all available properties of this object, type the following command:

   $file | Select-object *

The select-object cmdlet works similar to the Select statement in SQL.  You can use a wildcard to select all properties, or list specific ones you are interested in using a comma separated list.

  $file |select-object Name, fullname, attributes, LastAccessTime

All the properties and methods of an object are called members.  To view all the members of this file, type the command:

   $file |get-member

The first information that you see is the class that this file derives from:

     TypeName: System.IO.FileInfo

Next you will see all the methods and properties of the file.  To limit the output to just the methods, use this command:

   $file |get-member -type method

Methods are functions and small blocks of code that can be executed against instances of the class that contains them.  The methods listed in this example are common to all the files on your system and can be executed against them. 

Formatting output

As you saw in some of these examples, the output is not always in the format you are expecting.  The output from most cmdlets can be piped to one of several format specific cmdlets.

  • Format-list 
  • Format-table
  • Format-wide
  • Format-custom

Try the get-process cmdlet piped to the first three formatting cmdlets.  Notice how you can get different amounts of detail depending on the format.  A more extreme example is in the get-childitem cmdlet (aliased as dir).  Change the current path to the root of C:\ and run the dir cmdlet with each formatting cmdlet.  Note the properties that do and don't get displayed.

You can write your own XML files to define custom formats for different classes of object and call those custom formats from Powershell.  More details can be found in the helpfile for this cmdlet.  Type help format-custom -full for additional details.

Explore on your own:

  • Assign the output of the get-process cmdlet to the variable $procs.
  • Display only the ProcessName, Handles, CPU, and VM properties of this array.
  • Sort the display above by ProcessName.  Then sort by ProcessName first, VM second.
  • Only display processes that have a ProcessName beginning with a vowel.
  • Only display processes that are using more than 100, but less than 200 handles.
  • Start Notepad and assign the process to the variable $proc2.  Get all the members of $proc2.
  • Get the values of all properties of $proc2.

For further information you can read about the following in the help files:

  • about_Automatic_Variables
  • about_Environment_Variable
  • about_Shell_Variable
  • about_comparison_operators
  • about_regular_expressions

Richard Pesenko | Support Escalation Engineer