Inside System.Net.HttpWebRequest webproxy

  • Context:

I’ve logged on interactively with an administrative user A in a corporate environment, defined the proxy in Internet Explorer using the GUI, browsed the web, logged off and connected with user B, put the laptop into hibernation, brought the laptop at home, made a session reconnect with user B and finally launched a powershell console running as user A (as he has administrative credential on the laptop).

  • Problem:

Whenever I try to use the Invoke-Webrequest or Invoke-RestMethod, it ends with the following error: “Invoke-WebRequest : The proxy name could not be resolved:” invoke-webrequest error 01

  • Debugging steps:

So I’ve had a look at the stack trace that contains the most recent error but I got no clue:

$StackTrace

invoke-webrequest stacktrace 01

Trying to make the system fail to understand what’s going on is sometimes useful while troubleshooting.
I’ve tried to set a null proxy to override the corporate proxy adress that seems to be picked up automatically from somewhere:

Invoke-WebRequest "http://www.google.com" -Proxy [system.URI]''

I got the following:
invoke-webrequest error 02

I’ve looked at the new $PSDefaultParameterValues variable in powershell 3 and checked that a proxy parameter wasn’t defined.
I’ve then tried to define a null proxy for the Invoke-WebRequest cmdlet

$PSDefaultParameterValues += @{"Invoke-WebRequest:Proxy"=[system.URI]''}

Now when I do:

Invoke-WebRequest "http://www.google.com"

I’ve still got the same error as above: “Invoke-WebRequest : This operation is not supported for a relative URI.”

Great, this shows that I’ve been able to override the default user defined proxy but wasn’t able to set the proxy settings to none.
So I removed the default proxy setting I’ve set:

$PSDefaultParameterValues.Remove("Invoke-WebRequest:Proxy")

Then the following method on the system.net.webproxy .net object shows me the corporate proxy being defined

[system.net.webproxy]::GetDefaultProxy()

But it doesn’t have any method to reset it to ‘none’

[system.net.webproxy] | gm -MemberType Method -Static

Note also that it’s deprecated.

Having a look to the suggested .net object system.net.webrequest confirms that:

The DefaultWebProxy property reads proxy settings from the app.config file.
If there is no config file, the current user’s Internet Explorer (IE) proxy settings are used.

To make sure there isn’t any app.config file., I quickly did

Get-ChildItem $env:systemdrive\app.config -Recurse

I finally remembered the context and when I’ve read first line of the following article I came up with the solution.

$BinaryArray = (Get-ItemProperty 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections').DefaultConnectionSettings            

-join ($BinaryArray | % { [char][int]"$_"})            

Remove-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections' -Name DefaultConnectionSettings

VoilĂ , now the following works:

Invoke-WebRequest -Uri "http://www.google.com"
  • Lessons learned
    • Powershell 3 automatically uses the proxy defined in the current user profile unless there’s a machine level (ProxySettingsPerUser) defined that tells not to.
    • I haven’t found a way to override this setting by providing an explicit proxy parameter set to ‘none’. If anyone knows how to do it, pls let us know.
    • The new default parameter $PSDefaultParameterValues is interesting and should be tested systematically while troubleshooting or using cmdlets w/o parameters inside scripts
    Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s