function - Función PowerShell ValueFromPipelineByPropertyName que no utiliza el nombre del parámetro alias
parameters (2)
Intentando crear una función que tome objetos en la tubería usando la propiedad de alias. No estoy seguro de dónde está yendo mal.
Ejemplo del proceso:
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)"
}
Si ejecuto este comando:
Get-Aduser -filter {sn -eq ''smith''} -properties sn,givenname | Get-Name
la salida se ve así:
firstName = / string
LastName = / string
La función nunca parece captar los atributos sn y givenname del objeto pasado. ¿Qué me estoy perdiendo?
Según lo que he podido determinar, técnicamente no son los cmdlets de AD los culpables, sino los tipos en el espacio de nombres de Microsoft.ActiveDirectory.Management
, en este caso, ADUser
. Las propiedades de ADUser
finalmente se almacenan en un SortedDictionary
privado y se obtienen a través de los SortedDictionary
, lo que podría explicar por qué no funciona del modo esperado.
Como se mencionó en Colyn1337 en un comentario anterior, ADUser
no contiene una propiedad (o clave) denominada sn
o LastName
de forma predeterminada, por lo que necesitaría incluir un alias de Surname
en su parámetro LastName
o seleccionar sn
en su Get-ADUser
:
Get-ADUser -Filter {sn -eq ''Adkison''} -Properties sn | Get-Name
Eso todavía no funcionará, pero a partir de ahí puede simplemente conectar a Select-Object
antes de conectar a su función:
Get-ADUser -Filter {sn -eq ''Adkison''} -Properties sn | Select * | Get-Name
Por supuesto, también puede simplemente seleccionar las propiedades específicas que necesita en lugar de * en Select-Object
. Supongo que esto funciona porque resuelve el diccionario ADUser
en un PSCustomObject
con propiedades concretas. Una vez resueltos, coincidirán los alias y los nombres de los parámetros reales.
Los Cmdlets AD son los culpables aquí
El problema aquí es que los Cmdlets de AD devuelven objetos de maneras realmente no estándar. Por ejemplo, con cualquier otro cmdlet si toma el resultado del comando y selecciona una propiedad que no existe, no obtendrá nada como este:
get-date | select Hamster
Hamster
-------
>
No ver nada. Claro, dice Hamster, pero no hay ningún objeto real allí. Este es el comportamiento estándar de PowerShell.
Ahora, mira lo que hace Get-ADUser:
get-aduser -Filter {sn -eq ''adkison''} | select Hamster
Hamster
-------
{}
¡Crea un $ null! Entonces, qué sucederá con su función es que PowerShell buscará una propiedad de -LastName o -FirstName, obtendrá un $ null y luego se detendrá allí mismo. ¡Apesta!
La mejor forma de evitar esto es intercambiar los nombres de parámetros como este y seguirá funcionando:
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
¿Quiere saber más?
Mira esta increíble respuesta de / u / JBSmith sobre el tema.