Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Proxy parameters for commands that use Invoke-WebRequest or Invoke-RestMethod #396

Open
FISHMANPET opened this issue Oct 12, 2021 · 3 comments
Assignees
Labels
enhancement New feature or request

Comments

@FISHMANPET
Copy link

I'm in a situation where I'd like to be able to request a certificate for a system that requires a proxy to communicate with the outside world (including our certificate vendor). If I logon to a system and set the "Internet Options" to use our proxy server (which I believe Invoke-WebRequest and Invoke-RestMethod use) then I'm able to successfully install a certificate. While those Invoke commands will accept Proxy parameters, there's no way (that I can see) to pass those to the commands when they're used inside the module.

I can see a couple of ways to accomplish this (and I'd be more than happy to work on implementing them or any other suggestions, since I'm asking for it after all 😁)
First option, add a -Proxy, -ProxyCredential, and -ProxyUseDefaultCredentials to every command that will eventually result in an Invoke-Rest/Web call, to be used to pass to those commands when needed.
Second Option, use something similar to $env:POSHACME_HOME and set a script variable in Import-PAConfig that will be added to every Invoke command, the same way $script:UseBasic is added to every command currently.

I'm also open to working on a different implementation suggestion if you have any, or some way to accomplish this without having to modify the module itself.

@rmbolger
Copy link
Owner

Hi again, @FISHMANPET. Please forgive my ignorance here as I have very little experience dealing with environments that require using a proxy server. I was under the impression that the web cmdlets would already use the system-defined proxy settings if they exist. Though I seem to recall different versions of PowerShell or maybe just different versions of .NET having differing levels of support for that.

I found an MS Docs article relating to using the Azure PowerShell module behind a proxy that suggests using the standard HTTP_PROXY and HTTPS_PROXY environment variables depending on your PowerShell version.

https://docs.microsoft.com/en-us/powershell/azure/az-powershell-proxy

Would this potentially work for you?

If for whatever reason we need to explicitly provide the Proxy parameters to the internal web calls, we can probably make it work via environment variables for base module functions. But every single plugin that makes web calls will need to be modified to support them as well. But at that point, it probably makes sense to create a wrapper functions the plugins can call instead. But that has cascading effects for some folks who are using the plugins as standalone scripts outside the module. So I'm really hoping we can figure something out that doesn't involve explicitly using the Proxy* parameters on Invoke-WebRequest and Invoke-RestMethod.

@FISHMANPET
Copy link
Author

Right now I'm using PS 5.1 on Windows, so the advice there is to "use the system proxy". Also, I believe the AZ Powershell module is actually using .Net calls directly under the hood rather than the Invoke- commands, so the behavior may be different.

What I've been able to determine by experimenting is that if you set the "system" proxy (netsh winhttp set proxy ...) the Invoke commands won't use that. If you set it in Internet Options (either via the Control Panel or Internet Explorer options) the Invoke- commands will use those settings, for the user that defined them. Unfortunately, setting the user proxy programmatically is kind of a bear requiring byte math to write values into the registry. I've also tried using $PSDefaultParameterValues but it looks like those aren't honored inside the module's scope (probably a good design decision on PowerShell's part, even if it's making this more difficult for me).

I also agree that it would be a huge amount of work for what is probably a very small use case (seeing as how it's never come up until now). Maybe it's best for now to just put this on the "backlog" until other people ask for it. I think now that I've found that StackOverflow post on setting the registry values, even though it's complex it appears to be well defined and ultimately doable, I can go down that path myself without needing to make changes to the module.

@rmbolger
Copy link
Owner

$PSDefaultParameterValues is an interesting idea when combined with the environment variable option. I'm not sure if the scoping would work particularly for the plugins, but I can imagine something like the environment variables being checked during module load and then configuring $PSDefaultParameterValues in the module scope based on the results. Then theoretically nothing else in the module needs to explicitly call the web cmdlets with those parameters?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants