首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Powershell 3.0 Invoke-WebRequest HTTPS在所有请求上都失败

Powershell 3.0 Invoke-WebRequest HTTPS在所有请求上都失败
EN

Stack Overflow用户
提问于 2014-08-06 00:31:55
回答 5查看 35.6K关注 0票数 15

我正在尝试通过Powershell 3.0和REST API来使用我们的负载均衡器。然而,无论我如何尝试,无论是对我们的负载均衡器还是对任何其他https站点,我都会收到一个失败的请求。我觉得我漏掉了一些明显的东西。

以下是使用https时失败的代码

代码语言:javascript
运行
复制
try
{
    #fails
    #$location='https://www.bing.com'
    #fails
    #$location='https://www.google.com'
    #fails
    #$location='https://www.facebook.com'
    #fails
    #$location='https://www.ebay.com'
    #works
    #$location='http://www.bing.com'
    #works
    #$location='http://www.google.com'
    #fails (looks like Facebook does a redirect to https://)
    $location='http://www.facebook.com'
    #works
    #$location='http://www.ebay.com'
    $response=''
    $response = Invoke-WebRequest -URI $location
    $response.StatusCode
    $response.Headers
}
catch
{
    Write-Host StatusCode $response.StatusCode
    Write-Host $_.Exception
}

我得到的错误是:

代码语言:javascript
运行
复制
System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.Management.Automation.PSInvalidOperationException: 
There is no Runspace available to run scripts in this thread. You can provide one in the DefaultRunspace property of the System.Management.Automation.Runspaces.Runspa
ce type. The script block you attempted to invoke was: $true
   at System.Net.TlsStream.EndWrite(IAsyncResult asyncResult)
   at System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar)
   --- End of inner exception stack trace ---
   at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.GetResponse(WebRequest request)
   at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.ProcessRecord()

我希望this page和底部的建议,包括Aaron。)会有所不同,但它们都不会有什么不同。

代码语言:javascript
运行
复制
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

代码语言:javascript
运行
复制
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
}

代码语言:javascript
运行
复制
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

我尝试切换到Invoke-RestCommand,但没有用,因为我得到了相同的响应。

我觉得这必须是一些环境上的东西,因为我不敢相信上面的方法不适用于其他任何人,但我已经在工作站和服务器上尝试过了,结果是相同的(不完全排除环境,但我知道它们的设置是不同的)。

有什么想法吗?

EN

回答 5

Stack Overflow用户

发布于 2016-09-28 09:34:14

这对我来说非常有效。该网站默认使用TLS1.0,显然PS不能与之兼容。我使用了这行代码:

代码语言:javascript
运行
复制
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

我的PS脚本(到目前为止我测试过的所有脚本)都工作得很好。

票数 33
EN

Stack Overflow用户

发布于 2014-08-06 22:47:11

答案是不要这样做来解决SSL问题:

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

如果你这样做了,你的第一个https请求将会工作(看起来是这样),但是随后的请求将不会。此外,此时您需要关闭Powershell ISE,然后重新打开它,然后重试(不使用该线路)。

这在http://social.technet.microsoft.com/Forums/windowsserver/en-US/79958c6e-4763-4bd7-8b23-2c8dc5457131/sample-code-required-for-invokerestmethod-using-https-and-basic-authorisation?forum=winserverpowershell的一句话中提到了-“所有后续的运行都会产生这个错误:",但不清楚重置的解决方案是什么。

票数 20
EN

Stack Overflow用户

发布于 2016-03-11 05:23:31

我也被这个困扰了很长一段时间。当VS在运行NuGet恢复时将我的$PROFILE加载到它的域中时,它甚至影响了Visual Studio。

看到你上面的评论,我意识到我有一个自定义的回调脚本,因为我们的一个供应商在它的ssl证书中提供了一个带有无效CN的产品。

长话短说,我用一个编译的c#对象替换了我的脚本委托(从等式中删除了脚本运行空间)。

(用于C#突出显示的单独代码块)

代码语言:javascript
运行
复制
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

public static class CustomCertificateValidationCallback {
    public static void Install() 
    {
        ServicePointManager.ServerCertificateValidationCallback += CustomCertificateValidationCallback.CheckValidationResult;
    }

    public static bool CheckValidationResult(
        object sender, 
        X509Certificate certificate, 
        X509Chain chain, 
        SslPolicyErrors sslPolicyErrors)
    {
        // please don't do this. do some real validation with explicit exceptions.
        return true;
    }
}

在Powershell中:

代码语言:javascript
运行
复制
Add-Type "" # C# Code
[CustomCertificateValidationCallback]::Install()
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25143946

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档