Skip to content

Powershell#

Crash Course#

Basic terminology Definition
Cmdlet Commands built into shell written in .NET
Functions Commands written in PowerShell language
Parameter Argument to a Cmdlet/Function/Script
Alias Shortcut for a Cmdlet or Function
Scripts Text files with .ps1 extension
Applications Existing windows programs

Basic Operators#

=,+=,-=,*=,/=,%=,++,-- assigns one or more values to variable
-and,-or,-xor,-not/! logical operators
-band,-bor,-bxor,-bnot,-shr,-shl bitwise operators
-split splits a string (ex: “abcdefghi” -split “de”)
-join joins multiple strings (ex: “abc”,”def”,”ghi” -join “;”)
` `
, comma operator (array constructor)
@() array subexpression operator

Comparison Operators#

-eq,-ieq,-ceq equal
-ne,-ine,-cne not equal
-gt,-igt,-cgt greater than
-ge,-ige,-cge greater than or equal to
-lt,-ilt,-clt less than
-le,-ile,-cle less than or equal to
-like,-ilike,-clike wildcard matching
-notlike,-inotlike,-cnotlike negation of -like
-match,-imatch,-cmatch regular expression match
-notmatch,-inotmatch,-cnotmatch negation of -match
-replace, -ireplace, -creplace replace matching elements (ex: “abcde” -replace “bc”, “TEST”)
-contains,-icontains,-ccontains check if value in array (ex: 1,2,3,4,5 -contains 3)
-notcontains,-inotcontains,-cnotcontains negation of -contains
-in,-notin syntactic reverse of -contains/-notcontains (ex: 3 -in 1,2,3,4,5)
  • string comparisons: default case-insensitive
  • -c prefix: case sensitive variant e.g. -ceq
  • -i prefix: case-insensitive variant e.g. -ieq
  • $list -op $foo: shortcut for using operator as filter i.e. returns list items satisfying -op

    [!important]
    -contains, -in, -is, -replace: can't be used this way

PowerShell
$a = (1,2) -eq 3 
  := (1,2) | Where-Object { $_ -eq 2 }
$a.GetType().Name # result: Object[]
$a.Count          # result: 0

Type Operators#

-is,-isnot test if object is an instance of a specified .NET type (ex: 42 –is [int])
-as attempt type conversion to .NET type (ex: $a = 42 –as [String])
[] type cast (ex: [datetime]$birthday = "1/10/66")
() grouping expression operator

Flow Control#

