带管道或直接输入的多个参数

时间:2017-12-18 22:08:19

标签: function powershell parameter-passing pipeline

我在PowerShell中创建具有多个参数的函数时遇到问题。我有4个参数,它们的值可以通过管道传递或通过PowerShell窗口中的直接输入传递。

我似乎无法弄清楚如何确保4个参数可以在过程部分中使用。

这就是我所拥有的(Write-Host部分仅用于测试):

function Set-NewDevEnv {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true, ValuefromPipelineByPropertyName=$true)]
        [ValidateSet('IIS', 'SQL', 'SOLR', 'Vanilla')]
        [string[]]$VMType,
        [Parameter(Mandatory=$true, ValuefromPipelineByPropertyName=$true)]
        [string[]]$StaticIP,
        [Parameter(Mandatory=$true, ValuefromPipelineByPropertyName=$true)]
        [string[]]$VMName,
        [Parameter(Mandatory=$true, ValuefromPipelineByPropertyName=$true)]
        [string[]]$VMDNSName
    )

    Begin {}

    Process {
        Write-Host "VMType is $VMType ; StaticIP is $StaticIP ; VMName is $VMName; and VMDNSName is $VMDNSName"
    }

如果我使用它,它可以正常使用Pipeline输入,但不能直接命令行输入,即:

Set-NewDevEnd -VMType "SQL","IIS" -StaticIp "192.168.0.1","192.168.0.2" -VMName "Testing1","Testing2" -VMDNSName "Testing1","Testing2"

我正在

VMType is SQL IIS ; StaticIP is 192.168.0.1 192.168.0.2 ; VMName is Testing1 Testing2 ; and VMDNSName is Testing1 Testing2

我知道通常,为了支持直接输入和管道输入,您需要在foreach部分添加process循环,但我将如何使用foreach有多个参数的循环?

2 个答案:

答案 0 :(得分:2)

参数不会那样工作。当您通过管道传递输入时,每个参数一次获得一个值(对于每个处理过的对象)。在命令行调用中,您同时传递所有值,但各个参数数组的索引彼此没有关系,除非您在函数中实现了它。否则,PowerShell如何使用(例如)两个期望字符串数组和简单字符串的参数来处理函数?同时处理数组和简单值?每个数组索引以及简单字符串的副本?第一个带有简单字符串的索引,其余的带有空值?还有别的吗?

你可以做的是建立一个哈希表列表并将它们展开:

$data = @{
    'VMType'    = 'SQL'
    'StaticIP'  = '192.168.0.1'
    'VMName'    = 'Testing1'
    'VMDNSName' = 'Testing1'
},
@{
    'VMType'    = 'IIS'
    'StaticIP'  = '192.168.0.2'
    'VMName'    = 'Testing2'
    'VMDNSName' = 'Testing2'
}

$data | ForEach-Object { Set-NewDevEnv @_ }

虽然我不确定这会在构建自定义对象和管道化它们方面获得任何优势。

答案 1 :(得分:1)

ValuefromPipelineByPropertyName表示您需要在传递给输入的对象中具有相同名称的属性。参数类型也不需要是数组。您可以这样更改功能:

Function Set-NewDevEnv {
    [cmdletbinding()]
    param (
        [Parameter(Mandatory=$true,ValuefromPipelineByPropertyName=$true)]
        [ValidateSet('IIS','SQL','SOLR','Vanilla')]
        [string]$VMType,
        [Parameter(Mandatory=$true,ValuefromPipelineByPropertyName=$true)]
        [string]$StaticIP,
        [Parameter(Mandatory=$true,ValuefromPipelineByPropertyName=$true)]
        [string]$VMName,
        [Parameter(Mandatory=$true,ValuefromPipelineByPropertyName=$true)]
        [string]$VMDNSName
    )

    begin {"Test Begin"}
    process {
        Write-Host "VMType is $VMType ; StaticIP is $StaticIP ;" + `
        "VMName is $VMName; and VMDNSName is $VMDNSName"
    }
    end {"Test End"}
}

并测试:

@([pscustomobject]@{
    VMType = "SQL";
    StaticIP = "192.168.0.1";
    VMName = "Testing1";
    VMDNSName= "Testing1"; }, 
  [pscustomobject]@{
    VMType = "IIS";
    StaticIP = "192.168.0.2";
    VMName = "Testing2";
    VMDNSName= "Testing2";}) | Set-NewDevEnv

这将是结果:

Test Begin
VMType is SQL ; StaticIP is 192.168.0.1 ; VMName is Testing1; and VMDNSName is Testing1
VMType is IIS ; StaticIP is 192.168.0.2 ; VMName is Testing2; and VMDNSName is Testing2
Test End