Question:
Trying to create a function that takes objects on the pipeline using the alias property. I’m not sure where this is going wrong.
Example of the process:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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)" } |
If I run this command:
1 2 |
Get-Aduser -filter {sn -eq 'smith'} -properties sn,givenname | Get-Name |
the output looks like this:
1 2 3 |
firstName = / string LastName = / string |
The Function never seems to grab the sn and givenname attributes from the passed in object. What am I missing?
Answer:
The AD Cmdlets are to blame here
The problem here is that the AD Cmdlets return objects in really non-standard ways. For instance, with any other cmdlet if you take the output of the command and select a non-existing property, you’ll get back nothing, like this:
1 2 3 4 5 6 7 |
get-date | select Hamster Hamster ------- > |
See, nothing. Sure, it says Hamster, but there is no actual Object there. This is standard PowerShell behavior.
Now, look at what Get-ADUser does instead:
1 2 3 4 5 6 |
get-aduser -Filter {sn -eq 'adkison'} | select Hamster Hamster ------- {} |
It creates a $null! So what will happen with your function is that PowerShell will look for a property of -LastName or -FirstName, get a $null and then stop right there. It sucks!
The best way around this is to swap the parameter names like this, and it will still work:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
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 |