PowerShell Tips and Tricks: Using Default Parameter Values


Summary: Microsoft Scripting Guy, Ed Wilson, talks about using default Windows PowerShell parameter values.

Microsoft Scripting Guy, Ed Wilson, is here. The last thing I want to talk about from the tips and tricks session of the Charlotte Windows PowerShell User Group with Lee Holmes is using default Windows PowerShell parameter values.

To effectively use Windows PowerShell default parameter values, I need to first evaluate how I work. For example, if I routinely add –Wrap when I am using the Format-Table cmdlet, it might make sense for me to set that as my default.

To do this, I simply need to assign a value for the $PSDefaultParameterValues automatic variable. But this is not completely simple, because I need to assign my values as a type of hash table. (It is actually a System.Management.Automation.DefaultParameterDictionary object, but basically it is a hash table).

This means that I will be assigning keys and values to the hash table. The first thing I add is the key, and the second thing I add is my default value.

If I want to always use –Wrap with the Format-Table cmdlet, I need to add something like the following:

$PSDefaultParameterValues = @{"Format-Table:Wrap" = $true}

The key name looks a little weird because I specify the cmdlet name and then the parameter name. But if you think about it, maybe it is not too weird because all keys need to be unique, and it is very likely that I might want to specify more than one default parameter for a cmdlet. So this syntax sort of makes sense.

I do not have to add it to my Windows PowerShell profile, but this is a logical place to add it. I could, for example, add it to a script, or simply run it in my Windows PowerShell ISE session. In the following image, I assign the value in my Windows PowerShell ISE session, and then I can take advantage of the default parameter value (if I do not close the Windows PowerShell ISE).

Image of command output

I can look at the value of the $PSDefaultParameterValues variable and see the hash table I created:

PS C:\> $PSDefaultParameterValues

Name                      Value                                                  

----                             -----                                                  

Format-Table:Wrap        True  

If I want to add an additional default parameter value, I simply separate the values with a semicolon. But before I do that, I should stop to see all the places a particular parameter may be used. To do this, I use the Get-Command cmdlet and specify the name of the parameter I am interested in using. For example, I often use –Wrap and –AutoSize together, but I want to check to see where –AutoSize is used. This is shown here:

PS C:\> Get-Command -ParameterName autosize

CommandType     Name                        ModuleName         

-----------     ----                                               ----------          

Cmdlet          Format-Table                 Microsoft.PowerSh...

Cmdlet          Format-Wide                  Microsoft.PowerSh...

This makes sense, and if I am using Format-Wide, I also add the –AutoSize parameter. With this knowledge, I can use a wildcard formation to add my default parameter value. This is shown here:

$PSDefaultParameterValues = @{

    "*:AutoSize"=$true;

    "Format-Table:Wrap" = $true;

}

Now when I run a Windows PowerShell command and pipe it to Format-Table, I see that it automatically wraps and sizes. This is shown here:

Image of command output

If I want to turn off one of the default parameter values for a single command, I need to remember to overwrite them. In the case of a switched parameter, I add $false to the command. This is shown here:

Get-Process -FileVersionInfo -ea 0| Format-Table -AutoSize:$false

As shown here, when I run the Windows PowerShell command, I am no longer autosizing my output:

Image of command output

I can also add a script block that will be evaluated when the cmdlet runs. In the following command, I query Active Directory for all computers. I filter to see if the computer is up and responding to ping requests, and then I create an array of computer names and assign it to the ComputerName parameter as a default value.

$PSDefaultParameterValues = @{

    "*:ComputerName"= {((Get-ADComputer -filter *).name).Where(

     {Test-Connection $_ -Quiet})};

    "*:AutoSize"=$true;

    "Format-Table:Wrap" = $true;

}

This works, as shown here:

Image of command output

The problem with this approach is two-fold. First it is really slow. Every time I want to run a command remotely, I query for a list of computers, and then ping every one in succession to see if they are up. I finally have the list of computers I can use. The second problem is that there are lots of cmdlets that accept a ComputerName parameter. Ufortunately, not all of them are firewall friendly, and therefore, not all will work. In addition, some of the commands require special services to be running (such as the remote registry service).

That is all there is to using default Windows PowerShell parameter values. Join me tomorrow when I will have an article from the Scripting Wife about her ideal Ignite 2015 schedule.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Comments (2)

  1. Anonymous says:

    That’s pretty clear expalanations, thanks for your post !

Skip to main content