Accepting Different Parameter Types

by Oct 29, 2018

Occasionally, you might want to create a function that accepts different parameter types. Let’s say you want the user to be able to either submit an employee name, or an Active Directory object.

There is one fixed rule in PowerShell: variables cannot have multiple data types at the same time. Since parameters are variables, a given parameter can only have one distinct type.

However, you can use parameter sets to define mutual exclusive parameters which is a great way to deal with different input types. Below is an example of a function that accepts either a service name, or a service object. This is basically how Get-Service works inside, and the below example just illustrates how this is done:

function Get-MyService
{
  [CmdletBinding(DefaultParameterSetName="String")]
  param
  (
    [String]
    [Parameter(Mandatory,Position=0,ValueFromPipeline,ParameterSetName='String')]
    $Name,

    [Parameter(Mandatory,Position=0,ValueFromPipeline,ParameterSetName='Object')]  
    [System.ServiceProcess.ServiceController]
    $Service
  )
  
  process
  {
    # if the user entered a string, get the real object
    if ($PSCmdlet.ParameterSetName -eq 'String')
    {
      $Service = Get-Service -Name $Name
    }
    else
    {
        # else, if the user entered (piped) the expected object in the first place,
        # you are good to go
    }

    # this call tells you which parameter set was invoked
    $PSCmdlet.ParameterSetName
    
    # at the end, you have an object
    $Service
  }

}

Let’s take a look at how the function performs:

 
PS> Get-MyService -Name spooler
String

Status   Name               DisplayName                           
------   ----               -----------                           
Running  spooler            Print Spooler                         



PS> $spooler = Get-Service -Name Spooler

PS> Get-MyService -Service $spooler
Object

Status   Name               DisplayName                           
------   ----               -----------                           
Running  Spooler            Print Spooler                         



PS> "Spooler" | Get-MyService
String

Status   Name               DisplayName                           
------   ----               -----------                           
Running  Spooler            Print Spooler                         



PS> $spooler | Get-MyService
Object

Status   Name               DisplayName                           
------   ----               -----------                           
Running  Spooler            Print Spooler 

As you can see, the user can submit a service name or a service object. The Get-MyService function mimics the behavior found in Get-Service, and returns a service object, regardless of which input was chosen. Here is the syntax of above function:

Syntax
       Get-MyService [-Name] <string> [<CommonParameters>]        
       Get-MyService [-Service] <ServiceController> [<CommonParameters>]

Twitter This Tip! ReTweet this Tip!