【问题标题】:Powershell Pipeline Property Binding Failing [duplicate]Powershell管道属性绑定失败[重复]
【发布时间】:2015-07-07 20:27:11
【问题描述】:

我遇到了一个我无法弄清楚的特殊问题。我正在尝试将 Get-ADUser -Identity Test-User -Property SamAccountName 中的值绑定到自定义构建的 cmdlet。这是我以前做过很多次的事情,但由于某种奇怪的原因,它现在失败了。为了降低复杂性,我编写了一个测试函数来最小化复杂性。该函数是:

function Test-Binding{
    [cmdletbinding()]
    Param
    (
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$True)]
        [Alias("SamAccountName")]
        [string]
        $Identity
    )

    return $Identity
}

执行Get-ADUser -Identity Test-user | Test-Binding时出现错误:

Test-Binding : Cannot bind argument to parameter 'Identity' because it is an empty string.
At line:1 char:76
+ Trace-Command parameterbinding -Expression {Get-ADUser -Identity Test-User | Test- ...
+                                                                            ~~~~~
    + CategoryInfo          : InvalidData: (CN=Test-User...,DC=contoso,DC=com:PSObject) [Test-Binding], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Test-Binding

在查看我的代码并查看以前成功的脚本之后,我的下一步是运行跟踪。在跟踪中,第一次尝试绑定成功,但是 powershell 然后尝试继续将其绑定到其他输入值,直到它崩溃。这是转储:

DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Get-ADUser]
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Get-ADUser]
DEBUG: ParameterBinding Information: 0 : BIND cmd line args to DYNAMIC parameters.
DEBUG: ParameterBinding Information: 0 :     DYNAMIC parameter object: [Microsoft.ActiveDirectory.Management.Commands.GetADUserParameterSet]
DEBUG: ParameterBinding Information: 0 :     BIND NAMED args to DYNAMIC parameters
DEBUG: ParameterBinding Information: 0 :         BIND arg [Test-User] to parameter [Identity]
DEBUG: ParameterBinding Information: 0 :             COERCE arg to [Microsoft.ActiveDirectory.Management.ADUser]
DEBUG: ParameterBinding Information: 0 :                 Trying to convert argument value from System.String to Microsoft.ActiveDirectory.Management.ADUser
DEBUG: ParameterBinding Information: 0 :                 CONVERT arg type to param type using LanguagePrimitives.ConvertTo
DEBUG: ParameterBinding Information: 0 :                 CONVERT SUCCESSFUL using LanguagePrimitives.ConvertTo: [Test-User]
DEBUG: ParameterBinding Information: 0 :             Executing VALIDATION metadata: [Microsoft.ActiveDirectory.Management.Commands.ValidateNotNullOrEmptyADEntityAttribute
]
DEBUG: ParameterBinding Information: 0 :             Executing VALIDATION metadata: [System.Management.Automation.ValidateNotNullAttribute]
DEBUG: ParameterBinding Information: 0 :             BIND arg [Test-User] to param [Identity] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :     BIND POSITIONAL args to DYNAMIC parameters
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Get-ADUser]
DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Test-Binding]
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Test-Binding]
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Test-Binding]
DEBUG: ParameterBinding Information: 0 :     BIND arg [] to parameter [Identity]
DEBUG: ParameterBinding Information: 0 :         Executing DATA GENERATION metadata: [System.Management.Automation.ArgumentTypeConverterAttribute]
DEBUG: ParameterBinding Information: 0 :             result returned from DATA GENERATION: 
DEBUG: ParameterBinding Information: 0 :         COERCE arg to [System.String]
DEBUG: ParameterBinding Information: 0 :             Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 :         BIND arg [] to param [Identity] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 : BIND PIPELINE object to parameters: [Test-Binding]
DEBUG: ParameterBinding Information: 0 :     PIPELINE object TYPE = [Microsoft.ActiveDirectory.Management.ADUser]
DEBUG: ParameterBinding Information: 0 :     RESTORING pipeline parameter's original values
DEBUG: ParameterBinding Information: 0 :     Parameter [Identity] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
DEBUG: ParameterBinding Information: 0 :     BIND arg [Microsoft.ActiveDirectory.Management.ADPropertyValueCollection] to parameter [Identity]
DEBUG: ParameterBinding Information: 0 :         Executing DATA GENERATION metadata: [System.Management.Automation.ArgumentTypeConverterAttribute]
DEBUG: ParameterBinding Information: 0 :             result returned from DATA GENERATION: Microsoft.ActiveDirectory.Management.ADPropertyValueCollection
DEBUG: ParameterBinding Information: 0 :         BIND arg [Microsoft.ActiveDirectory.Management.ADPropertyValueCollection] to param [Identity] SKIPPED
DEBUG: ParameterBinding Information: 0 :     Parameter [Identity] PIPELINE INPUT ValueFromPipelineByPropertyName WITH COERCION
DEBUG: ParameterBinding Information: 0 :     BIND arg [Microsoft.ActiveDirectory.Management.ADPropertyValueCollection] to parameter [Identity]
DEBUG: ParameterBinding Information: 0 :         Executing DATA GENERATION metadata: [System.Management.Automation.ArgumentTypeConverterAttribute]
DEBUG: ParameterBinding Information: 0 :             result returned from DATA GENERATION: 
DEBUG: ParameterBinding Information: 0 :         COERCE arg to [System.String]
DEBUG: ParameterBinding Information: 0 :             Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 :         ERROR: Argument cannot be an empty string
DEBUG: ParameterBinding Information: 0 : BIND PIPELINE object to parameters: [Out-Default]
DEBUG: ParameterBinding Information: 0 :     PIPELINE object TYPE = [System.Management.Automation.ErrorRecord]
DEBUG: ParameterBinding Information: 0 :     RESTORING pipeline parameter's original values
DEBUG: ParameterBinding Information: 0 :     Parameter [InputObject] PIPELINE INPUT ValueFromPipeline NO COERCION
DEBUG: ParameterBinding Information: 0 :     BIND arg [Cannot bind argument to parameter 'Identity' because it is an empty string.] to parameter [InputObject]
DEBUG: ParameterBinding Information: 0 :         BIND arg [Cannot bind argument to parameter 'Identity' because it is an empty string.] to param [InputObject] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Out-Default]
DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Out-LineOutput]
DEBUG: ParameterBinding Information: 0 :     BIND arg [Microsoft.PowerShell.Commands.Internal.Format.ConsoleLineOutput] to parameter [LineOutput]
DEBUG: ParameterBinding Information: 0 :         COERCE arg to [System.Object]
DEBUG: ParameterBinding Information: 0 :             Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 :         BIND arg [Microsoft.PowerShell.Commands.Internal.Format.ConsoleLineOutput] to param [LineOutput] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Out-LineOutput]
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Out-LineOutput]
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 : BIND PIPELINE object to parameters: [Out-LineOutput]
DEBUG: ParameterBinding Information: 0 :     PIPELINE object TYPE = [System.Management.Automation.ErrorRecord]
DEBUG: ParameterBinding Information: 0 :     RESTORING pipeline parameter's original values
DEBUG: ParameterBinding Information: 0 :     Parameter [InputObject] PIPELINE INPUT ValueFromPipeline NO COERCION
DEBUG: ParameterBinding Information: 0 :     BIND arg [Cannot bind argument to parameter 'Identity' because it is an empty string.] to parameter [InputObject]
DEBUG: ParameterBinding Information: 0 :         BIND arg [Cannot bind argument to parameter 'Identity' because it is an empty string.] to param [InputObject] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [out-lineoutput]
DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Format-Default]
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Format-Default]
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Format-Default]
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 : BIND PIPELINE object to parameters: [Format-Default]
DEBUG: ParameterBinding Information: 0 :     PIPELINE object TYPE = [System.Management.Automation.ErrorRecord]
DEBUG: ParameterBinding Information: 0 :     RESTORING pipeline parameter's original values
DEBUG: ParameterBinding Information: 0 :     Parameter [InputObject] PIPELINE INPUT ValueFromPipeline NO COERCION
DEBUG: ParameterBinding Information: 0 :     BIND arg [Cannot bind argument to parameter 'Identity' because it is an empty string.] to parameter [InputObject]
DEBUG: ParameterBinding Information: 0 :         BIND arg [Cannot bind argument to parameter 'Identity' because it is an empty string.] to param [InputObject] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [format-default]
DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 :     BIND arg [1] to parameter [Version]
DEBUG: ParameterBinding Information: 0 :         Executing DATA GENERATION metadata: [Microsoft.PowerShell.Commands.SetStrictModeCommand+ArgumentToVersionTransformationAt
tribute]
DEBUG: ParameterBinding Information: 0 :             result returned from DATA GENERATION: 1.0
DEBUG: ParameterBinding Information: 0 :         COERCE arg to [System.Version]
DEBUG: ParameterBinding Information: 0 :             Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 :         Executing VALIDATION metadata: [Microsoft.PowerShell.Commands.SetStrictModeCommand+ValidateVersionAttribute]
DEBUG: ParameterBinding Information: 0 :         BIND arg [1.0] to param [Version] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 : CALLING EndProcessing
DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 :     BIND arg [1] to parameter [Version]
DEBUG: ParameterBinding Information: 0 :         Executing DATA GENERATION metadata: [Microsoft.PowerShell.Commands.SetStrictModeCommand+ArgumentToVersionTransformationAt
tribute]
DEBUG: ParameterBinding Information: 0 :             result returned from DATA GENERATION: 1.0
DEBUG: ParameterBinding Information: 0 :         COERCE arg to [System.Version]
DEBUG: ParameterBinding Information: 0 :             Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 :         Executing VALIDATION metadata: [Microsoft.PowerShell.Commands.SetStrictModeCommand+ValidateVersionAttribute]
DEBUG: ParameterBinding Information: 0 :         BIND arg [1.0] to param [Version] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 : CALLING EndProcessing
DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 :     BIND arg [1] to parameter [Version]
DEBUG: ParameterBinding Information: 0 :         Executing DATA GENERATION metadata: [Microsoft.PowerShell.Commands.SetStrictModeCommand+ArgumentToVersionTransformationAt
tribute]
DEBUG: ParameterBinding Information: 0 :             result returned from DATA GENERATION: 1.0
DEBUG: ParameterBinding Information: 0 :         COERCE arg to [System.Version]
DEBUG: ParameterBinding Information: 0 :             Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 :         Executing VALIDATION metadata: [Microsoft.PowerShell.Commands.SetStrictModeCommand+ValidateVersionAttribute]
DEBUG: ParameterBinding Information: 0 :         BIND arg [1.0] to param [Version] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 : CALLING EndProcessing
DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 :     BIND arg [1] to parameter [Version]
DEBUG: ParameterBinding Information: 0 :         Executing DATA GENERATION metadata: [Microsoft.PowerShell.Commands.SetStrictModeCommand+ArgumentToVersionTransformationAt
tribute]
DEBUG: ParameterBinding Information: 0 :             result returned from DATA GENERATION: 1.0
DEBUG: ParameterBinding Information: 0 :         COERCE arg to [System.Version]
DEBUG: ParameterBinding Information: 0 :             Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 :         Executing VALIDATION metadata: [Microsoft.PowerShell.Commands.SetStrictModeCommand+ValidateVersionAttribute]
DEBUG: ParameterBinding Information: 0 :         BIND arg [1.0] to param [Version] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 : CALLING EndProcessing
Test-Binding : Cannot bind argument to parameter 'Identity' because it is an empty string.
At line:1 char:76
+ Trace-Command parameterbinding -Expression {Get-ADUser -Identity Test-User | Test- ...
+                                                                            ~~~~~
    + CategoryInfo          : InvalidData: (CN=Walter Kerce...,DC=contoso,DC=com:PSObject) [Test-Binding], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Test-Binding

DEBUG: ParameterBinding Information: 0 : CALLING EndProcessing
DEBUG: ParameterBinding Information: 0 : CALLING EndProcessing

我的目标是了解为什么此绑定在这种情况下会失败。

编辑:

这不是重复的,因为我不使用 $null 返回。

【问题讨论】:

  • 已接受的链接问题的答案准确地指出了为什么会这样。您也可以通过 Get-ADUser 调用来测试它。这不是关于Get-ADUser 返回$null,而是Identity 属性将动态添加到返回的对象中,其值为$null,而不仅仅是丢失。因为它存在,所以它被绑定到管道输入并且永远不会使用别名。
  • @briantist 实际上没有。如果您遵循面包屑,则声称当输入为 $null 数据时您会遇到问题。正如我在编辑中所说,我没有使用 $null 输入。
  • 函数的输入 $null,因为你使用的是ValueFromPipelineByPropertyName。 PowerShell 首先尝试使用实际参数名称 (Identity)。通常,这将是缺失,它会继续绑定别名。但是,在 AD cmdlet 的情况下,将会发生的情况是,如果请求的 any 属性名称不存在,则将动态生成其值 $null。然后绑定该动态属性,因此永远不会检查别名。
  • @briantist 正如我在问题中所说的那样,并且在调试输出中可以观察到,powershell 能够识别匹配项。这是您第二次在未完全阅读您所评论内容的情况下发表评论。我不会再回复你的cmets了。感谢您的宝贵时间。
  • 我已完全阅读我所评论的内容。我认为Trace-Command 输出支持我所说的(顺便说一句,这与您接受的答案和链接副本中的内容相同)。

标签: powershell binding active-directory powershell-4.0


【解决方案1】:

不幸的是,这是 AD cmdlet 的一个已知问题 - 如果您向 AD cmdlet 生成的对象询问它没有的属性,它会自动生成并为其提供 $null 值,而不是正确返回该值该属性不存在,这将允许参数绑定继续并获得正确的值。

您可以查看有关此here 的 Microsoft Connect 项。

我见过的唯一解决方法是在函数中使用 AD 对象使用的确切属性名称命名参数,并为其他名称命名。如果我希望能够通过管道将 Get-ADComputer 传递给它,我经常必须将参数命名为 DNSHostName,例如,使用别名 ComputerName。

【讨论】:

  • 我还要补充一点,另一种解决方法是使用这样的代码:Get-ADUser -Filter * | Select SamAccountName | Test-Binding
猜你喜欢
  • 2019-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-30
  • 1970-01-01
  • 2021-05-11
  • 1970-01-01
相关资源
最近更新 更多