Powershell v3 Invoke-WebRequest HTTPS错误

时间:2012-07-27 23:39:41

标签: .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

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

 Invoke-WebRequest -Uri https://IPADDRESS/resource -Credential $cred -certificate $cert -Method GET

返回以下错误

 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

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

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

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

由于

11 个答案:

答案 0 :(得分:147)

这种解决方法对我有用: 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"

答案 1 :(得分:53)

李的答案很棒,但我也遇到了网络服务器支持哪些协议的问题 在添加以下行之后,我可以通过https请求。正如本回答https://stackoverflow.com/a/36266735

所指出的那样
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols

我使用Lee代码的完整解决方案。

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

答案 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)

答案 3 :(得分:6)

以下工作对我有用(并使用最新的非弃用方法与SSL Certs /回调功能进行交互),并且不会尝试在同一个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();

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

答案 4 :(得分:5)

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

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

我发现这个forum post引导我进入下面的功能。我在其他代码的范围内运行一次,它对我有用。

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
}

答案 5 :(得分:4)

调用WebRequest“域名” -SkipCertificateCheck

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

答案 6 :(得分:1)

我尝试在EM7 OpenSource REST API上搜索文档。到目前为止没有运气。

http://blog.sciencelogic.com/sciencelogic-em7-the-next-generation/05/2011

有很多关于OpenSource REST API的讨论,但没有指向实际API或任何文档的链接。 也许我很不耐烦。

以下是您可以试用的一些内容

$a = Invoke-RestMethod -Uri https://IPADDRESS/resource -Credential $cred -certificate $cert 
$a.Results | ConvertFrom-Json

尝试此操作,看看您是否可以过滤掉从API获取的列

$a.Results | ft

或者,您也可以尝试使用它

$b = Invoke-WebRequest -Uri https://IPADDRESS/resource -Credential $cred -certificate $cert 
$b.Content | ConvertFrom-Json

卷曲样式标题

$b.Headers

我使用twitter JSON api测试了IRM / IWR。

$a = Invoke-RestMethod http://search.twitter.com/search.json?q=PowerShell 

希望这有帮助。

答案 7 :(得分:0)

  1. 运行此命令
  2. New-SelfSignedCertificate -certstorelocation cert:\ localmachine \ my -dnsname {your-site-hostname}

    使用管理员权限在powershell中

    ,这将生成个人目录

    中的所有证书
    1. 要摆脱隐私错误,请选择这些证书,右键单击→复制。并粘贴在受信任的根证书颁发机构/证书中。
    2. 最后一步是在IIS中选择正确的绑定。转到IIS网站,选择Bindings,选择SNI复选框并为每个网站设置单独的证书。
    3. 确保网站主机名和证书dns-name完全匹配

答案 8 :(得分:0)

如果您以管理员身份运行,则该错误应该消失

答案 9 :(得分:0)

这些注册表设置影响.NET Framework 4+,从而影响PowerShell。设置它们并重新启动所有PowerShell会话以使用最新的TLS,无需重新启动。

Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord 

请参见https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls#schusestrongcrypto

答案 10 :(得分:0)

中的另一种实现(没有源的Add-Type):

#requires -Version 5

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()