Monday, March 21, 2016

Powershell: Using optional paramaters

Have you ever created a cmdlet that was a wrapper for another command but you added optional parameters. This is a very common pattern. But how do you pass or not pass that optional parameter to the underlying command? How often do you create an if or switch to check for it and have the function call in your code twice? Once with the param and once with out it.

This is such a common pattern especially when dealing with credentials. I saw this example in someone else's code:

if($Credential)
{
    foreach($Computer in $ComputerName)
    {
        $Disks += Get-WmiObject Win32_LogicalDisk -ComputerName $Computer -Filter "DeviceID='C:'" -Credential $Credential -ErrorAction SilentlyContinue
    }
}
else
{
    foreach($Computer in $ComputerName)
    {
        $Disks += Get-WmiObject Win32_LogicalDisk -ComputerName $Computer -Filter "DeviceID='C:'"
    }
}

The credential was optional to his use of the cmdlet. I just don't like to see code repeated like that. Sure, he could have placed the if logic inside the foreach loop. But he still has logic in two places. I see the error action is set to SilentlyContinue for one of them. I can't tell if that is intentional or it should have been on both.

This is that same code but using a hashtable and splatting to deal with the optional parameter.

$LogicalDiskArgs = @{
    Class  = 'Win32_LogicalDisk'
    Filter = "DeviceID='C:'"       
}

if($Credential)
{
    $LogicalDiskArgs.Credential  = $Credential
    $LogicalDiskArgs.ErrorAction = 'SilentlyContinue'
}

foreach($Computer in $ComputerName)
{
    $Disks += Get-WmiObject @LogicalDiskArgs -ComputerName $Computer
}

The use of splatting makes this really easy to do. I like how this really shows the intent of using that error action with the optional parameter. 

 

1 comment: