Search code examples
powershellpiping

Piping to a cmdlet with multiple parameters


I have this cmdlet: (stripped down)

[CmdletBinding()]
Function Add-DatabaseUser()
{
    Param([string]$LogonName, [string]$UserName, [switch]$FullAccess)

    Write-Output($LogonName)
    Write-Output($UserName)
    Write-Output($FullAccess)
}

Is it possible to pipe something like an array of arrays to this cmdlet like this:

$users = @(
    @('user1', 'user1', $true),
    @('user2', 'user2', $false),
    @('user3', 'user4', $true),
    @('user4', 'user4', $true)
)

$users | Add-DatabaseUser

Rather than doing 4 individual calls to the cmdlet?

Add-DatabaseUser 'user1' 'user1' $true
Add-DatabaseUser 'user2' 'user2' $false
# etc.

Update:

I've followed Richards advice and created something to test the piped input, but something isn't right. Code below: (I've added ValueFromPipelineByPropertyName = true to all parameters in the cmdlet)

$users = @(
 @{LogonName='user1'; UserName='user1'; FullAccess=$false},
 @{LogonName='user2'; UserName='user2'; FullAccess=$false}
)

$users | Add-DatabaseUser

This gives the following output:

System.Collections.HashTable
System.Collections.HashTable
True
System.Collections.HashTable
System.Collections.HashTable
False

Solution

  • Yes.

    You need to set the ValueFromPipelineByPropertyName value for the parameter.

    For example, from about_Functions_Advanced_Parameters

    Param
    (
      [parameter(Mandatory=$true,
                 ValueFromPipelineByPropertyName=$true)]
      [String[]]
      $ComputerName,
      …
    )
    

    With that definition, $ComputerName will be set from a property of that name on the object in the pipeline. (It will also match based on parameter name aliases.)