Parameters, values, and parameter sets
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:
# Code which determines if Recurse 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 isHigh
(default)Medium
: Prompts when command impact isMedium
orHigh
Low
: Prompts when command impact isLow
,Medium
, orHigh
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.