繁体   English   中英

PowerShell中管道输入的问题

[英]Problems with pipeline input in PowerShell

所以,希望有人可以帮助我。 我过去一直在寻找解决方案,并且以前总能找到一些东西。 但这个似乎太奇怪了。

我有一个PowerShell函数,可以有效地复制New-ADUser Cmdlet,并且它接受多个参数才能这样做。 此函数的大多数参数都将“ValueFromPipelineByPropertyName”参数属性设置为True,以便我可以将CSV和其他管道数据提供给函数,而无需编写大量“if”和赋值语句。 或者至少这是个主意。

这是我的功能的一个例子(简化为了更好地说明这一点):

[CmdletBinding()]
Param(
    [Parameter(ValueFromPipelineByPropertyName=$true)]
    [string]$FirstName,
    [Parameter(ValueFromPipelineByPropertyName=$true)]
    [string]$LastName,
    [Parameter(ValueFromPipelineByPropertyName=$true)]
    [string]$FullName
)

Process {
    if(-not $FullName) {
        $FullName = "$FirstName $LastName"
    }

    $user = "" | select FirstName,LastName,FullName
    $user.FirstName = $FirstName
    $user.LastName = $LastName
    $user.FullName = $FullName
    return $user
}

所以当我针对CSV数据运行时:

FirstName,LastName
Bob,Smith
Dick,Jones
Sami,Davis
Ray,Charles
Jane,Doe
Keith,Johnson
Ruth,Willson
Genni,Gartner

我明白了:

FirstName                       LastName                        FullName
---------                       --------                        --------
Bob                             Smith                           Bob Smith
Dick                            Jones                           Bob Smith
Sami                            Davis                           Bob Smith
Ray                             Charles                         Bob Smith
Jane                            Doe                             Bob Smith
Keith                           Johnson                         Bob Smith
Ruth                            Willson                         Bob Smith
Genni                           Gartner                         Bob Smith

现在,我明白这里发生了什么。 管道输入或函数参数中没有FullName的指定值,因此我在process语句中设置一个值以在该迭代中使用。 问题是,而不是$ FullName变量,然后“重置”回到下一个循环迭代的null未定义的值,它保持值集。

如果我更改CSV数据以明确定义FullName的“”值,则问题就会消失。 但是,当管道数据没有定义属性时,这对我没有帮助。

我试图避免重新编码整个函数以使用不同的变量名或使用$ _因为为了增加函数的复杂性我还定义了参数别名,以便我们可以直接从我们的HR程序的数据库获取数据并管道它进入新的用户功能而无需手动按摩数据。 这也让我回到无法在管道数据中添加空值参数。

我知道我的解释有点长,但这个场景似乎是独一无二的(至少根据我可以在互联网上挖掘的东西)。

这里的变量范围有些棘手,可能吗?

您可以尝试在函数末尾添加一个Remove-Variable FullName ,看看是否有帮助。

我知道你不想使用不同的变量名,但这可以使用一个不同的变量来更清楚地将“生成的”全名存储在函数中; 范围将不那么混乱,希望如此。

if(-not $FullName) {
    $GeneratedName = "$FirstName $LastName"
} else {
    $GeneratedName = $FullName
}

为什么不简单地'重置' $fullname变量?

[CmdletBinding()]
Param(
    [Parameter(ValueFromPipelineByPropertyName=$true)]
    [string]$FirstName,
    [Parameter(ValueFromPipelineByPropertyName=$true)]
    [string]$LastName,
    [Parameter(ValueFromPipelineByPropertyName=$true)]
    [string]$FullName
)

Process {  
            if([string]::IsNullOrEmpty($FullName))
                {
                    $script:Fullname =  "$FirstName $LastName"
                }        

    $user = "" | select FirstName,LastName,FullName
    $user.FirstName = $FirstName
    $user.LastName = $LastName
    $user.FullName = $FullName
    $FullName= [string]::Empty
    $user
}

你需要设置FullName的默认值,所以下面的代码将正常工作:

[CmdletBinding()]
Param(
    [Parameter(ValueFromPipelineByPropertyName=$true)]
    [string]$FirstName,
    [Parameter(ValueFromPipelineByPropertyName=$true)]
    [string]$LastName,
    [Parameter(ValueFromPipelineByPropertyName=$true)]
    [string]$FullName=$null
)

Process {
    if(-not $FullName) {
        $FullName = "$FirstName $LastName"
    }

    $user = "" | select FirstName,LastName,FullName
    $user.FirstName = $FirstName
    $user.LastName = $LastName
    $user.FullName = $FullName
    return $user
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM