Powershell v3 Invoke-WebRequest HTTPS hatası


126

Powershell v3'ün Invoke-WebRequest ve Invoke-RestMethod'u kullanarak bir https web sitesine bir json dosyası göndermek için POST yöntemini başarıyla kullandım.

Kullandığım komut

 $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

Ancak GET yöntemini şu şekilde kullanmaya çalıştığımda:

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

Aşağıdaki hata döndürülür

 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 sertifikasını yok saymak için aşağıdaki kodu kullanmaya çalıştım, ancak gerçekten bir şey yapıp yapmadığından emin değilim.

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

Birisi burada neyin yanlış gidebileceği ve nasıl düzeltileceği konusunda rehberlik edebilir mi?

Teşekkürler


Peki hangisini kullanıyorsun? Invoke-RestMethodveya Invoke-WebRequest?
svick

Invoke WebRequest. Invoke-RestMethod'un aksine istek / yanıt başlıklarını döndürdüğü için kullanıyorum. Bununla birlikte, aynı parametreleri de alan Invoke-RestMethod'u denedim.
floyd

Ne olursa olsun, ServerValidationCallback olayı neredeyse kesinlikle bir kırmızı ringa balığıdır, çünkü bir SSL doğrulama probleminiz olduğunda almanız gereken hata şunu söyleyin: Invoke-WebRequest : The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. Daha fazla bilgi için $ Error [0] .Exception.InnerException'ı keşfetmeyi deneyebilirsiniz .. .
Jaykul

Yanıtlar:


179

Bu geçici çözüm benim için çalıştı: http://connect.microsoft.com/PowerShell/feedback/details/419466/new-webserviceproxy-needs-force-parameter-to-ignore-ssl-errors

Temel olarak, PowerShell betiğinizde:

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
Bu cevabın doğru olduğunu unutmayın; ancak başka bir cevapta ( stackoverflow.com/a/25163476/68432 ) belirtilen nokta da geçerlidir. Önceden "[System.Net.ServicePointManager] :: ServerCertificateValidationCallback = {$ true}" yaptıysanız bu çözüm işe yaramayacaktır.
Paul Suart

Aşağıdaki Arthur Strutzenberg cevabına göre Tür koşulu kontrolünü eklemeniz gerekir, yoksa türün zaten mevcut olduğunu söyleyen bir hata alırsınız
Ralph Willgoss

Bunu üretimde kullanmanın bir güvenlik riski var mı?
Amjad

13
5 yıl sonra, PowerShell 5.1 (tam .NET Framework) için hala çözüm budur. PowerShell Core için bir -SkipCertificateCheckşimdi var.
evilSnobu

MS Connect'i kapattı, bu bağlantı geçersiz. Başka bir bağlantı var mı?
Mark Heath

71

Lee'nin cevabı harika, ancak web sunucusunun hangi protokolleri desteklediğiyle ilgili sorunlarım da vardı.
Aşağıdaki satırları da ekledikten sonra https talebini de alabilirim. Bu cevapta belirtildiği gibi https://stackoverflow.com/a/36266735

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

Lee'nin koduyla tam çözümüm.

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

Daha iyi bir çözüm buldunuz mu, çünkü 40 komut dosyanız varsa, her birine eklemeniz gerekir mi? Hiç mantıklı değil gibi görünüyor. Btw, cevabın için teşekkürler
Ender

1
Lee'nin cevabı benim için işe yaramadı. Referans verdiğiniz bitleri eklemek zorunda kaldım ve ÇALIŞTI!
Pat K

Çok teşekkür ederim, protokolleri belirtmek sorunu çözmeye yardımcı oldu
Alex

1
Bana SecurityProtocolküresel statik özelliği gösterdiğiniz için teşekkür ederim . Tanrım, endpoint does not respondhttps aracılığıyla belirli bir sunucuya erişirken (diğerleri işe yarıyor), sertifikaları, güvenleri, ağı, yolları, izinleri ve diğer şeylerin boktan şeylerini kontrol etmede DAYS kaybettim , çünkü o lanet olası powershell 5.1 varsayılan olarak SSL3, TLS'dir ve SADECE GODDAMN TLS11 ve TLS12'yi VARSAYILANLARA GÖRE BLOKLAR tanrı tarafından bu boktan ne kadar nefret ediyorum, bu betiği C # / Ruby / C ++ veya powershell olmayan başka bir şeyle
yazmalıydım

1
@StanTastic: Varsayılanları kalıcı olarak değiştirmenin imkansız olduğunu düşünüyorum. ServicePointManager kaynak kodunda kodlanmış olduğunu düşünüyorum. Yine de hiç kontrol etmedim, belki bir yolu vardır.
quetzalcoatl

10

Kullanmayı denedin System.Net.WebClientmi

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

Sunny, bu kodu kullanırken şunu alıyorum: "1" bağımsız değişkenle "DownloadString" çağırma özel durumu: "Uzak sunucu bir hata döndürdü: (406) Kabul Edilemez." Satırda: 4 karakter: 1 + $ wc.DownloadString ($ url) + ~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo: NotSpecified: (:) [ ], MethodInvocationException + FullyQualifiedErrorId: WebException
floyd

