If you’ve been using PowerShell for a while and stumbled across a ? symbol in someone’s script — and had no idea what it was doing. The question mark in PowerShell is one of those things that looks confusing at first but makes your scripts much cleaner once you understand it.
In this tutorial, I’ll walk you through every way the ? operator (and its relatives ??, ??=, ?., and ?[]) is used in PowerShell. By the end, you’ll know exactly when and how to use each one.
What Does ? Mean in PowerShell?
Here’s the thing — the question mark in PowerShell doesn’t mean just one thing. Depending on where you use it, it can mean completely different things:
- A shorthand alias for
Where-Object(when used after a pipe|) - The ternary operator (when used as
condition ? value_if_true : value_if_false) - Part of the null-coalescing operator (
??) - Part of the null-coalescing assignment operator (
??=) - Part of the null-conditional member access operator (
?.and?[])
The last four are only available in PowerShell 7 and above. If you’re still on Windows PowerShell 5.1, you’ll need to upgrade to use them.
Let’s go through each one with real examples.
1. ? as an Alias for Where-Object
This is the oldest use of ? in PowerShell and works in all versions.
Where-Object filters objects in a pipeline. The ? is just a shortcut for it. So instead of writing this:
Get-Process | Where-Object { $_.CPU -gt 100 }You can write this:
Get-Process | ? { $_.CPU -gt 100 }Both lines do the exact same thing. The ? simply saves some typing. You’ll see this a lot in quick one-liners and scripts where people prefer brevity.
Here is the exact output in the screenshot below:

