Function 具有管道或直接输入的多个参数

Function 具有管道或直接输入的多个参数,function,powershell,parameter-passing,pipeline,Function,Powershell,Parameter Passing,Pipeline,在PowerShell中创建具有多个参数的函数时,我遇到了一个问题。我有4个参数,它们的值可以通过管道传递,也可以通过PowerShell窗口中的直接输入传递 我似乎不知道如何确保这4个参数可以用于流程部分 以下是我所拥有的(当然,Write Host部分仅用于测试): 如果我使用它,它可以很好地用于管道输入,但不能用于直接命令行输入,即: Set-NewDevEnd -VMType "SQL","IIS" -StaticIp "192.168.0.1","192.168.0.2" -VMNam

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

我似乎不知道如何确保这4个参数可以用于流程部分

以下是我所拥有的(当然,
Write Host
部分仅用于测试):

如果我使用它,它可以很好地用于管道输入,但不能用于直接命令行输入,即:

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 VMType为sqliis;静态IP为192.168.0.1192.168.0.2;VMName正在测试1测试2;VMDNSName正在测试1测试2
我知道,通常,为了支持直接输入和管道输入,您需要在
过程
部分添加一个
foreach
循环,但是如何使用带有多个参数的
foreach
循环?

参数不是这样工作的。当您通过管道传递输入时,每个参数一次获得一个值(对于处理的每个对象)。在命令行调用中,您同时传递所有值,但是各个参数数组的索引彼此之间没有关系,除非您在函数中实现了这一点。否则,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 @_ }

尽管我不确定这是否会比构建自定义对象并对其进行管道化有任何优势。

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

谢谢Ansgar和您的答案基本相同hehe,但您的答案是,通过使用自定义对象,可以帮助我更进一步,因为我将专门调用这些值来在VMware中构建新的虚拟机。谢谢你的帮助!:)
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