
close
close
Want to know about the security benefits of Microsoft's E5 license?
Over the course of a few articles, I’ve been introducing you to PowerShell operators. Most of them like -eq and -And are not that difficult to figure out if you see them in an example. PowerShell has several other operators that I describe as special use and may not be intuitive, but I think you will find them quite useful.
The range operator (..) is a quick way to get a range of numbers in either ascending or descending order.
the PowerShell Range operator (Image Credit: Jeff Hicks)
Range failures (Image Credit: Jeff Hicks)
1..5 | foreach { "do something here on pass $_" }
This will run the code in the ForEach-Object loop five times.
Or you could use it like this to build a random password.
Function New-Password { Param([int]$Length = 7) -join (33..126 | Get-Random -count $length | foreach {$_ -as [char]} ) }
And maybe you want to generate a list of passwords
Creating a range of passwords (Image Credit: Jeff Hicks)
The call operator (&) is used to invoke or run an expression. You might have a scriptblock you are using with Invoke-Command, but you will need to test it.
Calling a PowerShell scriptblock (Image Credit: Jeff Hicks)
Invoking an PowerShell expression in a variable (Image Credit: Jeff Hicks)
Invoke failure (Image Credit: Jeff Hicks)
Calling a PowerShell command with parameters (Image Credit: Jeff Hicks)
The static member operator (::) confuses newcomers. Part of the problem is that this is part of the .NET world. In .NET, sometimes you have to construct an instance of an object before you can invoke or run any of the object’s methods. In those situations you would use the . operator.
$now = Get-Date $then = $now.AddDays(100)
I had to create a [Datetime] object before I could invoke the AddDays() method. But some .NET classes have methods that are considered static. In these situations, you don’t need to create an instance of the object. You can invoke the method directly from the class. The [math] class is a great example.
[math]::pi [math]::Pow(2,3)
Or here is a more practical example:
Get-CimInstance win32_logicaldisk -filter "drivetype = 3" -ComputerName $c | Select DeviceID, @{Name="SizeGB";Expression = {($_.size/1GB) -as [int]}}, @{Name="FreeGB";Expression = { [math]::Round($_.freespace/1gb,4)}}, @{Name="PctFree";Expression = { [math]::Round(($_.freespace/$_.size) *100,2)}}, PSComputername | Out-GridView -Title "Drive Report"
You’ll also notice I’m using a few other operators I’ve discussed in previous articles. Invoking the static methods from the [Math] class produces a much nicer report.
Drive report with calculated values (Image Credit: Jeff Hicks)
Most of the time you don’t need to define an array ahead of time. But you can explicitly create an empty array using @().
Explicitly defining an array in PowerShell (Image Credit: Jeff Hicks)
Testing array methods (Image Credit: Jeff Hicks)
Array problems (Image Credit: Jeff Hicks)
Using the comma operator to define an array (Image Credit: Jeff Hicks)
The last special operator I want to demonstrate is the subexpression or $(). Knowing how this works and when to use it indicates that you have moved beyond absolute PowerShell beginner.
Beginners will try to build a string like this:
"The computer $env:computername is running PowerShell version $psversiontable.psversion"
Beginners will expect this to show the PowerShell version, but instead they get a result like this:
The computer WIN81-ENT-01 is running PowerShell version System.Collections.Hashtable.psversion
That’s not what they expected. Instead they need to use a subexpression. Think of a subexpression like this: PowerShell will run the commands inside the parentheses and the $ sign tells PowerShell to treat the result like a temporary variable. Here is the correct solution using a subexpression:
"The computer $env:computername is running PowerShell version $($psversiontable.psversion)"
I use subexpressions, often in verbose messages in my scripts. Let’s revisit my New-Password function.
Function New-Password { [cmdletbinding()] Param([int]$Length = 7) Begin { Write-Verbose "[BEGIN ] Starting: $($MyInvocation.Mycommand)" Write-Verbose "[BEGIN ] Using Parameter set $($pscmdlet.ParameterSetName)" Write-Verbose "[BEGIN ] $env:computername $((Get-WmiObject Win32_operatingsystem).Caption) PS v$($PSVersionTable.PSVersion)" } #begin Process { Write-Verbose "[PROCESS] Creating password with length $length" -join (33..126 | Get-Random -count $length | foreach {$_ -as [char]} ) } End { Write-Verbose "[END ] Ending: $($MyInvocation.Mycommand)" } #end }
With subexpressions, I can include some useful information in my verbose output.
Subexpression output (Image Credit: Jeff Hicks)
More in PowerShell
Most popular on petri