As a full-stack developer and Linux expert, I often find myself needing to add logic and decision making to my PowerShell scripts. That usually means relying on traditional if/else statements or switch statements. However, PowerShell offers a third option for conditional logic that can really streamline your code – the ternary operator.

What is the Ternary Operator?

The ternary operator allows you to assign one of two values to a variable based on a condition. Here is the basic syntax:

$variable = <condition> ? <value if true> : <value if false>

It consists of three parts:

  1. A condition that evaluates to either true or false
  2. The "?" separating the condition from the values
  3. An expression to return if the condition is true, followed by ":"
  4. An expression to return if the condition is false

This compact syntax lets you ditch those bulky if/else statements when you only need to pick between two simple values or expressions.

Let‘s look at a quick example:

$age = 25
$status = $age > 21 ? "Adult" : "Minor"
$status
# Outputs "Adult"

Since $age is greater than 21, $status gets set to "Adult". The ternary operator spared us from writing a lengthy if/else statement to assign the right value.

Ternary Use Cases

The ternary operator shines when:

  • You need to pick between two values/expressions
  • The expressions and condition are simple
  • You want to set a variable value based on a condition
  • You want to return or output one of two values from a function

You can use it as a shorthand for if/else when the logic isn‘t too complex.

Some good examples:

  • Setting status values like "Active" or "Inactive" based on a condition
  • Outputting a "Pass" or "Fail" result from a validation function
  • Selecting a default value if a parameter is $null

The ternary operator improves readability in these cases and saves you lines of code.

Now let‘s explore some specific ways you can apply the ternary operator in PowerShell.

1. Assign Variable Values

One of the most common uses of the ternary operator is to assign different values to a variable based on a condition:

$files = Get-ChildItem
$fileCountStatus = $files.Count -gt 10 ? "High" : "Low"

Here we assign either "High" or "Low" to $fileCountStatus depending on the number of files returned.

You can also nest ternary statements:

$age = 25
$status = $age > 65 ? "Senior" : $age > 21 ? "Adult" : "Minor"

This sets $status to "Senior", "Adult" or "Minor" based on multiple age checks.

2. Control Function Output

Functions are another excellent use case for ternary logic:

function Test-Access {
  param([string]$path)

  $hasAccess = Test-Path -Path $path -Access Read

  return $hasAccess ? "Access granted" : "Access denied" 
}

Test-Access -Path C:\Users\molly\Documents

Here we use the ternary operator to return an appropriate status message from the function based on the condition result.

You can also use it to selectively output objects:

function Get-ActiveUsers {
  $users = Get-ADUser -Filter *  
  $activeUsers = @()

  foreach ($user in $users){
    $isActive = $user.Enabled -eq $true
    $activeUsers += $isActive ? $user : $null
  }

  return $activeUsers
}

This filters down the returned user accounts to only active ones based on the Enabled property. Much simpler than checking the condition and adding users in separate if/else logic!

3. Validate Input

Validating function parameters is another prime scenario:

function Set-Location{
   param(
     [string]$path
   )

   $isValid = Test-Path $path

   $path = $isValid ? $path : throw "Invalid location: $path"

   Push-Location $path  
}

Here we verify $path refers to a valid location, and throw an error if not. The ternary operator lets us handle the checking neatly.

You can also assign default values if parameters are $null:

function Write-Greeting{
   param(
     [string]$name = $null
   )

   $userName = $name ? $name : "Guest"

   "Hello $userName!"
}

Write-Greeting -Name Molly
#> Hello Molly! 

Write-Greeting 
#> Hello Guest!

This provides a default "Guest" greeting if no name is supplied.

4. Build Output Strings

The ternary operator works well for building custom messages based on logic conditions:

$dbStatus = Get-DatabaseStatus

$statusMsg = "Database is " + ($dbStatus.Active ? "currently active" : "offline")

By injecting conditional text into the status string, we can tailor the messaging precisely based on the true/false logic.

PowerShell 7 Enhancements

Up through PowerShell 6, the ternary operator only supported two expressions – essentially mimicking if/else logic.

PowerShell 7 introduced some nice enhancements:

  • You can now chain multiple ternary statements together with the same condition by separating them with semi-colons (;) instead of colons.

Example:

$role = "admin"
$message = $role -eq "admin" ? "All access granted"; "Advanced features enabled" : "Limited access"

This allows $message to contain both "All access granted" AND "Advanced features enabled" if $role matches "admin".

  • Null-coalescing support – this lets you fall back to a default if the first expression evaluates to null:
function Get-UserName{
  param([string]$email)

  $user = Get-User | ? Email -eq $email

  # Set default if $user lookup returned null
  return $user?.DisplayName ?? "Guest"  
}

If no match is found for $email, we default to return "Guest" instead of null.

These additions make the ternary operator even more versatile in PowerShell 7+.

Putting it All Together

Let‘s look at a final example that incorporates some of these techniques:

function Set-UserAccess {
   param(
     [string]$userName,
     [validateset("None","Read","ReadWrite")]
     $accessLevel 
   )

   $user = Get-User | ? Name -eq $userName

   $hasAccess = $user -and $accessLevel -ne "None"

   $access = $hasAccess ? "$userName granted $($accessLevel) access" : 
                      "$userName access denied"

   return $access

} 

Set-UserAccess -userName "Molly" -accessLevel "ReadWrite"
#> Molly granted ReadWrite access

Set-UserAccess -userName "BadUser" -accessLevel "Read"
#> BadUser access denied

This takes a username and access level and returns a status message indicating whether access was granted or denied:

  • The ternary operator assigns the message to $access based on $hasAccess
  • PowerShell 7‘s null-coalescing handles the case where an invalid $userName is passed
  • We build a dynamic string with conditionally inserted values

This produces simple, readable logic to handle all the access cases.

When NOT to Use Ternary

While the ternary operator has some cool advantages, it isn‘t a wholesale replacement for if/else or switch statements.

Avoid using it when:

  • You need additional conditional checks beyond true/false (go for if/elseif instead)
  • Handling more than 2 resulting values
  • Conditions or expressions get super complex
  • Logic requires nested conditionals or loops

In those cases, traditional conditional statements will be cleaner and more readable. Think of the ternary as handling simple binary choices rather than intricate program flow control.

Conclusion

The ternary operator is a great tool to add to your PowerShell scripting toolkit. Its compact syntax helps you manage simple conditional logic without the overhead of full if/else statements.

You now have several techniques under your belt to apply the ternary for assigning values, controlling output, validating parameters, and building dynamic output.

PowerShell 7 also upgraded the ternary to open up additional use cases with expression chaining and null-coalescing.

Keep the ternary operator in mind as you look to streamline decision making and output in your scripts. It can help you trim down repetitive if/else boilerplate drastically. But also recognize when more complex conditions warrant using full conditional statements instead.

I encourage you to play around with the ternary operator examples above to get comfortable applying it across different scripting scenarios. Mastering it will help you write leaner, cleaner logic as you automate tasks with PowerShell every day.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *