PowerShell 函数 ValueFromPipelineByPropertyName 不使用别名参数名称
PowerShell function ValueFromPipelineByPropertyName not using alias parameter name
正在尝试创建一个使用别名 属性 在管道上获取对象的函数。我不确定这是哪里出了问题。
过程示例:
function Get-Name
{
Param
(
[Parameter(ValueFromPipelineByPropertyName=$true)]
[alias("givenname")]
[System.String] $FirstName,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[alias("sn")]
[System.String] $LastName
)
write-host "firstName = $FirstName / $($FirstName.GetType().FullName)"
Write-host "LastName = $LastName / $($LastName.GetType().FullName)"
}
如果我运行这个命令:
Get-Aduser -filter {sn -eq 'smith'} -properties sn,givenname | Get-Name
输出如下所示:
firstName = / string
LastName = / string
该函数似乎从未从传入的对象中获取 sn 和 givenname 属性。我错过了什么?
AD Cmdlet 是罪魁祸首
这里的问题是 AD Cmdlets return 以非常不标准的方式对象。例如,对于任何其他 cmdlet,如果您获取命令的输出和 select 一个不存在的 属性,您将一无所获,如下所示:
get-date | select Hamster
Hamster
-------
>
看,没什么。当然,它说的是 Hamster,但那里没有实际的 Object。这是标准的 PowerShell 行为。
现在,看看 Get-ADUser 做了什么:
get-aduser -Filter {sn -eq 'adkison'} | select Hamster
Hamster
-------
{}
它创建了一个 $null!因此,您的函数将发生的情况是,PowerShell 将查找 -LastName 或 -FirstName 的 属性,得到 $null,然后就停在那里。糟透了!
解决此问题的最佳方法是像这样交换参数名称,它仍然有效:
function Get-Name
{
Param
(
[Parameter(ValueFromPipelineByPropertyName=$true)]
[alias('FirstName')]
[System.String] $givenname,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[alias("sn","lastname")]
[System.String] $Surname
)
write-host "firstName = $givenname / $($givenname.GetType().FullName)"
Write-host "LastName = $SurName / $($SurName.GetType().FullName)"
}
get-aduser -Filter {sn -eq 'adkison'} | Get-Name
firstName = James / System.String
LastName = Adkison / System.String
想了解更多?
从我能够确定的情况来看,从技术上讲,这不是 AD cmdlet 的罪魁祸首,而是 Microsoft.ActiveDirectory.Management
命名空间中的类型——在这种情况下,ADUser
. ADUser
上的属性最终都只是存储在私有 SortedDictionary
中并通过 get 访问器获取,这也许可以解释为什么它不能按预期工作。
正如 Colyn1337 在之前的评论中提到的,ADUser
默认不包含名为 sn
或 LastName
的 属性(或键),所以您需要在 LastName
参数中包含别名 Surname
或在 Get-ADUser
调用中包含 select sn
:
Get-ADUser -Filter {sn -eq 'Adkison'} -Properties sn | Get-Name
这仍然行不通,但是您可以从那里直接通过管道传输到 Select-Object
,然后再传输到您的函数:
Get-ADUser -Filter {sn -eq 'Adkison'} -Properties sn | Select * | Get-Name
当然,您也可以只 select 您需要的特定属性,而不是 Select-Object
中的 *。我认为这是可行的,因为它将 ADUser
字典解析为具有具体属性的 PSCustomObject
。解析后,它们将匹配别名以及实际参数名称。
正在尝试创建一个使用别名 属性 在管道上获取对象的函数。我不确定这是哪里出了问题。
过程示例:
function Get-Name
{
Param
(
[Parameter(ValueFromPipelineByPropertyName=$true)]
[alias("givenname")]
[System.String] $FirstName,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[alias("sn")]
[System.String] $LastName
)
write-host "firstName = $FirstName / $($FirstName.GetType().FullName)"
Write-host "LastName = $LastName / $($LastName.GetType().FullName)"
}
如果我运行这个命令:
Get-Aduser -filter {sn -eq 'smith'} -properties sn,givenname | Get-Name
输出如下所示:
firstName = / string
LastName = / string
该函数似乎从未从传入的对象中获取 sn 和 givenname 属性。我错过了什么?
AD Cmdlet 是罪魁祸首
这里的问题是 AD Cmdlets return 以非常不标准的方式对象。例如,对于任何其他 cmdlet,如果您获取命令的输出和 select 一个不存在的 属性,您将一无所获,如下所示:
get-date | select Hamster
Hamster
-------
>
看,没什么。当然,它说的是 Hamster,但那里没有实际的 Object。这是标准的 PowerShell 行为。
现在,看看 Get-ADUser 做了什么:
get-aduser -Filter {sn -eq 'adkison'} | select Hamster
Hamster
-------
{}
它创建了一个 $null!因此,您的函数将发生的情况是,PowerShell 将查找 -LastName 或 -FirstName 的 属性,得到 $null,然后就停在那里。糟透了!
解决此问题的最佳方法是像这样交换参数名称,它仍然有效:
function Get-Name
{
Param
(
[Parameter(ValueFromPipelineByPropertyName=$true)]
[alias('FirstName')]
[System.String] $givenname,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[alias("sn","lastname")]
[System.String] $Surname
)
write-host "firstName = $givenname / $($givenname.GetType().FullName)"
Write-host "LastName = $SurName / $($SurName.GetType().FullName)"
}
get-aduser -Filter {sn -eq 'adkison'} | Get-Name
firstName = James / System.String
LastName = Adkison / System.String
想了解更多?
从我能够确定的情况来看,从技术上讲,这不是 AD cmdlet 的罪魁祸首,而是 Microsoft.ActiveDirectory.Management
命名空间中的类型——在这种情况下,ADUser
. ADUser
上的属性最终都只是存储在私有 SortedDictionary
中并通过 get 访问器获取,这也许可以解释为什么它不能按预期工作。
正如 Colyn1337 在之前的评论中提到的,ADUser
默认不包含名为 sn
或 LastName
的 属性(或键),所以您需要在 LastName
参数中包含别名 Surname
或在 Get-ADUser
调用中包含 select sn
:
Get-ADUser -Filter {sn -eq 'Adkison'} -Properties sn | Get-Name
这仍然行不通,但是您可以从那里直接通过管道传输到 Select-Object
,然后再传输到您的函数:
Get-ADUser -Filter {sn -eq 'Adkison'} -Properties sn | Select * | Get-Name
当然,您也可以只 select 您需要的特定属性,而不是 Select-Object
中的 *。我认为这是可行的,因为它将 ADUser
字典解析为具有具体属性的 PSCustomObject
。解析后,它们将匹配别名以及实际参数名称。