I've been working on a project to introduce Azure IaaS VM deployments into an existing VM provisioning codeset. This is a huge codeset that has hundreds of various instances of Invoke-Command �calls spread out across dozens of modules.

Currently, all of these Invoke-Command references were not using SSL and I was tasked with moving all communication to VMs with WinRM over SSL.

I essentially had two ways to do this. I could either modify hundreds of Invoke-Command references adding a few more parameters with some code:

$icmParams = @{
    'ComputerName' = $ComputerName
    'UseSSL' = $true
    'Port' = 5986
    'SessionOption' = (New-PSSessionOption -SkipCACheck -SkipCNCheck)
}

...or I could somehow modify the behavior of all of those Invoke-Command references without having to copy/paste a bunch of extra code all over the place.

I chose the latter.

I first started out building my own Invoke-Command proxy function. However, since I was using multiple modules, I was running into some wonky problems when passing scriptblocks across the modules when using $using construct variables. I eventually got it working thanks to Dave Wyatt's help but the code was ugly. I thought there had to be a better way. It turns out, I think there is! The answer is $PSDefaultParameterValues!

Here's my solution:

$winRmParams = @{
    'UseSSL'= $true
    'Port'= '5986'
    'SessionOption' = (New-PSSessionOption -SkipCNCheck -SkipCACheck)
}

foreach ($i in $winRmParams.GetEnumerator()) {    
    $PSDefaultParameterValues.Add("Invoke-Command:$($i.Key)", $i.Value)       $PSDefaultParameterValues.Add("New-PSSession:$($i.Key)", $i.Value)
}
    
$Global:PSDefaultParameterValues = $PSDefaultParameterValues.clone()

I have this code located in the root module which will modify $PSDefaultParameterValues for both Invoke-Command (and the few instances in there making use of New-PSSession) as soon as the entire module stack is imported. This is the reason I needed to modify $PSDefaultParameterValues at the global scope. Otherwise, that might not have been necessary.

This does overwrite any $PSDefaultParameterValues you have in your profile. However, myself and my team don't use this automatic variable so we weren't affected however YMMV.

By using $PSDefaultParameterValues instead of building a proxy function and messing with session states and scopes makes this solution much simpler.

Join the Jar Tippers on Patreon

It takes a lot of time to write detailed blog posts like this one. In a single-income family, this blog is one way I depend on to keep the lights on. I'd be eternally grateful if you could become a Patreon patron today!

Become a Patron!