How to create a custom Powershell operator? How to create a custom Powershell operator? powershell powershell

How to create a custom Powershell operator?


You can create a prefix operator but not an in-fix or post-fix operator e.g.:

Set-Alias ?: Invoke-Ternaryfunction Invoke-Ternary {param(    [Parameter(Mandatory, Position=0)]    [scriptblock]    $Condition,    [Parameter(Mandatory, Position=1)]    [scriptblock]    $TrueBlock,    [Parameter(Mandatory, Position=2)]    [scriptblock]    $FalseBlock,    [Parameter(ValueFromPipeline, ParameterSetName='InputObject')]    [psobject]    $InputObject)Process {    if ($pscmdlet.ParameterSetName -eq 'InputObject') {        Foreach-Object $Condition -input $InputObject | Foreach {            if ($_) {                Foreach-Object $TrueBlock -InputObject $InputObject            }            else {                Foreach-Object $FalseBlock -InputObject $InputObject            }        }    }    elseif (&$Condition) {        &$TrueBlock    }    else {        &$FalseBlock    }}

Use like so:

$toolPath = ?: {[IntPtr]::Size -eq 4} {"$env:ProgramFiles(x86)\Tools"} {"$env:ProgramFiles\Tools"}}


After thinking on it, this is what I came up with:

Not sure if it's a better answer than Jon Tirjan's

function Op {    Param (        # this operator is the reverse of -contains        [switch] $isIn,        # this operator is just an example         [switch] $Plus    )    if ($isIn) {        if ($args.Length -ne 2) {            throw "Requires two arguments"        }        return ($args[1] -contains $args[0])    }    elseif ($Plus) {        if ($args.Length -ne 2) {            throw "Requires two arguments"        }        return ($args[0] + $args[1])    }}

Example usage:

PS> $ExampleList = @("alpha", "bravo", "charlie")PS> Op "alpha" -isIn $ExampleListTruePS> Op "delta" -isIn $ExampleListFalsePS> Write-Host ("Answer: " + (Op 5 -plus 7))Answer: 12


I know this is really late to the game.. but figured I would offer a nasty hack alternative.. The only benefit would be to make something that "looks" similar to the C# operator.

    Set-Alias ?: Invoke-Ternary    Function Invoke-Ternary {      [cmdletbinding()]      param(        [Parameter(Mandatory=$true, ValueFromPipeline=$true)]        [object]$Condition,        [Parameter(Mandatory=$true, Position=0)]        [Alias('FirstExpression')]        [object]$Consequent,        [Parameter(Mandatory=$true, Position=1)]        [Alias('SecondExpression')]        [object]$Alternative      )      $isTrue = if($Condition.GetType().Name -eq 'Scriptblock'){         Invoke-Command -ScriptBlock $Condition       } else {         $Condition       }      if ($isTrue) {        if($Consequent.GetType().Name -eq 'Scriptblock'){          Invoke-Command -ScriptBlock $Consequent        } else {          $Consequent        }      } else {         if($Alternative.GetType().Name -eq 'Scriptblock'){          Invoke-Command -ScriptBlock $Alternative        } else {          $Alternative        }      }    }    {[IntPtr]::Size -eq 4} |?: 'I like Soup' {'test'|?: 3  ('{0} prefer toast' -f 'We')}    {[IntPtr]::Size -eq 8} |?: 'I like Soup' {$false|?: 3  ('{0} prefer toast' -f 'We')}

While this is really nothing more than string mangling of the first expression separated by a semicolon (in favor of a colon), it illustrates that there are multiple ways to accomplish this behavior.That all being said.. I would LOVE to have official operators created forthe Ternary and the Null-Coalescing operators.. While I am at it.. an official Use-Object (using statement (not directive)) would be nice as well. Until then I will continue with my little hacks, but its nice to dream.