If your computer is on a corporate network behind a proxy server, by default you won’t be able to access external web resources from your PowerShell CLI. For example, you won’t be able to get the content of an external web page using the Invoke-WebRequest cmdlet, update help using the Update-Help, connect to Azure/Microsoft 365 tenant (Exchange Online PowerShell module), install modules from PSGallery, or RSAT capabilities, download an application package from an external package repository (using WinGet package manager). In this article, we’ll show you how to configure PowerShell to access the Web through a proxy server with authentication.
Let’s try to update the PowerShell Help on a computer behind a corporate proxy server:
Update-Help
Or refer to an external web page:
Invoke-WebRequest https://woshub.com
If your computer can only access the Web through a proxy and not through a direct connection, the command will return an error:
Update-help : Failed to update Help for the module(s) ‘DhcpServer, DirectAccessClientComponents….’ with UI culture(s) {en-US} : Unable to connect to Help content. The server on which Help content is stored might not be available. Verify that the server is available, or wait until the server is back online, and then try the command again.
Invoke-WebRequest: Unable to connect to the remote server. InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest).
Find-Module modulename
Unable to resolve package source 'https://www.powershellgallery.com/api/v2'
The fact is that Powershell (or rather, the .NET class System.Net.WebClient, which these cmdlets used to access external resources over HTTP/HTTPS) does not use the proxy server settings specified in the user settings. Let’s take a look at how to configure proxy server settings and perform authentication from the PowerShell console.
Set WinHTTP Proxy Server Settings for PowerShell
Check the current system proxy setting from PowerShell:
netsh winhttp show proxy
As you can see, proxy settings are not specified:
Current WinHTTP proxy settings: Direct access (no proxy server).
You can import proxy server configurations from Windows settings (Internet Explorer):
netsh winhttp import proxy source=ie
or set them manually:
netsh winhttp set proxy "192.168.0.14:3128"
You can specify a list of IP addresses or site names that you don’t need to use a proxy server to connect to (bypass list):
netsh winhttp set proxy "192.168.1.100:3128" bypass-list= "10.*,172.*,192.168.*,*.corp.woshub.com"
You can check if the connection to a specific URL is through a proxy or not: ([System.Net.WebRequest]::GetSystemWebproxy()).IsBypassed("https://woshub.com")
If the command returns False
, the connection to this URL will be made through the proxy configured in your PowerShell session.
If the proxy server requires authentication, an error like “(407) Proxy Authentication Required” will appear when you try to run PowerShell commands. For example, when trying to connect to your Azure tenant using the AzureAD module:
Connect-AzureAD
An error occurs:
The remote server returned an error: (407) Proxy Authentication Required.
Next, let’s look at how to authenticate to a proxy server from PowerShell.
Proxy Authentication with PowerShell
Let’s look at two ways to authenticate to a proxy server: you can use Windows SSO authentication or specify user credentials for authentication manually.
If you are authorized on your computer under a domain account, and your proxy server supports Active Directory Kerberos, or NTLM authentication (if you have not disabled it yet), then you can use the current user credentials to authenticate on the proxy server (you do not need to re-enter your username and password):
$Wcl = new-object System.Net.WebClient
$Wcl.Headers.Add(“user-agent”, “PowerShell Script”)
$Wcl.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
If you need to manually authenticate on the proxy server manually, run the following commands and specify the username and password in the Windows Security credential request window.
$Wcl=New-Object System.Net.WebClient
$Creds=Get-Credential
$Wcl.Proxy.Credentials=$Creds
Now you can try to access an external website or update the help with the Update-Help
command.
Or, if you have configured a proxy connection in a PowerShell session, the command should return the external IP address of your proxy server:
(Invoke-WebRequest -uri "http://ifconfig.me/ip").Content
As you can see, the Invoke-Web Request cmdlet returned data from the external site webpage!
Invoke-WebRequest https://woshub.com -ProxyUseDefaultCredentials -Proxy http://192.168.1.100:3128
Or you can request user credentials interactively:
$ProxyCreds = Get-Credential
Invoke-WebRequest https://woshub.com -Proxy "http://192.168.1.100:3128" -ProxyCredential $ProxyCreds
The above method allows you to configure proxy server settings and authenticate in classic Windows PowerShell 5.1 (How to check the PowerShell version installed?).
Configuring Proxy Connections for PowerShell Core
In new versions of PowerShell Core (6.x, 7.x), the System.Net.HttpClient class is used instead of the System.Net.WebRequest class to perform web requests in the Invoke-WebRequest, Find-Module, Install-Module, etc. cmdlets.
Accordingly, to set proxy server settings in PowerShell Core, you need to use the command:
[System.Net.Http.HttpClient]::DefaultProxy = New-Object System.Net.WebProxy('http://your-proxy:3128')
To authenticate on the proxy under the current Windows user:
[System.Net.Http.HttpClient]::DefaultProxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
To interactively request user credentials for proxy authentication:
[System.Net.Http.HttpClient]::DefaultProxy.Credentials = Get-Credential
PowerShell Core also supports special Windows environment variables you can use to enable proxy settings:
- HTTP_PROXY – proxy for HTTP requests
- HTTPS_PROXY — proxy for HTTPS requests
- ALL_PROXY – proxy for both HTTP and HTTPS
- NO_PROXY – proxy exclusion address list
You can set environment variables with the following PowerShell commands:
$proxy='http://192.168.1.100:8080'
$ENV:HTTP_PROXY=$proxy
$ENV:HTTPS_PROXY=$proxy
$proxy='http://username:password@IP:PORT'
Check that the proxy environment variables are set:
Dir env:
In PowerShell Core on Linux, you can export system proxy settings from environment variables using:
export HTTP_PROXY=http://192.168.1.100:3128
export HTTPS_PROXY=http://192.168.1.100:3128
Apply Proxy Server Settings with PowerShell Profile File
You can create a PowerShell profile file to automatically import proxy settings when PowerShell starts.
To do this, run the command that will create the PowerShell profile file (C:\Users\username\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1):
notepad $PROFILE
(or notepad $PROFILE.AllUsersCurrentHost
–if you need to apply a PowerShell profile to all users of the computer).
Copy your PowerShell code into the notepad window. For example, you are using the Proxy Auto-Configuration (PAC) files to automatically configure proxy server settings on user computers. You can specify the URL address of the PAC file and authenticate on the proxy server under the current user with the following PowerShell profile script.
# Force PowerShell to use TLS 1.2 for connections
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
[system.net.webrequest]::DefaultWebProxy = new-object system.net.webproxy('http://10.1.15.5:80')
# If you need to import proxy settings from Internet Explorer, you can replace the previous line with the: "netsh winhttp import proxy source=ie"
[system.net.webrequest]::DefaultWebProxy.credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
# You can request user credentials:
# System.Net.WebRequest]::DefaultWebProxy.Credentials = Get-Credential
# Also, you can get the user password from a saved XML file (see the article “Using saved credentials in PowerShell scripts”):
# System.Net.WebRequest]::DefaultWebProxy= Import-Clixml -Path C:\PS\user_creds.xml
[system.net.webrequest]::DefaultWebProxy.BypassProxyOnLocal = $true
Set-ExecutionPolicy RemoteSigned
Save the Microsoft.PowerShell_profile.ps1 file and restart the PowerShell console. Now, when you open a new PowerShell session, the code in the profile file is executed and the proxy settings are imported into your session.
Show Current Proxy Server Settings with PowerShell
You can get the current proxy settings in Windows from the registry with the PowerShell command:
Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' | Select-Object ProxyServer, ProxyEnable
In my example, the address and port of the proxy server are: 192.168.1.100:3128
Proxy server enabled: ProxyEnable =1
You can also get WebProxy settings like this:
[System.Net.WebProxy]::GetDefaultProxy()
If necessary, you can enable the use of proxy with the following command:
Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyEnable -value 1
To disable proxy:
Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' ProxyEnable -value 0
How to Change Proxy Settings in Windows with PowerShell?
You can set proxy settings using PowerShell. For example, the following PowerShell function allows you to change proxy settings, but first, it checks the availability of the proxy server and the port response on it using the Test-NetConnection cmdlet
function Set-Proxy ( $server,$port)
{
If ((Test-NetConnection -ComputerName $server -Port $port).TcpTestSucceeded) {
Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' -name ProxyServer -Value "$($server):$($port)"
Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' -name ProxyEnable -Value 1
}
Else {
Write-Error -Message "Invalid proxy server address or port: $($server):$($port)"
}
}
Set-Proxy 192.168.1.100 3128
You can add additional addresses to the proxy exclusion list:
$ProxyExceptionList = ";*.woshub.com;*.contoso.com"
$ProxyProperty = Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
If ($ProxyProperty.ProxyOverride) {
$OldValue = $ProxyProperty.ProxyOverride
$NewValue = $OldValue+$ProxyExceptionList
$ProxyProperty | Set-ItemProperty -Name ProxyOverride -Value $NewValue
} else {
Write-Warning "List of proxy overrides is empty!"
}
Additionally, you can save the login and password for authentication on the proxy server in the registry:
Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' -name ProxyUser -Value "proxy_username"
Set-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' -name ProxyPass -Value "proxy_password"
Note that older builds of Windows 10, Windows Server 2016, and older versions of Windows use the outdated and insecure TLS 1.0 protocol by default for PowerShell connections. This is why you may get the following error when trying to search for a module in PSGallery:
WARNING: Unable to resolve package source 'https://www.powershellgallery.com/api/v2'.
To use TLS 1.2 in PowerShell connections to endpoints, run the command
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12