PowerShell
if ($expr) {...} elseif ($expr) {...} else {...}
while ($expr) {...}
for ($i = 0; $i -lt 10; $i++) {...}
foreach ($file in Get-ChildItem 'C:\') { $file.name }
1..10 | ForEach-Object { $_ }

Special Operators#

  • ($list).property/method: Member Access Enumeration i.e. shortcut for map on collection
PowerShell
(Get-Service -Name event*).DisplayName 
  := (Get-Service -Name event*).ForEach({ $_.DisplayName })
  := (Get-Service -Name event*) | ForEach-Object { $_.DisplayName }
# result: @('Windows Event Log', 'COM+ Event System', ...)

[!note] Nuances

  • if property exists on collection, only the collection property is returned

    PowerShell
    (Get-Service).Count => 176
    

  • if error occurs during enumeration, method is invoked only on the items enumerated before error

  • more details around undefined members, $null values, errors, etc
  • $(): subexpression operator that evaluates inner expression with result treated as a variable i.e. expr form of block stmts

  • can contain statements e.g. i.e. expression operator

  • each statement's output appends to final scalar or array result

    PowerShell
    if($(code returning value) -eq "somevalue") { do_something }
    $city="Copenhagen"
    $strLength = "$($city.length)"
    "The result of 2 + 3 = $(2+3)"
    $(Get-WMIObject win32_Directory)
    

  • &: call/invocation operator to run command, script, or script block

  • can run commands stored in variables and represented by strings

  • does not parse or interpret command parameters

    PowerShell
    $c = "get-executionpolicy"
    & $c
    

  • .: dot sourcing operator to run script in current scope

  • all script created functions/aliases/variables are added to the current scope

    PowerShell
    . c:/scripts/sample.ps1
    . ./sample2.ps1
    

  • -f: format operator for string interpolation with format args e.g. padding, alignment, hex etc

PowerShell
1..10 | foreach { "{0:N2}" -f $_ }
Get-ChildItem c:\ | ForEach-Object {'File {0} Created {1}' -f $_.fullname,$_.creationtime}
  • ..: range operator to produce number sequence
PowerShell
10..20
1..10 | foreach {$_ * 5}
-5..0.9 # a more readable version of the same thing.

Redirection Operators#

n Output streams
1 success stream i.e. stdout
2 error stream i.e. stderr
3 warning stream
4 verbose stream
5 debug stream
6 information stream
* all Streams
n> send stream to file (default: n=1)
n>> append stream to file (default: n=1)
n>&1 redirects stream to success stream (default: n=1)

[!note] limitations
can only redirect to success stream

PowerShell
Get-Process word* | Stop-Process
Do-Something 3>   warning.txt # Writes warning output to warning.txt
Do-Something 4>>  verbose.txt # Appends verbose.txt with the verbose output
Do-Something 5>&1             # Writes debug output to the output stream
Do-Something *>&1             # Redirects all streams to stdout
Do-Something *>   out.txt     # Redirects all streams to out.txt

Gotchas#

  • Common Parameters/Preference Variables not inherited across module scopes
  • Details

Cheatsheet#

Useful Commands#

Command
Update-Help Downloads and installs newest help files
Get-Help get-process Get help for command
Get-Command Get all commands
Get-Command -Module RGHS Get all commands in RGHS module
Get-Command Get-p* Get all commands starting with get-p
Get-Member Gets the properties and methods of objects
Get-Module Gets all imported and importable modules
Get-Process \| Get-Member Get members of the object
Get-Process \| format-list -properties * Get-Process as list with all properties
Ctrl+c Interrupt current command
Left/Right Navigate editing cursor
Ctrl+Left/Right Navigate a word at a time
Home/End Move to start / end of line
Up'/'Down Move up and down through history
Insert Toggles between insert/overwrite mode
F7 Command history in a window
Tab/Shift+Tab Command line completion

Scripting#

  • %: alias for foreach-object

  • $_: current item in foreach-object

  • Get-Member: object introspection

  • pretty print

  • object: Write-Host ($foo | Format-Table | Out-String)

  • array: Write-Host ($foo | Format-List | Out-String)
  • string interpolation

  • use $ in double quotes e.g. "blaaa $myvar" or "blaaaa$($myobjVar.name)"

  • no string expansion: '$blaaa'
  • invoke command/script

  • & foo @(arg0,arg2,...): call operator invokes expression in child scope that's discarded (e.g. any global variable changes not persisted)

  • . foo @(arg0,arg2,...): dot sourcing invokes expression in current scope (e.g. global changes are persisted)
  • common batch operations

  • get all items in a directory: Get-ChildItem *

  • get all subdirectories: Get-ChildItem -Attributes Directory -Recurse
  • get all files in directory: Get-ChildItem *.docx | % Name
  • enabling -WhatIf, -Confirm, etc

  • add [CmdletBinding(SupportsShouldProcess = $true)] to param block

  • inside function, wrap state change code with if ($PSCmdlet.ShouldProcess(target,operation)) {...}
  • dump variables in a scope e.g. scope captured by GetNewClosure()
PowerShell
$m = (Get-Command testFunc2).Module
& $m Get-Variable -Scope 0
  • dump function definition

[!warning] Function provider has no containers and is always rooted

PowerShell
Get-ChildItem -Path Function:              # Dump all the functions in the current session
(Get-Item -Path function:mkdir).Definition # Dump Function Definition
$function:mkdir                            # Alternate Syntax for above
  • create function closure

[!warning] appears to capture "only" local variables i.e. those from the caller's current scope

PowerShell
function New-Function {
  $x = $global:x
  $function:global:testFunc2 = {$x}.GetNewClosure()
}
  • invocation info

  • $PSScriptRoot, $PSCommandPath: info about the current script

  • $MyInvocation.PSScriptRoot, $MyInvocation.PSCommandPath: info about the invoker or calling script

  • $MyInvocation Properties

    Property
    $MyInvocation.BoundParameters This member provides a dictionary of the parameters that were bound for this script or command.
    $MyInvocation.CommandOrigin This property tells you if you were being invoked inside the runspace or if it was an external request.
    $MyInvocation.DisplayScriptPosition The position for the invocation or error.
    $MyInvocation.ExpectingInput Is true if this command is expecting input...
    $MyInvocation.HistoryId History ID that represents the command. If unavailable, this will be -1.
    $MyInvocation.InvocationName Command name used to invoke this string - if invoked through an alias, then this would be the alias name.
    $MyInvocation.Line The text of the line that contained this cmdlet invocation.
    $MyInvocation.MyCommand Provide basic information about the command
    $MyInvocation.OffsetInLine Command's character offset in that line. If the command was executed directly through the host interfaces, this will be -1.
    $MyInvocation.PipelineLength How many elements are in the containing pipeline
    $MyInvocation.PipelinePosition which element this command was in the containing pipeline
    $MyInvocation.PositionMessage Formatted message indicating where the cmdlet appeared in the line
    $MyInvocation.PSCommandPath This property tells you the full path to the command from where you were being invoked
    $MyInvocation.PSScriptRoot This property tells you the directory from where you were being invoked
    $MyInvocation.ScriptLineNumber The line number in the executing script that contained this cmdlet.
    $MyInvocation.ScriptName The name of the script containing the cmdlet.
    $MyInvocation.UnboundArguments This member provides a list of the arguments that were not bound to any parameter

PSScriptAnalyzer Linter#

[!info] Built-in Rules

Rule Enabled Config Severity
PSAlignAssignmentStatement No Yes Warning
PSAvoidAssignmentToAutomaticVariable Yes Warning
PSAvoidDefaultValueForMandatoryParameter Yes Warning
PSAvoidDefaultValueSwitchParameter Yes Warning
PSAvoidGlobalAliases Yes Warning
PSAvoidGlobalFunctions Yes Warning
PSAvoidGlobalVars Yes Warning
PSAvoidInvokingEmptyMembers Yes Warning
PSAvoidLongLines No Yes Warning
PSAvoidMultipleTypeAttributes Yes Warning
PSAvoidNullOrEmptyHelpMessageAttribute Yes Warning
PSAvoidOverwritingBuiltInCmdlets Yes Yes Warning
PSAvoidSemicolonsAsLineTerminators No Warning
PSAvoidShouldContinueWithoutForce Yes Warning
PSAvoidTrailingWhitespace Yes Warning
PSAvoidUsingBrokenHashAlgorithms Yes Warning
PSAvoidUsingCmdletAliases Yes Yes Warning
PSAvoidUsingComputerNameHardcoded Yes Error
PSAvoidUsingConvertToSecureStringWithPlainText Yes Error
PSAvoidUsingDeprecatedManifestFields Yes Warning
PSAvoidUsingDoubleQuotesForConstantString No Yes Warning
PSAvoidUsingEmptyCatchBlock Yes Warning
PSAvoidUsingInvokeExpression Yes Warning
PSAvoidUsingPlainTextForPassword Yes Warning
PSAvoidUsingPositionalParameters Yes Warning
PSAvoidUsingUsernameAndPasswordParams Yes Error
PSAvoidUsingWMICmdlet Yes Warning
PSAvoidUsingWriteHost Yes Warning
PSDSCDscExamplesPresent Yes Information
PSDSCDscTestsPresent Yes Information
PSDSCReturnCorrectTypesForDSCFunctions Yes Information
PSDSCStandardDSCFunctionsInResource Yes Error
PSDSCUseIdenticalMandatoryParametersForDSC Yes Error
PSDSCUseIdenticalParametersForDSC Yes Error
PSDSCUseVerboseMessageInDSCResource Yes Error
PSMisleadingBacktick Yes Warning
PSMissingModuleManifestField Yes Warning
PSPlaceCloseBrace No Yes Warning
PSPlaceOpenBrace No Yes Warning
PSPossibleIncorrectComparisonWithNull Yes Warning
PSPossibleIncorrectUsageOfAssignmentOperator Yes Warning
PSPossibleIncorrectUsageOfRedirectionOperator Yes Warning
PSProvideCommentHelp Yes Yes Information
PSReservedCmdletChar Yes Error
PSReservedParams Yes Error
PSReviewUnusedParameter Yes Warning
PSShouldProcess Yes Warning
PSUseApprovedVerbs Yes Warning
PSUseBOMForUnicodeEncodedFile Yes Warning
PSUseCmdletCorrectly Yes Warning
PSUseCompatibleCmdlets Yes Yes Warning
PSUseCompatibleCommands No Yes Warning
PSUseCompatibleSyntax No Yes Warning
PSUseCompatibleTypes No Yes Warning
PSUseConsistentIndentation No Yes Warning
PSUseConsistentWhitespace No Yes Warning
PSUseCorrectCasing No Yes Information
PSUseDeclaredVarsMoreThanAssignments Yes Warning
PSUseLiteralInitializerForHashtable Yes Warning
PSUseOutputTypeCorrectly Yes Information
PSUseProcessBlockForPipelineCommand Yes Warning
PSUsePSCredentialType Yes Warning
PSUseShouldProcessForStateChangingFunctions Yes Warning
PSUseSingularNouns Yes Warning
PSUseSupportsShouldProcess Yes Warning
PSUseToExportFieldsInManifest Yes Warning
PSUseUsingScopeModifierInNewRunspaces Yes Warning
PSUseUTF8EncodingForHelpFile Yes Warning
  • disable rule
PowerShell
[System.Diagnostics.CodeAnalysis.SuppressMessage('PSAvoidUsingWriteHost', '')]

[!note] can control scoping

  • scope to file, add to top of file and param() below attribute

    PowerShell
    [System.Diagnostics.CodeAnalysis.SuppressMessage('PSAvoidUsingWriteHost','')]
    param()
    

  • namespace scope

    PowerShell
    [System.Diagnostics.CodeAnalysis.SuppressMessage('PSAvoidUsingWriteHost','',Scope='Namespace')]
    

  • list approved powershell verbs
PowerShell
Get-Verb | Sort-Object Verb

Resources#