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

问题描述 投票:1回答:2

我在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循环?

function powershell parameter-passing pipeline
2个回答
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

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 @_ }

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

© www.soinside.com 2019 - 2024. All rights reserved.