PowerShell Basics–Filtering and Iterating over Objects
Monday, February 4, 2013 at 12:58PM
Carlos Perez

Now that we know that commands in PowerShell produce objects and that they have properties we can now start comparing, filtering and manipulating the objects.

Operators

For the manipulation of objects we will cover first the Operators in PowerShell since they are used against Objects and the Properties of objects. You will notice that the operators for comparison operators in PowerShell will differ from those in Ruby, Python, Perl and other scripting languages and mimic more those found in Unix type shells so a Bash programmer will feel at ease with the operators in PowerShell. When comparisons are done PowerShell has the special variables $True and $False to represent Boolean values.

image

One thing to keep in mind when working with PowerShell is that it is case insensitive so when we are doing comparisons and we want them to be case sensitive we have to explicitly specify to be case sensitive.

PS > "hello" -eq "HELLO" 
True
To make a comparison be case sensitive one only need to add a c to the comparison.
PS > "hello" -ceq "HELLO" 
False
PowerShell will try to convert the types of the element for evaluation by analyzing them. It ill use the value on the left as the type to convert the type on the right.
PS > 1 -eq "1" 
True

There are also operators for comparing collections and type:

image

One common mistake by many starting with PowerShell is that many times -contains and -in operators are used by mistake to search in strings. Their use is for Arrays or Hash lists.

PS > "a","b","c" -contains "b" 
True 

PS > "b" -in "a","b","c" 
True
PowerShell also allow also to compare by type. The operators are: Type operators are mostly used to make sure the proper type is used in scripts
C:\PS> (get-date) -is [datetime] 
True 

C:\PS> (get-date) -isnot [datetime] 
False 

C:\PS> "9/28/12" -as [datetime] 
Friday, September 28, 2012 12:00:00 AM 

We can join several comparisons using Boolean Operators and each comparison operator is considered a subexpression.

image

Subexpressions can be parenthetical or cmdlets that return a Boolean. An example would be :

PS C:\> ((1 -eq 1) -or (15 -gt 20)) -and ("running" -like "*run*") 
True

Selecting Objects

The Select-Object cmdlet allows for:

The Select-Object cmdlets allows us to select from a collection of objects the ones we want when we specify the index position of the item. Just like all programing languages we start our count with 0.

PS > Get-Process | Sort-Object name -Descending | Select-Object -Index 0,1,2,3,4 

We can also use the range notation, this will return an array of number for the range and we can pass those to the index parameter.

PS > Get-Process | Sort-Object name -Descending | Select-Object -Index (0..4)

Select the first number of objects, the last number of objects or even skip a certain number.

PS > Get-Process | Sort-Object name -Descending | Select-Object -first 5 

The select-object cmdlets also allows us to create and rename an objects property, this is very useful when the property name is not to descriptive and when we are passing from one comdlet to another where the next cmdlet accepts and processes objects by Property Name. The way it works is that we create a hash with 2 values in it, one is Name which is the name we ant for the property and the other is expressions which is a script block whose returning value will be set as the value of the property we named.

PS > Get-Process | Select-Object -Property name,@{name = 'PID'; expression = {$_.id}} 

One thing that we have to be very careful with when using Select-Object is that when we select property names using it actually generates a new object of the same type with only those properties that we selected and strips out the rest. Depending on the chaining of cmdlets using the pipeline this could cause us to loose a property we may need further along the pipeline chain so do keep it in mind and be careful.

Iterating over Objects

Iteration is the method by which several objects in a collection are processed one by one and actions are taken against them. In PowerShell, there are 2 methods for iterating thru objects and are often confused:

As you can see the main reason for the confusion is that Foreach-Object has an alias of foreach which can be confused with the statement. Each method will take a collection and process the objects in a Scriptblock but each behaves differently, however and its use will vary case by case.

Lets start with Foreach-Object. The ForEach-Object cmdlet takes a stream of objects from the pipeline and processes each and it uses less memory do to garbage control, as objects gets processed and they are passed thru the pipeline they get removed from memory. The cmdlet takes 4 main parameters:

The ScriptBlocks parameters are also positional

PS C:\> 1..5 | ForEach-Object { $Sum = 0 } { $Sum += $_ } { $Sum } 
15 
To skip to the next object to be process in ForEach-Object the keyword Continue is used. For exiting the loop inside of a ForEach-Object the break keyword is used.
C:\PS> $Numbers = 4..7 
C:\PS> 1..10 | foreach-object { if ($Numbers -contains $_) { continue }; $_ } 
1 
2 
3 

Now lets take a look at the at the Foreach statement. The foreach( in ){} statement places on each iteration an element of a collection in to memory first and then processes each. (Not good for extremely large collections on memory constrained systems). Since the collection being worked on is loaded in to memory it tends to be faster than the ForEach-Object cmdlet.

To skip to the next object to be process in foreach statement the keyword continue is used. For exiting the loop inside of a foreach statement the break keyword is used.

The foreach statement can even be used in a interactive shell session:

PS >foreach ($i in (1..10)){ 
>>    if ($i -gt 5){ 
>>        continue 
>>    } 
>>    $i 
>> } 
>>
1 
2 
3 
4 
5 
As always I hope you have found this blogpost informative and useful. Thanks.
Article originally appeared on Security and Networking (http://darkoperator.squarespace.com/).
See website for complete article licensing information.