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
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.