Setting a Proxy without changing your #PowerShell Code

Hardcoding a proxy server is an anti-pattern and you are probably aware of this. But how do you handle it when your PowerShell code is executed in different environment with and without a proxy server. You certainly do not want to add parameters for this because this would only be the beginning. $PSDefaultParameterValues to the rescue!

I bet you already know where to add the proxy server because you see where the code stalls and eventually fails. In most cases, this will be cmdlets like Invoke-WebRequest and Invoke-RestMethod but there are a few more. A quick search for cmdlets with a proxy parameter shows a total of 22 cmdlets:

PS> Get-Command -ParameterName Proxy

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Find-Command                                 PowerShellGet
Function        Find-DscResource                             PowerShellGet
Function        Find-Module                                  PowerShellGet
Function        Find-RoleCapability                          PowerShellGet
Function        Find-Script                                  PowerShellGet
Function        Install-Module                               PowerShellGet
Function        Install-Script                               PowerShellGet
Function        Register-PSRepository                        PowerShellGet
Function        Save-Module                                  PowerShellGet
Function        Save-Script                                  PowerShellGet
Function        Set-PSRepository                             PowerShellGet
Function        Update-Module                                PowerShellGet
Function        Update-Script                                PowerShellGet
Cmdlet          Find-Package                                 PackageManagement
Cmdlet          Find-PackageProvider                         PackageManagement
Cmdlet          Install-Package                              PackageManagement
Cmdlet          Install-PackageProvider                      PackageManagement
Cmdlet          Invoke-RestMethod                            Microsoft.PowerShell.Utility
Cmdlet          Invoke-WebRequest                            Microsoft.PowerShell.Utility
Cmdlet          Register-PackageSource                       PackageManagement
Cmdlet          Save-Package                                 PackageManagement
Cmdlet          Set-PackageSource                            PackageManagement

Instead of modifying all the calls to the listed cmdlets, you can simply tell PowerShell to add a parameter to the required cmdlets using $PSDefaultParameterValues:

PS> $Proxy = ''
PS> $PSDefaultParameterValues = @{
    'Invoke-WebRequest:Proxy' = $Proxy
    'Invoke-RestMethod:Proxy' = $Proxy

If you are already using $PSDefaultParameterValues please add new entries to the hash:

PS> $Proxy = ''
PS> $PSDefaultParameterValues.Add('Invoke-WebRequest:Proxy', $Proxy)
PS> $PSDefaultParameterValues.Add('Invoke-RestMethod:Proxy', $Proxy)

I recommend you do not add a proxy to all cmdlets using $PSDefaultParameterValues.Add('*:Proxy', '') because a cmdlet can have such a parameter with a different meaning.

When using $PSDefaultParameterValues all calls to the specified cmdlets will receive the additional parameter as long as they are in the same session and unless they explicitly override the value.

Feedback is always welcome! If you'd like to get in touch with me concerning the contents of this article, please use Twitter.