Lately, I have been using splatting more and more in my scripts. For those of you that don’t know what splatting is, let me first demo how it works.

Basically, you take a normal cmdlet like Send-MailMessage with all it’s parameters and convert it to a hash table. The following command shows a typical cmdlet with it’s many parameters that can be lengthy.

Send-MailMessage -To helpdesk@fabrikam.com -From monitor@fabrikam.com -Bcc admin@fabrikam.com -Subject "Low Disk Space" -Body $body -BodyAsHtml -SmtpServer mail.fabrikam.com -ErrorAction Stop

NOTE: The reason I am adding the ErrorAction parameter is to show you that you should be using Try-Catch to wrap all your command within a script.

As you can see – when sharing something like this in an email, you don’t know when it is going to wrap, or copying that out may cause issues and it is hard to read.

Now, let’s look at splatting using the same command above.

$mailParams = @{
    To          = "helpdesk@fabrikam.com"
    From        = "monitor@fabrikam.com"
    Bcc         = "admin@fabrikam.com"
    Subject     = "Low Disk Space"
    Body        = $body
    BodyAsHtml  = $true
    SmtpServer  = "mail.fabrikam.com"
    ErrorAction = "Stop"
}
Send-MailMessage @mailParams

Note: When Splatting and calling the hash table, be sure you change the “$” to “@”.

Now you can see how it is easier to read, probably doesn’t wrap on your screen and easy to see all the parameters.

The other nice thing is you can easily modify parameters in your script. Let’s assume you are testing a script and you don’t want to spam your help desk and the admin account with 20 test messages. You can add an IF statement to modify attributes.

if ($testing) {
    $mailParams.To = "myaccount@fabrikam.com"
    $mailParams.Remove("Bcc")
}

As you can see with the above statement, I can replace parts of the parameters, and even remove another. You can also add other parameters by just running a command like this:

$mailParams.WhatIf = $true

So it gives me a way to build the parameters and only call the “Send-MailMessage” cmdlet once.

Now, this is what I love about the above example. I wrote a script for a customer whose email server crashed. My script could NOT send emails. The Try-Catch block caught this in the logs, but we could NOT simply recover those emails. Now, in reality, the above Send-MailMessage is actually sending notifications about new users or modified user from an automation script. My customer had to go through the logs to find all the messages that should have been sent and manually re-build the emails. These emails were complex with a Welcome message, information about their accounts, etc. They asked if there was a simple way to also document these emails.

After discussing what they wanted, we came up with a simple answer, Export-CliXml. I added an Export CliXml that takes those parameters and dumps them to a file.

$mailParams | Export-CliXml -Path "C:\Logs\LastEmail.xml"

I also then built a GUI tool that parses the logs folder for XML and can show the run of the EXE a preview of the Email and then they can re-send the mail message with a single button click in the GUI.

Behind the code of the GUI is a simple code something like this:

$mailParams = Import-Clixml -Path "C:\Logs\LastEmail.xml"
Try {
    Send-MailMessage @mailParams
} Catch {
    Write-Warning -Message "Cannot send because $_"
}

It will resend the mail message, with all the parameters. Much simpler that having the administrators go through the logs, find all the information required to be in the emails, copy-paste into another email message and then send the mail message.

So, once you build your hash table for splatting, the option to save the table as XML may give you the option to save those parameters if you need to.