Using $PSDefaultParameterValues in PowerShell

Recently I saw someone posted a reply to one of my comments on a blog article that he had never heard of $PSDefaultParameterValues before now.  With that, I will give you a walkthrough of this feature added in PowerShell V3 and show you some thing that you can do with it!

$PSDefaultParameterValues is an automatic variable that exists in PowerShell and the object type is System.Management.Automation.DefaultParameterDictionary. Basically, this is a hash table that you can add a Name/Value combination to the existing object. However, unlike a typical hash table, there are requirements to adding items to this object.

There are 3 possibly syntaxes that are allowed with this:

  • $PSDefaultParameterValues=@{“<CmdletName>:<ParameterName>”=”<DefaultValue>”}
  • $PSDefaultParameterValues=@{“<CmdletName>:<ParameterName>”={<ScriptBlock>}}
  • $PSDefaultParameterValues[“Disabled”]=$true | $false

Note that just using the top two syntaxes will overwrite the current object. If you wish to add things to the existing object, you have to use the Add() method instead.

  • $PSDefaultParameterValues.Add({“<CmdletName>:<ParameterName>”,”<DefaultValue>”})

Removing an item is as easy as using the .Remove() method.

  • $PSDefaultParameterValues.Remove(“<CmdletName>:<ParameterName>”)

Lastly, you can clear out everything in this object by calling the .Clear() method.

$PSDefaultParameterValues.Clear()

You can also Enable or Disable the object globally, meaning that everything will either work (Enabled) or not work (Disabled).

#Disable
$PSDefaultParameterValues.Add("Disabled", $true)
#OR
$PSDefaultParameterValues["Disabled"] = $true
#Enable
$PSDefaultParameterValues.Add("Disabled", $false)
#OR
$PSDefaultParameterValues["Disabled"] = $false

Ok, now that we have covered the syntaxes and being able to enable/disable this as well, it is time to dive in and show some examples.

Let’s say we want to make sure that we do not accidently stop any processes using Stop-Process. We can force WhatIf to always be used with Stop-Process to better protect ourselves:

$PSDefaultParameterValues.Add("Stop-Process:WhatIf",$True)

image

Ok, lets try this out.

Get-Process | Stop-Process

image

Perfect! Instant safety net to avoid any potential issues.

Heck, we can take it one step further by forcing all cmdlets and functions to force WhatIf:

$PSDefaultParameterValues.Add("*:WhatIf",$True)

 

image

Now anything that utilizes WhatIf will not actually make any changes.

If I wanted a little more security, but not outright blocking my ability to perform an action, then I could just set Confirm to $True.

$PSDefaultParameterValues.Add("*:Confirm",$True)

image

One of the last cool things you can do is specify a script block that can run different default values based on a certain condition, such as using Format-Table.

$PSDefaultParameterValues=@{"Format-Table:AutoSize"={if ($host.Name -eq "ConsoleHost"){$true}}}

Other things that could prove to be useful are adding Verbose output on specific cmdlets, setting up an some parameters for Send-MailMessage. A personal favorite is using some saved credentials to automatically supply them on any cmdlet that has a Credential parameter.

I would recommend that if you have favorite or common values for parameters that you use, you should make some additions to you PowerShell profile to include them.

Some of the values that I use in my PowerShell profile:

$Cred = Get-Credential
$PSDefaultParameterValues.Add("*:Credential",$Cred)
$PSDefaultParameterValues.Add("Get-ChildItem:Force",$True)
$PSDefaultParameterValues.Add("Receive-Job:Keep",$True)
$PSDefaultParameterValues.Add("Format-Table:AutoSize",{if ($host.Name -eq "ConsoleHost"){$true}})
$PSDefaultParameterValues.Add("Send-MailMessage:To","<emailaddress>")
$PSDefaultParameterValues.Add("Send-MailMessage:SMTPServer","mail.whatever.com")
$PSDefaultParameterValues.Add("Update-Help:Module","*")
$PSDefaultParameterValues.Add("Update-Help:ErrorAction","SilentlyContinue")
$PSDefaultParameterValues.Add("Test-Connection:Quiet",$True)
$PSDefaultParameterValues.Add("Test-Connection:Count","1")

I am always interested in seeing what others are using, so feel free to share what you are using with $PSDefaultParameterValues!

This entry was posted in powershell, V3, V4 and tagged , , , . Bookmark the permalink.

4 Responses to Using $PSDefaultParameterValues in PowerShell

  1. Todd says:

    Using your -Credential trick, I had a problem with Get-WMIObject. I ran that command, but did not supply a -ComputerName, and this resulted:

    Get-WmiObject : User credentials cannot be used for local connections

    I wonder if there’s a way to say ‘supply credential for everything except the Get-WMIObject command’.

  2. live a day; learn a lot; great post, thanks for sharing

  3. Pingback: UC Unleashed » PowerShell Default Parameter Values – Time to Tweak Your Profile Again!

  4. mjolinor says:

    IMHO, it’s notable that $PSDefaultParameter is the only preference variable that is a hash table.

    Normally preference variables set withing a function or script will be isolated to that scope. Adding a default parameter setting in a function or script can pollute the local scope if you don’t create it as a new hash table in the function or script.

    If you want to also retain the existing default settings in the parent scope, create a new hash table in the child scope using $PSDefaultParameterValues.clone(), then add your scope-specific defaults to that.

Leave a comment