As seen while looking at syntax in Get-Help, commands accept a mixture of parameters. The following sections show how these parameters are described in help and how to use them.
Parameters
When viewing help for a command, several different conventions are used to describe when a parameter is required and how it should be used. These conventions include:
- Optional parameters, where parameter names and arguments are enclosed in a single pair of square brackets.
- Optional positional parameters – the same as an optional parameter but with the parameter name also enclosed in square brackets.
- Mandatory parameters, where the parameter name and argument are not bracketed.
- Mandatory positional parameters, where the parameter name is in square brackets, but the argument is not.
The following sections show each of these conventions in greater detail.
Optional parameters
Optional parameters are surrounded by square brackets. If a parameter is used, a value (or argument) must be supplied. A fragment of the syntax for Get-Help is shown below. It shows that a Category parameter is available and that the parameter is optional.
SYNTAX
Get-Help ... [-Category <string[]>] ...
If a value for the Category parameter is to be used, the name of the parameter must also be specified. This is shown in the following example:
Get-Help -Category HelpFile
The command above filters help documents to help files, the “about” documents.
Optional positional parameters
An optional positional parameter is surrounded by square brackets, like an optional parameter. In addition, the parameter name itself is enclosed in square brackets. This indicates that the parameter is optional and that if it is used, the parameter and value can be supplied, or just the value without the parameter name.
It is not uncommon to see an optional positional parameter as the first parameter:
SYNTAX
Get-Process [[-Name] <string[]>] ...
In this example, either of the following may be used:
Get-Process -Name pwsh
Get-Process pwsh
The output from the two commands is identical. This includes the parameter name, which, even when it is optional, is less ambiguous and therefore a recommended practice.
Mandatory parameters
A mandatory parameter must always be supplied and is written as follows:
SYNTAX
Get-ADUser -Filter <string> ...
In this case, the Filter parameter name must be used, and it must be given a value. For example, to supply a Filter for the command, the Filter parameter must be explicitly written:
Get-ADUser -Filter 'sAMAccountName -eq "SomeName"'
The Get-ADUser command has a second parameter set that uses a different parameter name with a positional value.
Mandatory positional parameters
Mandatory parameters must always be supplied, but in some cases, it is possible to supply the value without using the parameter name. The parameter the value applies to is based on position.
Parameters that are mandatory and accept values based on position are written with the parameter name only in square brackets, as shown here:
SYNTAX
Get-ADUser [-Identity] <ADUser> ...
In this case, the Identity parameter name is optional, but the value is not. This command may be used as described by either of the following examples:
Get-ADUser -Identity useridentity
Get-ADUser useridentity
In both cases, the supplied value fills the Identity parameter.
The Add-Content command has a parameter set that uses more than one mandatory positional parameter. The first part of the syntax for the parameter set is shown here:
Add-Content [-Path] <string[]> [-Value] <object[]>
In this case, the command may be called using any of the following:
Add-Content -Path c:\temp\file.txt -Value 'Hello world'
Add-Content -Value 'Hello world' -Path c:\temp\file.txt
Add-Content 'Hello world' -Path c:\temp\file.txt
Add-Content c:\temp\file.txt -Value 'Hello world'
Add-Content c:\temp\file.txt 'Hello world'
The first of these is easiest to read as both parameters are explicitly named and tends to be the better style to use.
Each of the parameters so far has required an argument, a value. PowerShell also allows parameters that do not require arguments.
Switch parameters
A switch parameter does not require an argument. If the switch is present, the value is equivalent to true, while if the switch parameter is absent, it is equivalent to false.
As with the other types of parameters, optional use is denoted by using square brackets around the parameter.
Switch parameters are typically used to toggle a behavior on. For example, Recurse is a switch parameter for Get-ChildItem:
SYNTAX
Get-ChildItem ... [-Recurse] ...
Using the switch instructs Get-ChildItem to recurse when listing the content of a directory, as shown here:
Get-ChildItem c:\windows -Recurse
It is possible to supply a value for a switch parameter from a variable. This might be desirable when writing a script where the presence of a switch parameter is based on another variable. As switch parameters do not normally expect a value, a syntax change is required:
$recurse = $false
Get-ChildItem c:\windows -Recurse:$recurse
In some cases, a switch parameter will default to present, and it may be desirable to stop the parameter from applying. The most common example is the Confirm parameter, which will be explored later in this chapter.
Parameter values
The syntax blocks explored in the preceding sections show the type that is expected when providing a value for a parameter. A type is a .NET concept; it describes what an object is, how it behaves, and what it can do. Types will be covered in greater detail in Chapter 7, Working with .NET.
The Get-CimInstance command expects a string as the argument for the ClassName parameter. This is shown in the snippet taken from the syntax block:
Get-CimInstance [-ClassName] <String>
A string is a sequence of characters. For example, the string Win32_Service can be used as follows:
Get-CimInstance -ClassName Win32_Service
ClassName must always be a single value. If more than one value is supplied, an error will be displayed:
PS> Get-CimInstance -ClassName Win32_Service, Win32_Process
Get-CimInstance: Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'ClassName'. Specified method is not supported.
Parameters that accept more than one value use [] after the type name. This indicates that the type is an array. The Name parameter for the Get-Service command is shown here:
Get-Service [[-Name] <String[]>]
In this case, the parameter type is an array of strings. An array may consist of one or more strings separated by a comma:
PS> Get-Service -Name WinDefend, WlanSvc
Status Name DisplayName
------ ---- -----------
Running WinDefend Windows Defender Antivirus Service
Running WlanSvc WLAN AutoConfig
PowerShell will attempt to coerce any value supplied into the required type. A single string can be used as an argument for the parameter. PowerShell will convert the single value into an array of strings with one element. For example:
Get-Service -Name WinDefend
Each of the commands used in this section will allow the value to be entered without the parameter name. For example, for Get-Service, the Name parameter can be omitted:
Get-Service WinDefend
Get-Service WinDefend, WlanSvc
When using positional parameters, PowerShell can use the type to determine which parameter (and which parameter set) should be used.
Parameter sets
In PowerShell, a parameter set is a set of parameters that may be used together when running a command.
Many of the commands in PowerShell have more than one parameter set. This was seen when looking at the Syntax section when using Get-Help.
For example, the Stop-Process command has three parameter sets:
SYNTAX
Stop-Process [-Id] <Int32[]> [-Confirm] [-Force] [-PassThru] [-WhatIf] [<CommonParameters>]
Stop-Process [-InputObject] <Process[]> [-Confirm] [-Force] [-PassThru] [-WhatIf] [<CommonParameters>]
Stop-Process [-Confirm] [-Force] -Name <String[]> [-PassThru] [-WhatIf] [<CommonParameters>]
PowerShell will attempt to find a matching parameter set based on the parameters and values it is given.
The parameter sets for Stop-Process have two different sets that will accept a value by position:
Stop-Process [-Id] <Int32[]>
Stop-Process [-InputObject] <Process[]>
The first expects an ID as an integer. The second expects a Process object, an object returned by the Get-Process command.
The variable $PID is an automatic variable that holds the process ID (an integer) of the current PowerShell console. Running the following command will stop the PowerShell process. The first parameter set for Stop-Process is chosen because an integer value is used:
Stop-Process $PID
The second parameter set expects a value for InputObject. Again, this may be supplied as a positional parameter (or via the pipeline). In this case, PowerShell distinguishes based on its type. The following snippet contains the three possible approaches available when using the InputObject parameter:
$process = Start-Process notepad -PassThru
Stop-Process -InputObject $process
Stop-Process $process
$process | Stop-Process
Pipeline input
Get-Help shows which parameters accept pipeline input in the help for each parameter. This may be viewed using either of the following commands:
Get-Help Stop-Process -Parameter *
Get-Help Stop-Process -Full
Examples are likely to show how to use the parameters with a pipeline.
If Get-Help is incomplete, Get-Command can be used to explore parameters:
(Get-Command Stop-Process).Parameters.InputObject.Attributes
Each of the parameter sets here also shows that the command supports common parameters.
Common parameters
Common parameters are used to control some of the standardized functionality PowerShell provides, such as verbose output and actions to take when errors occur.
When looking at the syntax, most commands will end with a CommonParameters item:
SYNTAX
Get-Process ... [<CommonParameters>]
The following is a list of common parameters:
Debug
ErrorAction
ErrorVariable
InformationAction
InformationVariable
OutBuffer
OutVariable
PipelineVariable
Verbose
WarningAction
WarningVariable
Each is described in the about_CommonParameters document:
Get-Help about_CommonParameters
The help document is also available online: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters.
For example, Stop-Process does not explicitly state that it has a Verbose switch parameter, but since Verbose is a common parameter, it may be used. This can be seen if notepad is started and immediately stopped:
PS> Start-Process notepad -Verbose -PassThru | Stop-Process -Verbose
VERBOSE: Performing the operation "Stop-Process" on target "notepad (5592)".
Not so verbose
Just because a command supports common parameters does not mean it uses them. For example, Get-Process supports the Verbose parameter, yet it does not write any verbose output when Verbose is specified.
In addition to common parameters, PowerShell also offers specialized parameters for commands that make changes.
Confirm and WhatIf
Confirm and WhatIf can be used with commands that make changes to files, variables, data, and so on. These parameters are often used with commands that use the verbs New, Set, or Remove, but the parameters are not limited to specific verbs.
Confirm and WhatIf have associated preference variables that are used to customize default behavior in PowerShell. Preference variables have an about file, which may be viewed using the following command:
Get-Help about_Preference_Variables
The Confirm switch parameter is used to control automatic prompting for high impact operations by default.
Confirm and ConfirmPreference
The Confirm switch parameter and the ConfirmPreference variable can be used to decide if a command should prompt. The decision to prompt is based on a comparison of ConfirmPreference with ConfirmImpact when set by a command author.
ConfirmPreference has four possible values:
High: Prompts when command impact is High (default)
Medium: Prompts when command impact is Medium or High
Low: Prompts when command impact is Low, Medium, or High
None: Never prompts
ConfirmImpact uses the same four values.
In Windows PowerShell, the default value for ConfirmImpact is Medium.
In PowerShell 7, the default value for ConfirmImpact is None. If the command uses SupportsShouldProcess, then the default is Medium. SupportsShouldProcess is explored in greater detail in Chapter 17, Scripts, Functions, and Script Blocks.
Finding commands with a specific impact
The following snippet returns a list of all commands that state they have a high impact:
Get-Command -CommandType Cmdlet, Function | Where-Object {
$metadata = [System.Management.Automation.CommandMetadata]$_
$metadata.ConfirmImpact -eq 'High'
}
If the Confirm parameter is explicitly provided, the value of ConfirmPreference within the scope of the command is set to Low, which will trigger any confirmation prompts. Scoping of preference variables is explored in greater detail in Chapter 17, Scripts, Functions, and Script Blocks.
The Confirm switch parameter therefore causes a command to prompt before an action is taken; for example, the Confirm switch parameter forces Remove-Item to prompt when a file is to be removed:
PS> Set-Location $env:TEMP
PS> New-Item FileName.txt -Force
PS> Remove-Item FileName.txt -Confirm
Confirm
Are you sure you want to perform this action?
Performing the operation "Remove File" on target "C:\Users\whoami\AppData\Local\Temp\FileName.txt".
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"):
In the previous example, a confirmation prompt was explicitly requested. In a similar manner, confirmation prompts may be suppressed. For example, the value of the Confirm parameter may be explicitly set to false:
Set-Location $env:TEMP
New-Item FileName.txt -Force
Remove-Item FileName.txt -Confirm:$false
The ability to provide a value for the Confirm parameter is useful for commands that prompt by default; for example, Clear-RecycleBin prompts by default:
PS> Clear-RecycleBin
Confirm
Are you sure you want to perform this action?
Performing the operation "Clear-RecycleBin" on target " All of the contents of the Recycle Bin".
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"):
Setting the Confirm parameter to false for Clear-RecycleBin bypasses the prompt and immediately empties the recycle bin:
Clear-RecycleBin -Confirm:$false
If the Confirm parameter is not set, whether a prompt is shown is determined by PowerShell. The value of the ConfirmPreference variable is compared with ConfirmImpact on a command.
There is more than one way to prompt
There are two ways of requesting confirmation in PowerShell. These are ShouldProcess and ShouldContinue. These are explored in Chapter 17, Scripts, Functions, and Script Blocks.
ShouldProcess is affected by the Confirm parameter and ConfirmPreference variable.
ShouldContinue is a forced prompt and is unaffected by the Confirm parameter and ConfirmPreference variable.
For example, Remove-Item will always prompt when attempting to delete a directory that is not empty without supplying the Recurse parameter.
It is not possible to easily discover commands using forced prompts. Reviewing documentation and testing is vital.
By default, the value of ConfirmPreference is High. This means that prompts will be raised when ConfirmImpact for a command is High. The default value for ConfirmPreference may be viewed as follows:
PS> $ConfirmPreference
High
Finding ConfirmImpact
In scripts and functions, the ConfirmImpact setting is part of the CmdletBinding attribute:
[CmdletBinding(ConfirmImpact = 'High')]
If CmdletBinding or ConfirmImpact is not present, the impact is Medium in Windows PowerShell and None in PowerShell 7.
The impact of a function or cmdlet may be viewed using the ConfirmImpact property of a command’s metadata:
[System.Management.Automation.CommandMetadata](Get-Command Remove-Item)
The use of CmdletBinding is explored in detail in Chapter 17, Scripts, Functions, and Script Blocks.
A new value for ConfirmPreference may be set by assigning it in the console; for example, it can be set to Low. When the preference variable is set to Low, prompts may be raised by all commands where ConfirmImpact is Low, Medium, or High:
$ConfirmPreference = 'Low'
ConfirmPreference and the Confirm parameter
When ConfirmPreference is set to None to suppress confirmation prompts, confirmation may still be explicitly requested using the Confirm parameter; for example:
$ConfirmPreference = 'None'
New-Item NewFile.txt -Confirm
Support for confirmation also provides support for WhatIf.
WhatIf and WhatIfPreference
WhatIf is typically used when testing a command. If implemented correctly by a command author, WhatIf should allow a state-changing command to be run without it making the change.
WhatIf is not always implemented as expected
WhatIf support for a command is defined by a command author. If the author does not correctly handle the preference, an undesirable change may be made.
The Set-ADAccountPassword had a bug for a while where WhatIf was ignored.
Even if a command supports WhatIf, test it on small sets of data before using the parameter to verify a large change.
The WhatIf parameter has an associated preference variable, WhatIfPreference, which may be set to either true or false. The default value is false.
The WhatIf parameter replaces the confirmation prompt with a simple statement describing the action the command would have taken. Using Remove-Item as an example again, a message will be displayed, and the file will not be deleted:
PS> Set-Location $env:TEMP
PS> New-Item FileName.txt -Force
PS> Remove-Item FileName.txt -WhatIf
What if: Performing the operation "Remove File" on target "C:\Users\whoami\AppData\Local\Temp\FileName.txt".
WhatIf can be explicitly set on a per-command basis by supplying a value in the same manner as the Confirm parameter. For example, WhatIf might be explicitly set to false:
'Some message' | Out-File $env:TEMP\test.txt -WhatIf:$false
Setting WhatIf in the manner used here might, for instance, be useful if a log file should be written even if other state-changing commands are ignored.
If the preference variable is set to true, all commands that support WhatIf act as if the parameter is set explicitly. A new value may be set for the variable, as shown in the following code:
$WhatIfPreference = $true
The WhatIf parameter and $WhatIfPreference preference variable take precedence over the Confirm parameter. For example, the WhatIf dialog is shown when running the following New-Item, but the Confirm prompt is not:
PS> $WhatIfPreference = $true
PS> New-Item NewFile.txt -Confirm
What if: Performing the operation "Create File" on target "Destination: C:\Users\whoami\AppData\Local\Temp\NewFile.txt".
Restarting the console will restore preference variables to their default values.
The behavior of Confirm and WhatIf is prescribed by PowerShell. Parameters such as Force and PassThru are commonly used in PowerShell but have less well-defined behavior.
Force parameter
The Force parameter is not one of the common parameters with behavior defined by PowerShell itself, but the parameter is frequently used.
Force has no fixed usage; the effect of using Force is a choice a command author must make. Help documentation should state the effect of using Force with a command. For example, the use of Force with Remove-Item is available:
Get-Help Remove-Item -Parameter Force
With the Force parameter, New-Item overwrites any existing file with the same path. When used with Remove-Item, the Force parameter allows the removal of files with Hidden or System attributes.
The error that is generated when attempting to delete a Hidden file is shown by running the following code:
Set-Location $env:TEMP
New-Item FileName.txt -Force
Set-ItemProperty FileName.txt -Name Attributes -Value Hidden
Remove-Item FileName.txt
When Remove-Item is run, the following error will be displayed:
Remove-Item: You do not have sufficient access rights to perform this operation or the item is hidden, system, or read only. RemoveFileSystemItemUnAuthorizedAccess,Microsoft.PowerShell.Commands.RemoveItemCommand
Adding the Force parameter allows the operation to continue:
Remove-Item FileName.txt -Force
The Force parameter may be worth exploring if a command is prompting, and the prompts cannot be suppressed using the Confirm parameter or the ConfirmPreference variable.
PassThru parameter
The PassThru parameter, like Force, is frequently used, but the behavior of the parameter is not defined by PowerShell. However, PassThru tends to have predictable behavior.
The PassThru parameter is typically used with commands that do not normally generate output and is used to force the command to return the object it was working with.
For example, the Start-Process command does not normally return any output. If PassThru is used, it will return the process it created:
PS> Start-Process notepad -PassThru
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
9 1.98 6.70 0.05 22636 1 notepad
The PassThru parameter is therefore useful if more work is to be done with the object after the first command has finished.
For example, PassThru might be used with Set-Service, which ordinarily does not return output, allowing a service to be started immediately after another change:
Get-Service Audiosrv |
Set-Service -StartupType Automatic -PassThru |
Start-Service
Parameters in PowerShell are a complex topic but are a vital part of working with the language.