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:
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:
Get-Aduser -filter {sn -eq 'smith'} -properties sn,givenname | Get-Name
the output looks like this:
firstName = / string
LastName = / string
The Function never seems to grab the sn and givenname attributes from the passed in object. What am I missing?
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:
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:
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:
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
Check out this awesome answer from /u/JBSmith on the topic.
From what I've been able to determine, it isn't technically the AD cmdlets that are to blame, but the types in the Microsoft.ActiveDirectory.Management
namespace--in this case, ADUser
. The properties on ADUser
are ultimately all just stored in a private SortedDictionary
and fetched through get accessors, which might explain why it doesn't work quite as expected.
As alluded to by Colyn1337 in a previous comment, ADUser
doesn't contain a property (or key) named either sn
or LastName
by default, so you'd need to either include an alias of Surname
on your LastName
parameter or select sn
in your Get-ADUser
call:
Get-ADUser -Filter {sn -eq 'Adkison'} -Properties sn | Get-Name
That still won't work, but from there you can just pipe to Select-Object
before piping to your function:
Get-ADUser -Filter {sn -eq 'Adkison'} -Properties sn | Select * | Get-Name
Of course, you could also just select the specific properties you need instead of * in Select-Object
. I assume this works because it resolves the ADUser
dictionary into a PSCustomObject
with concrete properties. Once resolved, they will match aliases as well as the actual parameter names.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With