As a corporate customer, I would like CVRF downloads to occur via Proxy
Within a corporate environment, where servers are restricted from accessing the internet, the cmdlets should have "out-of-the-box" support for specifying Proxy settings.

Text-based Error
PS C:\> Get-MsrcCvrfDocument -ID $monthOfInterest -ApiKey $msrcApiKey -Verbose
VERBOSE: Calling https://api.msrc.microsoft.com/cvrf/2017-Apr?api-version=2016-08-01
VERBOSE: GET https://api.msrc.microsoft.com/cvrf/2017-Apr?api-version=2016-08-01 with 0-byte payload
Get-MsrcCvrfDocument : HTTP Get failed with status code ProxyAuthenticationRequired: Proxy Authentication Required
At line:1 char:1
+ Get-MsrcCvrfDocument -ID $monthOfInterest -ApiKey $msrcApiKey -Verbose
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-MsrcCvrfDocument
:shipit:
Good suggestion, Xeleema. The commands in this module are really just wrappers over Invoke-RestMethod (https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.utility/invoke-restmethod) which has parameters to support using a Proxy.
As a workaround, you could do this:
Import-Module MsrcSecurityUpdates
Set-MSRCApiKey -ApiKey Foo
### Get a CVRF document using Proxy Credentials
$apiUrl = "$msrcApiUrl/cvrf/2017-Apr?$msrcApiVersion"
Invoke-RestMethod -Method Get -Uri $apiUrl -Headers @{
'Api-Key' = $global:MSRCApiKey
'Accept' = 'application/json'
} -Proxy http://myProxy -ProxyCredential (Get-Credential -Message 'Please enter the creds for the proxy' -UserName MyProxyUserName)
### Get security Updates using Proxy Credentials
$apiUrl = "$msrcApiUrl/updates?$msrcApiVersion"
Invoke-RestMethod -Method Get -Uri $apiUrl -Headers @{
'Api-Key' = $global:MSRCApiKey
'Accept' = 'application/json'
} -Proxy http://myProxy -ProxyCredential (Get-Credential -Message 'Please enter the creds for the proxy' -UserName MyProxyUserName) |
Select-Object -ExpandProperty Value```
You could also set the proxy as devault values like this:
$PSDefaultParameterValues += @{'*:ProxyUseDefaultCredentials'=$true;'*:Proxy'='http://proxy:port'}
That's a great workaround, thanks for the suggestion! Given that the workaround exists, I don't think we should plumb the parameters through to the Get-Msrc* commands.
Fixed by @NicholasBn in #10
~~Work-around mentioned by vrdse doesn't work in my case.~~ However it may be something in the 1.6.4 version of the module. The private function Get-CVRFID works when called directly, however when called by Get-MsrccvrfDocument, Get-CVRFID throws "Cannot retrieve the dynamic parameters for the cmdlet. Unable to get online the list of CVRF ID".
Digging into $Error shows Invoke-RestMethod caught an "Access Denied (authentication_failed)" from the proxy. So something isn't quite right with $PSDefaultParameterValues (or $global:PSDefaultParameterValues, even when specifying 'Invoke-RestMethod instead of '*').
I'll grab 1.6.6 and give that a shot. :)
Edit: $PSDefaultParameterValues suggestion works, then things trip and stumble when Get-MsrccvrfDocument calls Get-CVRFID.
Moved comment to Issue #9
Have you tried using Set-MSRCApiKey with the Proxy and ProxyCredential parameters?
Set-MSRCApiKey -ApiKey foo -Proxy http://myProxy -ProxyCredential (Get-Credential)
@craig-martin Yes, I tried the new parameters. Works as good as or as bad as setting $PSDefaultParameterValues. In both cases I have the issue #9. Not 100% sure if it's proxy related though.
Thanks for the extra detail. Can you try using Invoke-RestMethod on its own? This module is basically a wrapper over that command so I'd like to confirm that it works.
Here is a sample command line without proxy details:
Invoke-RestMethod -Uri https://api.msrc.microsoft.com/cvrf/2016-Sep?api-Version=2016 -Headers @{'Api-Key'='YOUR KEY GOES HERE';Accept='application/json'}
Here is a sample command line with proxy details:
Invoke-RestMethod -Uri https://api.msrc.microsoft.com/cvrf/2016-Sep?api-Version=2016 -Headers @{'Api-Key'='YOUR KEY GOES HERE';Accept='application/json'} -Proxy http://YourProxyServer -ProxyCredential (Get-Credential)
@craig-martin When I execute the following, I can get through our internal proxy and obtain data from the RESTful API;
# $MyAPIKey= ## redacted for post
# $MyProxyAndPort= ## redacted for post
$PSDefaultParameterValues += @{'Invoke-RestMethod:ProxyUseDefaultCredentials'=$true}
Invoke-RestMethod -Uri https://api.msrc.microsoft.com/cvrf/2016-Sep?api-Version=2016 -Headers @{'Api-Key'=$MyAPIKey;Accept='application/json'} -Proxy $MyProxyAndPort
When I dot-source and call Get-CVRFID directly, I'm able to get data through our proxy;
. C:\CVRF\MsrcSecurityUpdates\Private\Get-CVRFID.ps1
Get-CVRFID -ID "2017-May"
However, I catch an error when running ; Get-MsrcCvrfDocument -ID "2017-May" -Verbose
##
## TEST BLOCK (Base) - C:\CVRF\MsrcSecurityUpdates
##
$PSDefaultParameterValues += @{'Invoke-RestMethod:ProxyUseDefaultCredentials'=$true}
Import-Module C:\CVRF\MsrcSecurityUpdates
# $MyAPIKey = ## redacted for post
# $MyProxyAndPort = ## redacted for post
Set-MSRCApiKey -ApiKey $MyAPIKey -Proxy $MyProxyAndPort
Get-MsrcCvrfDocument -ID "2017-May" -Verbose
##
## TEST BLOCK base (end)
##
The run of Invoke-RestMethod (called from Get-CVRFID) is getting Access Denied because it assumes that if $Proxy is specificed, that $ProxyCredentials (rather than $DefaultCredentials) will be used.
Every call to Invoke-RestMethod is affected.
NOTE: However, this was as it stood on May 11th with version 1.6.7. I'll upgrade to PowerShell v5.0 and grab the latest *.zip file blob.
Update: Since there doesn't appear to be an applicable code-change since May 11th, I've dug deeper and discovered the following;
Within \MsrcSecurityUpdates\Private\Get-CVRFID.ps1
Regarding the if-statement for $global:msrcProxyCredential (Lines 21 thru 23)
Remove this;
if ($global:msrcProxyCredential){
$RestMethod.Add('ProxyCredential',$global:msrcProxyCredential)
}
Then incorporate it into the if-statement for $global:msrcProxy ;
if ($global:msrcProxy){
$RestMethod.Add('Proxy' , $global:msrcProxy)
if ($global:msrcProxyCredential){
$RestMethod.Add('ProxyCredential',$global:msrcProxyCredential)
} else {
$RestMethod.Add('ProxyUseDefaultCredentials',$true)
}
}
Note the "if no msrcproxyCredential then set ProxyUseDefaultCredentials to $true".
My test-block now results in the following output;
PS C:\CG\HFS>
PS C:\CG\HFS> cd \
PS C:\> $error.clear()
PS C:\> ##
PS C:\> ## TEST BLOCK (Base) - C:\CVRF\MsrcSecurityUpdates
PS C:\> ##
PS C:\>
PS C:\> $PSDefaultParameterValues += @{'Invoke-RestMethod:ProxyUseDefaultCredentials'=$true}
PS C:\> Import-Module C:\CVRF\MsrcSecurityUpdates
PS C:\>
PS C:\> Set-MSRCApiKey -ApiKey $MyAPIKey -Proxy $MyProxyAndPort
PS C:\>
PS C:\> Get-MsrcCvrfDocument -ID "2017-May" -Verbose
VERBOSE: Calling https://api.msrc.microsoft.com/cvrf/2017-May?api-version=2016-08-01
VERBOSE: GET https://api.msrc.microsoft.com/cvrf/2017-May?api-version=2016-08-01 with 0-byte payload
VERBOSE: received 1298134-byte response of content type application/json; charset=utf-8
DocumentTitle : @{Value=May 2017 Security Updates}
DocumentType : @{Value=Security Update}
DocumentPublisher : @{ContactDetails=; IssuingAuthority=; Type=0}
DocumentTracking : (lots of good stuff)
DocumentNotes : (even more good stuff)
ProductTree : (good stuff)
Vulnerability : (good stuff)
PS C:\>
PS C:\> ##
PS C:\> ## TEST BLOCK base (end)
PS C:\> ##
PS C:\>
We have run into the same issue at our corporation. We need to access this data via proxy (MiM) that is required for our govt customer base.