Powershell Invoke-RestMethod over HTTPS

心不动则不痛 提交于 2019-12-03 10:30:08

I solved the mystery while troubleshooting another thing. The web server in question only supported TLS1.1 and TLS1.2. Powershell does NOT seem to support that. If I enabled TLS1.0 it worked.

To force TLS1.2 you can use this line:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

Hope that helps someone else and thanks for all helpful comments!

/Patrik

It appears you're trying to invoke a json API with Invoke-RestMethod. According to the documentation:

-ContentType

Specifies the content type of the web request.

If this parameter is omitted and the request method is POST, Invoke-RestMethod sets the content type to "application/x-www-form-urlencoded". Otherwise, the content type is not specified in the call.

To use a json body, you will need to use Invoke-RestMethod -ContentType 'application/json' <other args>

I went through a lot of pain recently in order to get past a similar situation. I was creating a proof of concept using a trial SaaS service. The service had a self-signed SSL certificate so I wanted to ignore certificate errors while attempting to invoke a POST method to it (similar to the "-k" parameter for curl). After much struggle, I found that it needed both - (a) the call to ignore cert validation errors and (b) an explicit setting for TLS 1.2 as the security protocol. I think the latter because the service was perhaps declining attempts to connect using any of the other protocols. (I spent too much time trying the different variations for doing each as suggested on various SOF threads but independently...)

Here's the code that worked...

Important: The cert validation bypass is purely for the prototype/PoC. We do not intent to do this in production (and you shouldn't either!).

$defaultSecurityProtocol = $null
try
{   
    #BUGBUG, TODO: Disabling cert validation for the duration of this call...('trial' version cert is self-signed.)
    #Remove this after the PoC.
    [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true } 
    #Cache the previous protocol setting and explicitly require TLS 1.2 
    $defaultSecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol
    [System.Net.ServicePointManager]::SecurityProtocol = `
                [System.Net.SecurityProtocolType]::Tls12

    if (-not [String]::IsNullOrWhiteSpace($authZHeaderValue))
    {
        $response = Invoke-WebRequest `
                    -Uri $webhookUrl `
                    -Method "Post" `
                    -Body $eventJson `
                    -Header @{ $authZHeaderName = $authZHeaderValue} 
    }
    else 
    {
        $response = Invoke-WebRequest `
                    -Uri $webhookUrl `
                    -Method "Post" `
                    -Body $eventJson
    }
}
catch 
{
    $msg = $_.Exception.Message
    $status = $_.Exception.Status
    $hr = "{0:x8}" -f ($_.Exception.HResult)
    $innerException = $_.Exception.InnerException
    #Just issue a warning about being unable to send the notification...
    Write-Warning("`n`t[$status] `n`t[0x$hr] `n`t[$msg] `n`t[$innerException]")
}
finally 
{
    # Set securityProtocol and CertValidation behavior back to the previous state.
    [System.Net.ServicePointManager]::SecurityProtocol = $defaultSecurityProtocol
        [System.Net.ServicePointManager]::ServerCertificateValidationCallback = $null
}

Also want to add that the preferred security protocols keep changing as various vulnerabilities are discovered and fixes implemented. Moreover, different systems (SSL/TLS stacks in client OSes and servers/services) often have their own catching up to do with the latest/most secure options. Thus exactly which flag might work will be a function of the client and server systems and also of time (in that TLS1.2 might not remain preferred a few months later). Ideally one shouldn't need to specify a flag at all. Please see the "Remarks" section in this MSDN document for more.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!