One thing to keep in mind: the ? only works as an alias for Where-Object when it comes after a pipe (|). Outside of a pipeline, PowerShell treats it differently — which brings us to the ternary operator.
2. The Ternary Operator (? 🙂 — Cleaner If/Else
The ternary operator was introduced in PowerShell 7. It lets you write a simple if/else condition in a single line.
Syntax:
<condition> ? <value if true> : <value if false>
Without the ternary operator, you’d write:
$age = 20
if ($age -ge 18) {
$status = "Adult"
} else {
$status = "Minor"
}
$status
With the ternary operator, the same logic becomes:
$age = 20
$status = ($age -ge 18) ? "Adult" : "Minor"
$status
Much shorter and easier to read. The condition goes before the ?, the true value goes right after, and the false value follows the :.
Practical Example — Check If a File Exists
$path = "C:\Logs\error.log"
$result = (Test-Path $path) ? "File found" : "File is missing"
Write-Host $result
If the file exists, you get File found. If not, File is missing. One line, clean and clear.
Important: Always wrap your condition in parentheses
()before the?. Without the brackets, PowerShell might interpret the?as a parameter of the cmdlet rather than the ternary operator — and your script will break in a confusing way.
Multi-Line Ternary
PowerShell 7 lets you split the ternary operator across multiple lines, which helps with readability on longer conditions:
$diskSpace = 5
$warning = ($diskSpace -lt 10) ? "Warning: Low disk space" : "Disk space is OK"
Write-Host $warning
You can see the exact output in the screenshot below:

Check out PowerShell Unary Operator Examples
3. Null-Coalescing Operator (??)
This one is incredibly handy when you’re working with variables that might be $null.
The ?? operator returns the left-hand value if it’s not null. If the left value is null, it returns the right-hand value instead. Think of it as a fallback.
Syntax:
$variable ?? <fallback value>
Example:
$username = $null
$displayName = $username ?? "Guest"
Write-Host $displayName
# Output: Guest
Since $username is null, PowerShell falls back to "Guest".
Now if $username actually has a value:
$username = "John"
$displayName = $username ?? "Guest"
Write-Host $displayName
# Output: John
This is much cleaner than writing:
if ($username -ne $null) {
$displayName = $username
} else {
$displayName = "Guest"
}Chaining ?? Operators
You can chain multiple ?? operators together — PowerShell evaluates them left to right and stops at the first non-null value:
$a = $null
$b = $null
$c = "Fallback value"
$result = $a ?? $b ?? $c
Write-Host $result
# Output: Fallback value
This is extremely useful when you’re pulling values from multiple sources and want to use the first one that actually exists.
Read PowerShell Not Equal Operator
4. Null-Coalescing Assignment Operator (??=)
This is a close cousin of ??. The ??= operator assigns a value to a variable — but only if the variable is currently null. If the variable already has a value, it stays untouched.
Syntax:
$variable ??= <value to assign if null>
Example:
$config = $null
$config ??= "default-config.json"
Write-Host $config
# Output: default-config.json
Now run it again but this time the variable already has a value:
$config = "custom-config.json"
$config ??= "default-config.json"
Write-Host $config
# Output: custom-config.json
The assignment was skipped because $config wasn’t null. This is super useful when setting default values at the start of a script without accidentally overwriting something that’s already been set.
Check out PowerShell If Null Then Empty
5. Null-Conditional Member Access (?. and ?[])
These two operators solve one very common scripting headache: trying to access a property or method on an object that might be $null, which would normally throw an error.
?. — Safe Property Access
$user = $null
$name = $user?.Name
Write-Host $name
# Output: (nothing — returns $null silently, no error)
Without the ?., this would throw an error in strict mode or when the object is genuinely null. With ?., it just returns $null quietly and your script keeps running.
Here’s a more realistic example:
$process = Get-Process -Name "notepad" -ErrorAction SilentlyContinue
$processName = $process?.Name
Write-Host "Process name: $processName"
If Notepad isn’t running, $process is null and $processName just becomes null — no ugly red errors.
?[] — Safe Array Element Access
The ?[] operator does the same thing for arrays. It lets you safely access an array element without worrying about whether the array itself is null.
$items = $null
$firstItem = $items?[0]
Write-Host $firstItem
# Output: (nothing — $null, no error)
Contrast this with the standard approach:
$firstItem = $items[0] # This throws an error if $items is $null
The ?[] operator is especially useful in strict mode (Set-StrictMode -Version Latest) where accessing a null object would otherwise break your script.
Check out PowerShell Match Operator Examples
When Should You Use Which Operator?
Here’s a quick decision guide on when you should use these operators.
- Use
?after a pipe → when you want to filter objects withWhere-Object - Use
? :→ when you want a one-line if/else to assign a value - Use
??→ when a variable might be null and you need a fallback value - Use
??=→ when you want to set a default only if the variable hasn’t been set yet - Use
?.or?[]→ when accessing properties/elements on something that might be null
A Note on PowerShell Version Compatibility
The ? alias for Where-Object works in all versions of PowerShell. Everything else — ? :, ??, ??=, ?., and ?[] — requires PowerShell 7.0 or later.
To check your version, run:
$PSVersionTable.PSVersion
If you’re on version 5.x (Windows PowerShell), upgrade to PowerShell 7 to unlock all these features. You can install it from the official Microsoft GitHub page and it runs side-by-side with Windows PowerShell — no conflict.
Check out PowerShell Filter Operators
Real Example
Now, let me show you a real example of using several of these operators together so you can see how they interact in real time.
Below is the complete PowerShell script.
# Set a default log path if none is provided
$logPath ??= "C:\Logs\default.log"
# Check if the log file exists
$logStatus = (Test-Path $logPath) ? "Log file found" : "Log file missing"
Write-Host $logStatus
# Safely get the log file's last write time
$logFile = Get-Item $logPath -ErrorAction SilentlyContinue
$lastWritten = $logFile?.LastWriteTime ?? "Never written"
Write-Host "Last written: $lastWritten"
This script:
- Assigns a default path if
$logPathis null - Uses a ternary to check if the file exists
- Safely accesses the file’s property using
?. - Falls back to
"Never written"using??if the property is null
Final Thoughts
The question mark operators in PowerShell are one of those upgrades that — once you start using them — you’ll wonder how you ever lived without. They make your code shorter, cleaner, and easier to read. Start with the ternary and null-coalescing operators since they come up the most often, and you’ll naturally pick up the others as your scripts get more complex.
I hope these examples helps you, if you still have any questions, feel free to leave a comment below.
You may also like:
Bijay Kumar is an esteemed author and the mind behind PowerShellFAQs.com, where he shares his extensive knowledge and expertise in PowerShell, with a particular focus on SharePoint projects. Recognized for his contributions to the tech community, Bijay has been honored with the prestigious Microsoft MVP award. With over 15 years of experience in the software industry, he has a rich professional background, having worked with industry giants such as HP and TCS. His insights and guidance have made him a respected figure in the world of software development and administration. Read more.