406'yı kullanan REST hizmetinin API belgelerine göre, "istekte bulunan kabul başlığının XML veya JSON yanıtına izin vermediğini" belirtir
floyd

XML / JSON yanıtlarına izin verilmiyorsa hangi yanıt türlerine izin verilir?
Sunny Chakraborty

Bu, kullandığınız özel bir web hizmeti mi? REST API için herkese açık herhangi bir belge var mı?
Sunny Chakraborty

EM7 adında bir bilet sistemidir. Herkese açık dokümanları olduğuna inanmıyorum. Hizmet JSON / XML yanıtını kabul etmiyor (cURL kullanırsam gayet iyi çalışıyor) Hatanın System.Net.WebClient olmadığını gösterdiğine inanıyorum?
floyd

10

Saf olarak alternatif bir uygulama (olmadan Add-Type arasında kaynak):

#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

Aşağıdakiler benim için çalıştı (ve SSL Sertifikaları / geri arama işlevselliği ile etkileşimde bulunmak için en son kullanımdan kaldırılmamış araçları kullanır) ve aynı kodu aynı powershell oturumu içinde birden çok kez yüklemeye çalışmaz:

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

Bu, aşağıdaki makaleden uyarlanmıştır: https://d-fens.ch/2013/12/20/nobrainer-ssl-connection-error-when-using-powershell/


5

SSL sertifikalarını yok saymak için bu geri arama işlevini kullandığımda [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

Her zaman aldığınız Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send.sonuçlara benzeyen hata mesajını aldım .

Beni aşağıdaki işleve götüren bu forum gönderisini buldum . Bunu diğer kodumun kapsamı içinde bir kez çalıştırıyorum ve benim için çalışıyor.

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
}


2

Invoke-WebRequest "EtkiAlanıAdı" -SkipCertificateCheck

Bunu tek satırlık bir komut olarak elde etmek için -SkipCertificateCheck Parametresini kullanabilirsiniz (BU PARAMETRE YALNIZCA CORE PSEDITION ÜZERİNDE DESTEKLENMEKTEDİR)


1

EM7 OpenSource REST API ile ilgili belgeleri aramayı denedim. Şimdiye kadar şans yok.

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

OpenSource REST API hakkında çok fazla konuşma var, ancak gerçek API veya herhangi bir belgeye bağlantı yok. Belki sabırsızdım.

İşte deneyebileceğiniz birkaç şey

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

API'den aldığınız sütunları filtreleyip atamayacağınızı görmek için bunu deneyin

$a.Results | ft

veya bunu da deneyebilirsiniz

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

Curl Stili Başlıkları

$b.Headers

IRM / IWR'yi twitter JSON api ile test ettim.

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

Bu yardımcı olur umarım.


Tüm yardımlarınız için teşekkür ederim. Ancak ilk komut $ a = Invoke-RestMethod (...) şu anda benim için çalışmayan komuttur. Bir HTTP sitesi için iyi çalışıyor ancak HTTPS'yi tanıttığınızda hangi EM7 açıklanan hatayı döndürüyor. Bu, Invoke-RestMethod ve Invoke-WebRequest içindir. Sadece bir Invoke-Command cmdlet'i kullanma ve curl çalıştırma sürecindeyim.
floyd

0
  1. Bu komutu çalıştırın

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

powershell'de yönetici haklarını kullanarak , Bu Kişisel dizindeki tüm sertifikaları oluşturacak

  1. Gizlilik hatasından kurtulmak için bu sertifikaları seçin, → Kopyala'ya sağ tıklayın. Ve Güvenilir Kök Sertifika Yetkilisi / Sertifikaları'na yapıştırın.
  2. Son adım, IIS'de doğru bağlamaları seçmektir. IIS web sitesine gidin, Bağlantıları seçin, SNI Seç onay kutusunu seçin ve her web sitesi için ayrı sertifikalar ayarlayın.

Web sitesi ana makine adının ve sertifika dns-adının tam olarak eşleştiğinden emin olun


0

Bu kayıt defteri ayarları, .NET Framework 4+ ve dolayısıyla PowerShell'i etkiler. Bunları ayarlayın ve herhangi bir PowerShell oturumunu en son TLS'yi kullanacak şekilde yeniden başlatın, yeniden başlatma gerekmez.

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 

Bkz. Https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls#schusestrongcrypto


Bu yanıtı gören başka herhangi biri için, deneyimlerimiz, bu kayıt defteri yamasının aslında düzgün işlevselliği garanti etmek için yeniden başlatma gerektirdiğidir. .NET uygulaması çalıştıran bir Windows kutusu arasında TLS 1.2 bağlantısı sağlamaya çalışırken, SSL 3, bu kayıt defteri değeriyle birlikte kullanılmak üzere ağ izleme aracılığıyla, ancak yeniden başlatmadan önce gösterildi; TLS 1.2, yalnızca yeniden başlatmanın ardından çağrıldı.
David W

-1

Bunu yönetici olarak çalıştırırsanız, bu hata ortadan kalkar

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.