Weekend Scripter: Wow! I Didn’t Know You Could Do That in PowerShell!
Summary: Discover the power of the “double splat.”
Honorary Scripting Guy, Sean Kearney, here filling in for our good friend, Ed. He’s keeping himself inside where it’s warm. I’m here in Canada typing really fast to keep even warmer! It’s 31 degrees below Celsius here in Ottawa, don’t cha know?
I was developing a solution that needed to authenticate against two Active Directory domains, and the client threw in a twist during development (yes, these things happen). During this process, I discovered a cool trick called “double splatting.”
In my script, I first needed to authenticate against two possible Active Directory domains. “Well, that’s awfully easy,“ I thought to myself. “I’ll simply have two Windows PowerShell variables to hold the credentials and the domain controller, and use them as I create users. Too easy.”
Yes, that was the original thought. But as the script grew, feature creep from the client came forth. Additional parameters, such as target organizational units were be added to the mix. Multiple situations with more Active Directory cmdlets appeared.
I found that I was adding the same information over and over and over…
So to resolve that issue, I decided to bite the bullet and use “splatting.” Splatting is a cool technique in Windows PowerShell where you can define parameters for a cmdlet and its values within an array, and pass that object directly to the cmdlet. The big advantage of splatting (other than avoiding some typing and a readability improvement) is that if there are common parameters that I need to change “en-masse” in a script, I can edit the array.
In my original script, I wrote something like this to query a user:
$MyClearTextPassword –AsPlainText –force
$Cred=New-object System.Management.Automation.PSCredential $MyUsernameDomain,$SecurePassword
Then each time I would try to query a user, I would do this:
REMOVE-ADUser JohnSmith –credential $Cred –server $DC
To use splatting, first create an array that contains the names of parameters for a cmdlet and their values:
Then pass it directly to the cmdlet:
REMOVE-ADUser JohnSmith @ADparams
This now makes flipping the credentials and servers easier. I can also add additional parameters to the same array, and the cmdlets will use them. I was in my glory. Life was good…until…
The client decided, yes, feature creeeeep!
They needed to ensure that they could have a safety switch to test the script—not just a single cmdlet—without hurting data.
Well, in Windows PowerShell, that’s easy. That’s the –whatif parameter. I can flip cmdlets to automatically default to a whatif mode by setting this variable:
This worked like a charm, but every cmdlet (including those for creating logs) warned about what they were going to do without doing it. In my case, I only wanted it to happen for Active Directory cmdlets.
Soooooo…scrap that idea.
Then I stumbled across something really cool. When mucking about, I found that I can splat twice!
Yes, the parser doesn’t only work on one splat, you can have multiple in the same cmdlet. In my case, I created a tiny splat for the –whatif parameter by defining one of two possible values.
To work with those cmdlets, I can pass two splats to the Active Directory cmdlets that need a safety switch, and change the script globally from the top level as a parameter:
REMOVE-ADuser JohnSmith @AdParams @Safety
The double splat! An available, built-in feature in Windows PowerShell. It’s been sitting there and ready to use the whole darn time!
We now return you to your regularly scheduled scripting!
I invite you to follow the Scripting Guys on Twitter and Facebook. If you have any questions, send email to firstname.lastname@example.org, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Sean Kearney, Honorary Scripting Guy and Windows PowerShell MVP