I recently decided to start learning the (fairly) new Windows PowerShell script language and thought it would be useful to write down some of its pecularities. The list below is by no means complete, it’s just my own notes when learning the language.
BTW, I’m quite impressed of the power of this script language and will be using it from now on instead of the good old CMD.EXE and BAT files. However, there is a learning curve involved and it’s steeper than it could have been. The creators’ idea of “elastic syntax” (you can write the same logic in many ways) doesn’t exactly help… Thus there is a need for a reference like this one.
Here we go:
Setup
To allow script execution, do this:
Set-ExecutionPolicy RemoteSigned
Virtual drives
More things than files can be accessed using a file system-like method using the virtual drives mechanism.
- cert:
- env:
- function:
- HKCU:
- HKLM:
- variable:
Example:
dir variable:*
Error handling
PowerShell has a quite powerful error handling arsenal.
Errors can be trapped:
trap { "Something bad happened: " + $_;break } 1/$null trap { "Something bad happened: " + $_.Exception; break } 1/$null
The first example uses the $_ variable to access the ErrorRecord object of the current error, and the second example displays the underlying .Net exception (including call stack, etc).
The previous errors are stored in the $errors array.
Using the console
Display text in the console (and don’t send it down the pipeline):
write-host -fore red -back green "unreadable, colored text"
Send text to stderr:
write-error "my error"
Change the console prompt:
function prompt { "$(write-host -NoNewLine -fore cyan (pwd))> " }
The prompt function should return a single string.
Special operators
# swap variable values $b,$c = $c,$b # array with values 1 through 10 1..10 # read file (or variable) content. NB, no whitespace after "{"! ${c:\boot.ini} # encapsulate in array if needed @( "foobar" ) # initialize an empty array $a = @() # initialize an array with 1 element $a = ,1 # initialize an array $a = 1,2,3 # (assigns elements from the array to variables $b == 1, $c == 2,3) $b,$c = $a # retrieves values for index 0 and 2 from an array $a[0,2] # retrieves values for index 0 through 2 from an array $a[0..2] # expression sequence (all results is merged into an array) "foo"; "bar" # & - execute script block $a = { Get-Process | Select -First 2 } & $a # . - same as &, but execute in current scope $x = 2 . { $x = 3 } $x # $x is now 3, if we used & instead it would still be 2 # % can be use as a shortcut for the Foreach-Object Cmdlet 1..5 | % { $_ * 3 } # ? can be used as a syntax shortcut for the Where-Object Cmdlet 1..17 | ? { $_ % 2 -eq 0 }
Hash tables (object imitations)
# initialize hash table $user = @{FirstName = "John"; LastName="Smith"} # object property syntax $user.FirstName = "Mary" # array syntax $user["FirstName"] = "Mary" # all values from the hash table $user.Values # all keys from the hash table $user.Keys # all values from the hash table using an array as input $user[$user.keys]
Constants
These are fairly self-explanatory:
- $true
- $false
- $null
Built-in variables
- $_ – “current” object variable used in many contexts, i.e. foreach-object and where-object Cmdlets
- $home – current user’s home directory
- $profile – path to the current user’s profile script in PowerShell (executed at PowerShell startup). NB: This script does not necessarily exist!
- $OFS – Output Field Separator, used when converting lists to strings. Example:
$OFS="|";[string] @(1,2,3)
- $matches – hash table contained matches after wildcard or regex pattern matching
- $args – parameter array for a function or script
- $input – input object array for functions in a pipeline
- $error – array of errors (error[0] is the latest one)
- $? – boolean error status of last command
- $LastExitCode – exit code of the last command or EXE
- $host – reference to the application hosting PowerShell. $host.ui is useful for reading/writing text to and from the console
- $foreach – enumerator in foreach statement
- $switch – enumerator in switch statement
Pattern matching
Wildcard matching (true/false):
"foo bar" -like "f*bar"
Regular expressions (true/false + matching results in $matches):
"foo bar" -match "([a-z]*) ([a-z]*)"; $matches Output: True Name Value ---- ----- 2 bar 1 foo 0 foo bar
Discarding output of a command
Any of the following will do the trick:
[void] (dir) dir | Out-Null dir > $null
Conditional and looping statements
The switch statement is mighty cool:
switch (3) { 1 {"one"} 3 {"three"} default {$_}} switch (1..5) { 1 {"one"} 3 {"three"} default {$_}} switch (1..5) { {$_ -gt 3} { "[$_]" } default { $_} } switch -wildcard ("one", "two", "three", "four", "five") { t* { "[$_]" } default { $_} } switch -regex ("one", "two", "three", "four", "five") { ^o.* { "[$_]" } default { $_} }
That’s it for now. I will probably extend this posting later as i discover more things that are difficult to remember…
/Emil
Good stuff!
Jeffrey Snover [MSFT]
Distinguished Engineer
Visit the Windows PowerShell Team blog at: http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at: http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx