PowerShell Question Mark Operator: Ternary, ??, ?. and $?

The question mark operator in PowerShell usually means the ternary operator, condition ? valueIfTrue : valueIfFalse. It picks one of two values in a single line, and it needs PowerShell 7 or later:

$diskFreeGB = 12

$status = $diskFreeGB -lt 20 ? 'Low disk space' : 'OK'
"Status: $status"

$servers = 'web01', 'web02', 'sql01'
"Found $($servers.Count) $($servers.Count -eq 1 ? 'server' : 'servers')"

Output:

Status: Low disk space
Found 3 servers
PowerShell ternary operator example
The ternary operator picks the status text and the singular or plural word (PowerShell 7)

PowerShell also uses the question mark in ??, ??=, ?., as an alias and in $?. I cover each one below, with what works in Windows PowerShell 5.1.

The ternary operator in Windows PowerShell 5.1

Windows PowerShell 5.1 can’t even read a script that contains ? :. The parser rejects it before anything runs:

try { [void][scriptblock]::Create('$status = $diskFreeGB -lt 20 ? "Low" : "OK"'); 'Parsed fine' }
catch { 'Failed. Windows PowerShell 5.1 does not understand the ? : operator' }

Output:

Failed. Windows PowerShell 5.1 does not understand the ? : operator
PowerShell ternary operator fails in Windows PowerShell 5.1
Windows PowerShell 5.1 can’t parse the ternary operator

Use an if statement as an expression instead. It works in every version and reads almost as well:

$diskFreeGB = 12

$status = if ($diskFreeGB -lt 20) { 'Low disk space' } else { 'OK' }
"Status: $status"

Output:

Status: Low disk space

If your script must run on older servers, stick with the if form. Comparison operators covers the conditions you can use.

?? and ??=: defaults for null values

The null-coalescing operator ?? returns the left side unless it’s $null, and the right side otherwise. ??= assigns a value only when the variable is $null:

$configuredPath = $null
$logPath = $configuredPath ?? 'C:\Logs\app.log'
"Log path: $logPath"

$region = $null
$region ??= 'us-east'
$region ??= 'us-west'
"Region: $region"

$emptyName = ''
"Empty string with ??: '$($emptyName ?? 'default')'"

Output:

Log path: C:\Logs\app.log
Region: us-east
Empty string with ??: ''
PowerShell null-coalescing operator ?? and ??=
?? fills in a default path, and ??= sets the region only once (PowerShell 7)

?? only reacts to $null. An empty string isn’t null, so it passes through unchanged. Check IsNullOrEmpty when empty text should get the default too.

?. and ?[]: safe property and index access

The null-conditional operators return $null instead of failing when the object is $null. Because ? is allowed in variable names, wrap the name in braces:

$user = $null
"Name with ?. : '$(${user}?.Name)'"

$user = [pscustomobject]@{ Name = 'Emma Carter'; Groups = @('Sales', 'VPN Users') }
"Name with ?. : '$(${user}?.Name)'"
"First group:   '$(${user}?.Groups?[0])'"

"Without braces: '$($user?.Name)'"

Output:

Name with ?. : ''
Name with ?. : 'Emma Carter'
First group:   'Sales'
Without braces: ''

Without the braces, PowerShell reads $user? as a separate variable that doesn’t exist, so you get nothing back. These operators need PowerShell 7.1 or later.

? as an alias for Where-Object

On its own, ? is a built-in alias for Where-Object, in every version. That’s the question mark you see in one-liners like this:

"Aliases for Where-Object: $((Get-Alias -Definition Where-Object).Name | Sort-Object)"

$big = 5, 18, 42, 7, 99 | ? { $_ -gt 10 }
"Values over 10: $($big -join ', ')"

Output:

Aliases for Where-Object: ? where
Values over 10: 18, 42, 99

Spell out Where-Object in scripts others will read. Where-Object covers filtering in depth.

$?: did the last command succeed?

The automatic variable $? is True when the last command succeeded and False when it reported an error:

Get-Item -Path C:\psfaqs\no-such-file.txt -ErrorAction SilentlyContinue
"After a failed command, `$? is $?"

Get-Date -Date '2026-09-29' | Out-Null
"After a successful command, `$? is $?"

Output:

After a failed command, $? is False
After a successful command, $? is True

Check it on the very next line, because every command resets it. Microsoft describes it in about_Automatic_Variables, and the other operators in about_Operators.

Frequently Asked Questions

Does PowerShell have a ternary operator?

Yes, in PowerShell 7 and later: $result = $x -gt 10 ? 'big' : 'small'. Windows PowerShell 5.1 doesn’t support it.

What can I use instead of the ternary operator in PowerShell 5.1?

An if expression: $result = if ($x -gt 10) { 'big' } else { 'small' }.

What does ?? do in PowerShell?

It returns the right side when the left side is $null. $path ?? 'C:\Logs' gives a default path.

What does ? mean in a PowerShell pipeline?

It’s an alias for Where-Object, so | ? { $_ -gt 10 } filters the input.

What does $? mean in PowerShell?

It’s True if the last command succeeded and False if it reported an error.

Related operator guides: