Powershell v3 Invoke-WebRequest HTTPS错误

flo*_*oyd 113 .net rest powershell https

使用Powershell v3的Invoke-WebRequest和Invoke-RestMethod我已成功使用POST方法将json文件发布到https网站.

我正在使用的命令是

 $cert=New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("cert.crt")
 Invoke-WebRequest -Uri https://IPADDRESS/resource -Credential $cred -certificate $cert -Body $json -ContentType application/json -Method POST
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用GET方法时:

 Invoke-WebRequest -Uri https://IPADDRESS/resource -Credential $cred -certificate $cert -Method GET
Run Code Online (Sandbox Code Playgroud)

返回以下错误

 Invoke-RestMethod : The underlying connection was closed: An unexpected error occurred on a send.
 At line:8 char:11
 + $output = Invoke-RestMethod -Uri https://IPADDRESS/resource -Credential $cred
 +           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest)      [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
Run Code Online (Sandbox Code Playgroud)

我曾尝试使用以下代码来忽略SSL证书,但我不确定它是否真的在做任何事情.

 [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
Run Code Online (Sandbox Code Playgroud)

有人可以提供一些指导,说明这里可能出现的问题以及解决方法吗?

谢谢

Lee*_*som 161

这个解决方案对我有用:http: //connect.microsoft.com/PowerShell/feedback/details/419466/new-webserviceproxy-needs-force-parameter-to-ignore-ssl-errors

基本上,在PowerShell脚本中:

add-type @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
        }
    }
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

$result = Invoke-WebRequest -Uri "https://IpAddress/resource"
Run Code Online (Sandbox Code Playgroud)

  • 注意,这个答案是正确的; 但是,另一个答案(http://stackoverflow.com/a/25163476/68432)上提出的观点也是有效的.如果您事先已完成"[System.Net.ServicePointManager] :: ServerCertificateValidationCallback = {$ true}",则此解决方案将无效. (8认同)
  • 5年后,这仍然是PowerShell 5.1(完整的.NET Framework)的解决方案.对于PowerShell Core,现在有一个`-SkipCertificateCheck`. (7认同)

And*_*dOs 63

Lee的答案很棒,但我也遇到了Web服务器支持哪些协议的问题.
在添加以下行之后,我可以通过https请求.正如在这个答案/sf/answers/2538671481/中指出的那样

$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
Run Code Online (Sandbox Code Playgroud)

我的完整解决方案与李的代码.

add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
    public bool CheckValidationResult(
        ServicePoint srvPoint, X509Certificate certificate,
        WebRequest request, int certificateProblem) {
        return true;
    }
}
"@
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
Run Code Online (Sandbox Code Playgroud)

  • 李的回答对我不起作用。我必须添加您引用的部分并且它起作用了! (2认同)
  • 谢谢谢谢谢谢你向我展示了 `SecurityProtocol` 全局静态属性。基督,我刚刚失去了天的检验证书,信托,网络,路由,权限和其他东西shitload试图解决含糊`端点访问通过HTTPS一个特定的服务器时(所有其他做工作)不respond`错误,只是因为那个该死的 powershell 5.1 默认为 SSL3,TLS 并且它只是 **BLOCKS** 该死的 TLS11 和 TLS12 **BY DEFAULT** 上帝我多么讨厌这个废话我应该用 C#/Ruby/C++ 编写那个脚本,或者任何其他不是 powershell 的东西 (2认同)

小智 10

你尝试过使用过System.Net.WebClient吗?

$url = 'https://IPADDRESS/resource'
$wc = New-Object System.Net.WebClient
$wc.Credentials = New-Object System.Net.NetworkCredential("username","password")
$wc.DownloadString($url)
Run Code Online (Sandbox Code Playgroud)


小智 7

Invoke-WebRequest "DomainName" -SkipCertificateCheck

您可以使用-SkipCertificateCheck参数将其作为单行命令来实现(此参数仅支持核心 PSEDITION)


小智 6

以下代码对我有用(并使用了最新的,不建议使用的方法与SSL证书/回调功能进行交互),并且没有尝试在同一powershell会话中多次加载相同的代码:

if (-not ([System.Management.Automation.PSTypeName]'ServerCertificateValidationCallback').Type)
{
$certCallback=@"
    using System;
    using System.Net;
    using System.Net.Security;
    using System.Security.Cryptography.X509Certificates;
    public class ServerCertificateValidationCallback
    {
        public static void Ignore()
        {
            if(ServicePointManager.ServerCertificateValidationCallback ==null)
            {
                ServicePointManager.ServerCertificateValidationCallback += 
                    delegate
                    (
                        Object obj, 
                        X509Certificate certificate, 
                        X509Chain chain, 
                        SslPolicyErrors errors
                    )
                    {
                        return true;
                    };
            }
        }
    }
"@
    Add-Type $certCallback
 }
[ServerCertificateValidationCallback]::Ignore();
Run Code Online (Sandbox Code Playgroud)

改编自以下文章 https://d-fens.ch/2013/12/20/nobrainer-ssl-connection-error-when-using-powershell/


Aar*_*n D 5

我发现当我使用这个回调函数忽略SSL证书时 [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

我总是收到错误消息Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send.,听起来就像你的结果.

我发现这个论坛帖子引导我进入下面的功能.我在其他代码的范围内运行一次,它对我有用.

function Ignore-SSLCertificates
{
    $Provider = New-Object Microsoft.CSharp.CSharpCodeProvider
    $Compiler = $Provider.CreateCompiler()
    $Params = New-Object System.CodeDom.Compiler.CompilerParameters
    $Params.GenerateExecutable = $false
    $Params.GenerateInMemory = $true
    $Params.IncludeDebugInformation = $false
    $Params.ReferencedAssemblies.Add("System.DLL") > $null
    $TASource=@'
        namespace Local.ToolkitExtensions.Net.CertificatePolicy
        {
            public class TrustAll : System.Net.ICertificatePolicy
            {
                public bool CheckValidationResult(System.Net.ServicePoint sp,System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Net.WebRequest req, int problem)
                {
                    return true;
                }
            }
        }
'@ 
    $TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource)
    $TAAssembly=$TAResults.CompiledAssembly
    ## We create an instance of TrustAll and attach it to the ServicePointManager
    $TrustAll = $TAAssembly.CreateInstance("Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll")
    [System.Net.ServicePointManager]::CertificatePolicy = $TrustAll
}


The*_*le1 5

在纯替代实现(没有Add-Type源):

#requires -Version 5
#requires -PSEdition Desktop

class TrustAllCertsPolicy : System.Net.ICertificatePolicy {
    [bool] CheckValidationResult([System.Net.ServicePoint] $a,
                                 [System.Security.Cryptography.X509Certificates.X509Certificate] $b,
                                 [System.Net.WebRequest] $c,
                                 [int] $d) {
        return $true
    }
}
[System.Net.ServicePointManager]::CertificatePolicy = [TrustAllCertsPolicy]::new()
Run Code Online (Sandbox Code Playgroud)