Powershell v3 Invoke-WebRequest HTTPSエラー


126

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}

誰かがここで何が問題になっているのか、そしてそれをどのように修正するのかについてのガイダンスを提供できますか?

ありがとう


どちらを使用していますか?Invoke-RestMethodまたはInvoke-WebRequest
12

Invoke-WebRequest。Invoke-RestMethodとは異なり、要求/応答ヘッダーを返すため、これを使用します。ただし、同じパラメーターを取るInvoke-RestMethodも試しました。
フロイド

価値があることについては、ServerValidationCallbackはほぼ間違いなく赤いニシンです。SSL検証の問題が発生したときに発生するエラーは、次のように説明されているInvoke-WebRequest : The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. ためです。詳細については、$ Error [0] .Exception.InnerExceptionを調べてみてください。 。
Jaykul

回答:


179

この回避策は私にとってうまくいきました: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"

9
この答えは正しいことに注意してください。ただし、別の回答(stackoverflow.com/a/25163476/68432)で行われたポイントも有効です。このソリューションは、事前に「[System.Net.ServicePointManager] :: ServerCertificateValidationCallback = {$ true}」を実行している場合は機能しません。
Paul Suart

以下のArthur Strutzenbergの回答に従ってタイプ条件チェックを追加する必要があります。そうしないと、タイプがすでに存在しているというエラーが表示されます
Ralph Willgoss

これを本番環境で使用することにはセキュリティ上のリスクがありますか
Amjad 2018年

13
5年後、それはPowerShell 5.1(完全な.NET Framework)のソリューションです。PowerShell Coreには-SkipCertificateCheck今があります。
evilSnobu

MSはConnectを削除しました、そのリンクは無効です。別のリンクはありますか?
マークヒース

71

Leeの答えは素晴らしいですが、Webサーバーがサポートするプロトコルにも問題がありました。
次の行も追加した後、httpsリクエストを通過させることができました。この回答で指摘されているようにhttps://stackoverflow.com/a/36266735

$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols

リーのコードによる私の完全な解決策。

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

あなたはより良い解決策を見つけましたか、40スクリプトがあるなら、あなたはそれをそれぞれに追加する必要がありますか?意味をなさないようです。ところで、答えをありがとう
エンダー

1
リーの答えは私にはうまくいきませんでした。私はあなたが参照したビットを追加しなければならず、IT WORKED!
Pat K

問題を解決するのに役立つプロトコルを指定していただき、ありがとうございました
Alex

1
SecurityProtocolグローバル静的プロパティを表示していただき、ありがとうございます。キリスト、私は証明書、信頼、ネットワーク、ルート、アクセス許可、およびendpoint does not respondhttpsを介して特定のサーバーにアクセスするときのあいまいなエラーを解決しようとする他のもののチェックロード(他のすべては機能する)で数日間を失いましたSSL3、TLSのデフォルトとそれJUST BLOCKS田舎者の白人野郎TLS11とTLS12 BYのデフォルト私はこのがらくたを憎むどれだけ神様は私が書かれているべきであるPowerShellのではないのC#/ルビー/ C ++、または任意の他でスクリプト
ケツァルコアトル

1
@StanTastic:デフォルトを永続的に変更することは不可能だと思います。ServicePointManagerソースコードにハードコーディングされていると思います。私はチェックしたことがないので、たぶんいくつかの方法があります。
ケツァルコアトル2018年

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)

晴れ、そのコードを使用すると次のメッセージが表示されます。「1」の引数を使用して「DownloadString」を呼び出す例外:「リモートサーバーがエラーを返しました:(406)受け入れられません。」行:4 char:1 + $ wc.DownloadString($ url)+ ~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo:NotSpecified:(:) [ ]、MethodInvocationException + FullyQualifiedErrorId:WebException
floyd

406を使用したRESTサービスのAPIドキュメントに基づいて、imは「リクエストに含まれるAcceptヘッダーがXMLまたはJSON応答を許可しないこと」を示しています
floyd

XML / JSON応答が許可されていない場合、どの応答タイプが許可されますか?
サニーチャクラボルティ

これは、使用しているカスタムWebサービスですか?REST APIの公開されているドキュメントはありますか?
サニーチャクラボルティ

それはEM7と呼ばれる発券システムです。彼らが公開ドキュメントを持っているとは思いません。サービスはJSON / XML応答を受け入れます(cURLを使用する場合は問題なく動作します)エラーはSystem.Net.WebClientが存在しないことを示していると思いますか?
フロイド

9

純粋な代替実装 (なし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()

7

以下は私のために働き(そして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();

これは、以下の記事 https://d-fens.ch/2013/12/20/nobrainer-ssl-connection-error-when-using-powershell/


5

このコールバック関数を使用してSSL証明書を無視すると、 [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

私はいつもInvoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send.あなたが持っている結果のように聞こえるエラーメッセージを受け取りました。

以下の機能に私を導くこのフォーラムの投稿を見つけました。これを他のコードのスコープ内で1回実行すると、問題なく機能します。

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
}


1

EM7 OpenSource REST APIのドキュメントを検索してみました。これまでのところ運がありません。

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

オープンソース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

IRM / IWRをTwitter JSON APIでテストしました。

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

お役に立てれば。


ご協力ありがとうございます。ただし、最初のコマンド$ a = Invoke-RestMethod(...)は、現在のところ機能しません。HTTPサイトでは正常に機能しますが、EM7が実行するHTTPSを導入すると、説明されているエラーが返されます。これは、Invoke-RestMethodおよびInvoke-WebRequestの場合です。Invoke-Commandコマンドレットを使用してcurlを実行しているところです。
フロイド2012

1

Invoke-WebRequest "DomainName" -SkipCertificateCheck

-SkipCertificateCheckパラメーターを使用して、これを1行のコマンドとして実現できます(このパラメーターはコアPSEDITIONでのみサポートされています)


0
  1. このコマンドを実行する

New-SelfSignedCertificate -certstorelocation cert:\ localmachine \ my -dnsname {your-site-hostname}

PowerShellで管理者権限を使用して、すべての証明書を個人ディレクトリに生成します

  1. プライバシーエラーを取り除くには、これらの証明書を選択し、右クリック→[コピー]をクリックします。そして、信頼されたルート証明機関/証明書に貼り付けます。
  2. 最後のステップは、IISで正しいバインディングを選択することです。IIS Webサイトに移動し、[バインディング]、[SNIの選択]チェックボックスを選択して、各Webサイトに個別の証明書を設定します。

ウェブサイトのホスト名と証明書のDNS名が完全に一致していることを確認してください


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を参照してください


この答えを見た人にとって、私たちの経験では、このレジストリパッチは実際には適切な機能を保証するために再起動を必要とします。.NETアプリを実行しているWindowsボックス間のTLS 1.2接続を確認しようとすると、SSL 3がネットワークトレースを介して表示され、このレジストリ値を使用して再起動する前に使用されました。TLS 1.2は、再起動後にのみ呼び出されました。
デビッドW

-1

これを管理者として実行すると、そのエラーはなくなるはずです

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.