Powershell v3 Invoke-WebRequest HTTPS error


126

Menggunakan Invoke-WebRequest dan Invoke-RestMethod Powershell v3 saya telah berhasil menggunakan metode POST untuk mengirim file json ke situs web https.

Perintah yang saya gunakan adalah

 $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

Namun ketika saya mencoba menggunakan metode GET seperti:

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

Kesalahan berikut dikembalikan

 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

Saya telah mencoba menggunakan kode berikut untuk mengabaikan sertifikat SSL, tetapi saya tidak yakin apakah itu benar-benar melakukan sesuatu.

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

Dapatkah seseorang memberikan panduan tentang apa yang mungkin salah di sini dan bagaimana cara memperbaikinya?

Terima kasih


Jadi yang mana yang kamu gunakan? Invoke-RestMethodatau Invoke-WebRequest?
svick

Invoke-WebRequest. Saya menggunakannya karena mengembalikan header request / resposne tidak seperti Invoke-RestMethod. Namun saya telah mencoba Invoke-RestMethod yang mengambil parameter identik juga.
floyd

Untuk apa nilainya, hal ServerValidationCallback hampir pasti herring, karena kesalahan yang harus Anda dapatkan ketika Anda memiliki masalah validasi SSL harus MENGATAKAN bahwa: Invoke-WebRequest : The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. Anda dapat mencoba menjelajahi $ Error [0] .Exception.InnerException untuk informasi lebih lanjut .. .
Jaykul

Jawaban:


179

Solusi ini berhasil untuk saya: http://connect.microsoft.com/PowerShell/feedback/details/419466/new-webserviceproxy-needs-force-parameter-to-ignore-ssl-errors

Pada dasarnya, dalam skrip PowerShell Anda:

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
Perhatikan, jawaban ini benar; namun, poin yang dibuat pada jawaban lain ( stackoverflow.com/a/25163476/68432 ) juga valid. Solusi ini tidak akan berfungsi jika Anda telah melakukan "[System.Net.ServicePointManager] :: ServerCertificateValidationCallback = {$ true}" sebelumnya.
Paul Suart

Anda perlu menambahkan pemeriksaan kondisi Jenis sesuai jawaban Arthur Strutzenberg di bawah ini atau Anda akan mendapatkan pesan kesalahan yang mengatakan bahwa jenis tersebut sudah ada
Ralph Willgoss

Apakah ada risiko keamanan untuk menggunakan ini dalam produksi?
Amjad

13
5 tahun kemudian, itu masih menjadi solusi untuk PowerShell 5.1 (full .NET Framework). Untuk PowerShell Core -SkipCertificateChecksekarang ada.
evilSnobu

MS telah menghapus Connect, link itu tidak valid. Apakah ada tautan lain?
Mark Heath

71

Jawaban Lee bagus, tetapi saya juga memiliki masalah dengan protokol mana yang didukung server web.
Setelah juga menambahkan baris berikut, saya bisa mendapatkan permintaan https melalui. Seperti yang ditunjukkan dalam jawaban ini https://stackoverflow.com/a/36266735

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

Solusi lengkap saya dengan kode 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

Sudahkah Anda menemukan solusi yang lebih baik, karena jika Anda memiliki 40 skrip maka Anda harus menambahkannya ke masing-masing ?. Sepertinya tidak masuk akal. Btw, terima kasih atas jawabannya
Ender

1
Jawaban Lee tidak berhasil untukku. Saya harus menambahkan bit yang Anda rujuk dan BERHASIL!
Pat K

Terima kasih banyak, menentukan protokol membantu memecahkan masalah
Alex

1
Terima kasih, terima kasih, terima kasih telah menunjukkan SecurityProtocolproperti statis global. Astaga, saya baru saja kehilangan HARI untuk memeriksa sertifikat, kepercayaan, jaringan, rute, izin, dan banyak hal lain yang mencoba menyelesaikan endpoint does not respondkesalahan yang tidak jelas saat mengakses satu server tertentu melalui https (semua yang lain berfungsi), hanya karena PowerShell 5.1 default untuk SSL3, TLS dan hANYA BLOK sialan TLS11 dan TLS12 BY dEFAULT Tuhan betapa aku benci omong kosong ini seharusnya aku menulis bahwa script di C # / Ruby / C ++, atau apapun yang lain yang tidak PowerShell
Quetzalcoatl

1
@StanTastic: Saya pikir tidak mungkin mengubah default secara permanen. Saya pikir itu hardcode dalam kode sumber ServicePointManager. Saya tidak pernah memeriksanya, jadi mungkin ada beberapa cara.
quetzalcoatl

10

Apakah Anda mencoba menggunakan 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)

Cerah, saya menerima hal berikut saat menggunakan kode itu: Pengecualian memanggil "DownloadString" dengan argumen "1": "Server jarak jauh mengembalikan kesalahan: (406) Tidak Dapat Diterima." Pada baris: 4 karakter: 1 + $ wc.DownloadString ($ url) + ~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo: NotSpecified: (:) [ ], MethodInvocationException + FullyQualifiedErrorId: WebException
floyd

