During a recent talk I gave at the Cincinnati PowerShell User Group, I briefly demonstrated the technique I use to create advanced functions that accept credentials. I’ve been using this approach for a while and thought it would be great to show it off so others can take advantage of it. Of course like most demos it failed miserably. Here’s why:
PowerShell 4.0 - The Way We Were
In PowerShell 2 and above we could specify that a function parameter should accept objects of type
System.Management.Automation.PSCredential, or use the type adapter
[PSCredential] starting in v3.0:
This parameter will accept a pre-created credential object and nothing else:
However, if you want to pass in a string username you’re out of luck:
To do this we need to use the System.Management.Automation.CredentialAttribute() parameter attribute:
You can read about how this attribute works here. When you use this attribute your credential parameter will happily accept either credential object or a string username, in which case you’ll be prompted to enter the password:
So I attempted to demonstrate this approach in my demo and found that when I ran
Test-PSCredential I didn’t receive an error - it behaved exactly the same way as using
CredentialAttribute()! It seems that the
PSCredential class has gotten a bit of an upgrade in PowerShell 5.0. Let’s check it out:
Trace-Command we can watch the parameter binding process and see that
PSCredential is now leveraging the
CredentialAttribute argument transformation in the background! This makes it really easy to create flexible function parameters that accept either a credential object, or a simple string username.
I’m not sure when this feature was added to the
PSCredential class as the MSDN documentation doesn’t seem to allude to this at all. Also, keep in mind that since this was only added in PowerShell 5.0, you’ll need to continue using the
CredentialAttribute() decoration to support downlevel versions of PowerShell.
The above MSDN article on the
CredentialAttribute class states that it inherits from the ArgumentTransformationAttribute class. I find this intriguing and would love to learn more about argument transformations and if any other classes inherit from this or leverage it’s functionality. If you have any background on this class, please hit me up or blog about it somewhere.