powershellparameters

PowerShell array param with optional values


I'd like my PS script to have an interface like this:

tool.ps1 -Update item1, item2, item3 # Update individual items
tool.ps1 -Update # Update all items

I've tried all known attribute combinations (AllowEmptyCollection etc), and still can't get the second example to work: PS asks to provide a param value.

Any ideas?


Solution

  • You can achieve the described behavior by separating the -Update parameter from the optional arguments:

    [CmdletBinding(DefaultParameterSetName = 'Default')]
    param(
      [Parameter(Mandatory = $true, ParameterSetName = 'Update')]
      [switch]$Update,
    
      [Parameter(ValueFromRemainingArguments = $true, DontShow = $true)]
      [string[]]$Values
    )
    
    if ($PSCmdlet.ParameterSetName -eq 'Update') {
      # update requested
      if ($Values.Count) {
        Write-Host "Updating items: $($Values -join ', ')"
      }
      else {
        Write-Host "Updating all items!"
      }
    }
    else {
      Write-Host "No update requested"
    }
    

    Now, if present, the additional arguments will be bound to the hidden -Values parameter instead (thanks to the ValuesFromRemainingArguments flag), which should give you the behavior you want:

    PS ~> .\tool.ps1 -Update
    Updating all items!
    PS ~> .\tool.ps1 -Update item1, item2, item3
    Updating items: item1, item2, item3
    PS ~> .\tool.ps1
    No update requested