Berdasarkan dokumentasi API dari layanan REST im using 406 menunjukkan "bahwa header penerimaan yang disertakan dalam permintaan tidak mengizinkan respons XML atau JSON"
floyd

Jenis tanggapan apa yang diizinkan jika tanggapan XML / JSON tidak diizinkan?
Cerah Chakraborty

Apakah ini layanan web khusus yang Anda gunakan? Apakah ada dokumentasi yang tersedia untuk umum untuk REST API?
Cerah Chakraborty

Ini adalah sistem tiket yang disebut EM7. Saya tidak percaya mereka memiliki dokumen publik. Layanan menerima tanggapan JSON / XML (bekerja dengan baik jika saya menggunakan cURL) Saya yakin kesalahan menunjukkan bahwa System.Net.WebClient isnt?
floyd

10

Implementasi alternatif secara murni (tanpa Add-Typedari sumber):

#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

Hal berikut berfungsi untuk saya (dan menggunakan cara terbaru yang tidak digunakan lagi untuk berinteraksi dengan fungsi SSL Certs / callback), dan tidak mencoba memuat kode yang sama beberapa kali dalam sesi PowerShell yang sama:

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

Ini diadaptasi dari artikel berikut https://d-fens.ch/2013/12/20/nobrainer-ssl-connection-error-when-using-powershell/


5

Saya menemukan bahwa ketika saya menggunakan fungsi panggilan balik ini untuk mengabaikan sertifikat SSL [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

Saya selalu mendapat pesan kesalahan Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send.yang terdengar seperti hasil yang Anda dapatkan .

Saya menemukan posting forum ini yang membawa saya ke fungsi di bawah ini. Saya menjalankan ini sekali di dalam lingkup kode saya yang lain dan berfungsi untuk saya.

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

Saya mencoba mencari dokumentasi di EM7 OpenSource REST API. Tidak beruntung sejauh ini.

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

Ada banyak pembicaraan tentang OpenSource REST API, tetapi tidak ada tautan ke API aktual atau dokumentasi apa pun. Mungkin saya tidak sabar.

Berikut beberapa hal yang bisa Anda coba

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

Coba ini untuk melihat apakah Anda dapat memfilter kolom yang Anda peroleh dari API

$a.Results | ft

atau, Anda juga dapat mencoba menggunakan ini

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

Header Gaya Curl

$b.Headers

Saya menguji IRM / IWR dengan api JSON twitter.

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

Semoga ini membantu.


Terima kasih atas semua bantuannya. Namun perintah pertama $ a = Invoke-RestMethod (...) adalah perintah yang saat ini tidak berfungsi untuk saya. Berfungsi dengan baik untuk situs HTTP tetapi ketika Anda memperkenalkan HTTPS yang dilakukan EM7, ia mengembalikan kesalahan yang dijelaskan. Itu untuk Invoke-RestMethod dan Invoke-WebRequest. Saya sedang dalam proses hanya menggunakan cmdlet Perintah-Perintah dan menjalankan curl.
floyd

1

Invoke-WebRequest "DomainName" -SkipCertificateCheck

Anda dapat menggunakan -SkipCertificateCheck Parameter untuk mencapai ini sebagai perintah satu baris (PARAMETER INI HANYA DIDUKUNG PADA PSEDISI UTAMA)


0
  1. Jalankan perintah ini

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

di PowerShell menggunakan hak admin , Ini akan menghasilkan semua sertifikat di direktori Pribadi

  1. Untuk menghilangkan kesalahan Privasi, pilih sertifikat ini, klik kanan → Salin. Dan tempel di Otoritas / Sertifikat Sertifikasi Root Terpercaya.
  2. Langkah terakhir adalah memilih binding yang benar di IIS. Buka situs web IIS, pilih Bindings, Pilih kotak centang SNI dan setel sertifikat individu untuk setiap situs web.

Pastikan nama host situs web dan nama-dns sertifikat harus sama persis


0

Pengaturan registri ini mempengaruhi .NET Framework 4+ dan oleh karena itu PowerShell. Atur dan mulai ulang sesi PowerShell untuk menggunakan TLS terbaru, tidak perlu reboot.

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 

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


Bagi siapa pun yang melihat jawaban ini, pengalaman kami adalah bahwa tambalan registri ini sebenarnya memerlukan boot ulang untuk menjamin fungsionalitas yang tepat. Saat mencoba memastikan koneksi TLS 1.2 antara kotak Windows yang menjalankan aplikasi .NET, SSL 3 ditampilkan melalui jejak jaringan untuk digunakan dengan nilai registri ini di tempatnya, tetapi sebelum reboot; TLS 1.2 dipanggil hanya setelah reboot.
David W

-1

Jika Anda menjalankan ini sebagai administrator, kesalahan itu akan hilang

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.