1
votes

I have been using a script that has been working for a year without issue, making a call to Invoke-RestMethod to a secure (https) site, which is now failing. After a much testing I found that I can make the call fail consistently and reproducible for any secure site request but I don't know why. The following code fails.

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
Invoke-RestMethod -Uri https://blogs.msdn.com/powershell/rss.aspx | Format-Table -Property Title, pubDate

The error produced is the following:

Invoke-RestMethod : The underlying connection was closed: An unexpected error occurred on a send. At line:1 char:1 + Invoke-RestMethod -Uri https://blogs.msdn.com/powershell/rss.aspx | Format-Table ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

I found that if I include

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

the above line, I get the previously shown error. The above behavior and error is actually the opposite of what should occur. Previously, I could not make the https request without assigning the ServerCertificateValidationCallback to be true.

I have tried this from multiple computers, under different Windows user profiles, launching PowerShell using administrative privileges but I find adding the above line enables me to reproduce the problem. In order to make it work, I must close PowerShell, reopen it and remove the ServerCertificateValidationCallback line. If I add the line to the code, the error returns.

The last time I ran my code was two weeks ago, so that is as narrowly as I can pinpoint the timeframe. Any ideas on why this is now failing?

Note this is not the site I was originally having a problem with however, the issue I am facing can be reproduced with the above code.

1

1 Answers

0
votes

Check out the solution here on the Huddled Masses blog.

Based on that I started using these:

function Disable-SslVerification
{
    if (-not ([System.Management.Automation.PSTypeName]"TrustEverything").Type)
    {
        Add-Type -TypeDefinition  @"
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
public static class TrustEverything
{
    private static bool ValidationCallback(object sender, X509Certificate certificate, X509Chain chain,
        SslPolicyErrors sslPolicyErrors) { return true; }
    public static void SetCallback() { System.Net.ServicePointManager.ServerCertificateValidationCallback = ValidationCallback; }
    public static void UnsetCallback() { System.Net.ServicePointManager.ServerCertificateValidationCallback = null; }
}
"@
    }
    [TrustEverything]::SetCallback()
}
function Enable-SslVerification
{
    if (([System.Management.Automation.PSTypeName]"TrustEverything").Type)
    {
        [TrustEverything]::UnsetCallback()
    }
}

The bad news is that based on an update, I'm back on StackOverflow because that stopped working this week sometime...

If you are using an older version of Powershell you might still be good with the code I've posted.