PowerShell 7 (and later, pwsh) introduced several modern operators that enhance scripting efficiency and align PowerShell more closely with other programming languages.

Included Operators

  • && and ||Pipeline chain operators
  • ?? and ??=Null-coalescing operators
  • ?:Ternary operator

1. Pipeline Chain Operators (&& and ||)

Introduced: PowerShell 7.0
Purpose: Execute commands conditionally based on the success or failure of the previous command — similar to Bash.

Behavior

  • && — Executes the next command only if the previous command succeeds (exit code 0).
  • || — Executes the next command only if the previous command fails (non-zero exit code).

Key Points

  • Success is determined by $LASTEXITCODE for external commands (e.g., hugo, git).
  • Works with both PowerShell cmdlets and external commands in pwsh.

Examples

Check Hugo and Deploy:

# In WSL's pwsh
hugo version && wrangler pages deploy public/ --project-name=my-project

✅ Runs wrangler pages deploy only if hugo version succeeds.

Handle Failure:

hugo version || sudo apt install -y hugo

✅ Installs Hugo only if hugo version fails.

Simple Demo:

2 -gt 1 && Write-Host "Success"
ls y: || Write-Host "Failure"

As 2 -gt 1 return 0, so pint out Success.

AS drive y: not exist, pring out Failure.

Real Example:

cd ~/my-site && hugo --minify && wrangler pages deploy public/ --project-name=my-project

2. Null-Coalescing Operators (?? and ??=)

Introduced: PowerShell 7.0
Purpose: Simplify handling of null or undefined values — similar to C# or JavaScript.

Behavior

  • ?? — Returns the left-hand value if not null; otherwise, the right-hand value.
  • ??= — Assigns the right-hand value only if the variable is null.

Example: Safe Defaults

If AD account PSS1001 exists, get its first name and set in $firstName.

If the account not exists, set ‘Unknown’ to $firstName.

$user = Get-ADUser -Identity "PSS1001" -Properties GivenName
$firstName = $user.GivenName ?? "Unknown"
Write-Host "First Name: $firstName"

Example: Default Assignment

$outputPath ??= "ADUsers_PS_Digits.csv"
Write-Host "Exporting to: $outputPath"

In Context — Hugo + AD Integration Example

$results = $users | Select-Object @{
    Name = 'firstName'
    Expression = { $_.GivenName ?? "N/A" }
}, @{
    Name = 'account#'
    Expression = { if ($_.SamAccountName -match '^PS.*(\d+)$') { $matches[1] } else { "N/A" } }
}

$baseURL ??= "https://yourdomain.com"
Set-Content -Path config.toml -Value "baseURL = '$baseURL'"

3. Ternary Operator (?:)

Introduced: PowerShell 7.2
Purpose: Provide a concise inline if-then-else expression like condition ? trueValue : falseValue.

Syntax

condition ? valueIfTrue : valueIfFalse

Example: AD User Status

$user = Get-ADUser -Identity "PSS1001" -Properties Enabled
$status = $user.Enabled ? "Active" : "Disabled"
Write-Host "User PSS1001 is $status"

Example: Hugo Content Check

$postCount = (Get-ChildItem ~/my-site/content/posts | Measure-Object).Count
$message = $postCount -gt 10 ? "Ready for AdSense" : "Add more posts"
Write-Host $message

Example: Enhanced AD Output

$results = $users | Select-Object @{
    Name = 'account#'
    Expression = { if ($_.SamAccountName -match '^PS.*(\d+)$') { $matches[1] } else { "N/A" } }
}, @{
    Name = 'firstName'
    Expression = { $_.GivenName ?? "N/A" }
}, @{
    Name = 'lastName'
    Expression = { $_.Surname ?? "N/A" }
}, @{
    Name = 'status'
    Expression = { $_.Enabled ? "Active" : "Disabled" }
} | Sort-Object -Property 'account#'

Running Examples in WSL

If you’re using WSL (Ubuntu 24.04):

  1. Launch PowerShell:

    pwsh

  2. Run your script:

    pwsh ./script.ps1

  3. For AD scripts (Windows module required):

    powershell.exe -File /mnt/c/path/to/script.ps1

  4. Keep PowerShell updated:

    sudo apt install powershell


Troubleshooting

Operator Not Recognized:
Ensure PowerShell ≥ 7.2

pwsh --version

AD Script Errors: Combine operators for safer logic:

$user = Get-ADUser -Identity "PSS1001" -Properties GivenName, Enabled -ErrorAction SilentlyContinue
$name = $user ? ($user.GivenName ?? "N/A") : "User not found"
$status = $user ? ($user.Enabled ? "Active" : "Disabled") : "N/A"

Hugo Integration:

$csv = Import-Csv ADUsers_PS_Digits.csv
$yaml = $csv | ForEach-Object {
    @{
        "account#" = $_.account#
        "name" = ($_.firstName -eq "N/A" ? "Unknown" : $_.firstName)
    }
} | ConvertTo-Yaml
$yaml | Set-Content ~/my-site/data/authors.yaml


These operators make your scripts shorter, safer, and more readable — ideal for both automation and Hugo + Cloudflare Pages workflows.