Invoke-WebRequest: PowerShell ile HTTP İstekleri Gerçekleştirin, Dosyaları İndirin, Web'i Ayrıştırın


Invoke-WebRequest cmdlet'i, HTTP/HTTPS/FTP kaynaklarını doğrudan PowerShell konsolundan istemek için kullanılabilir. Bu komutu HTTP istekleri (GET ve POST) göndermek, bir web sitesinden dosya indirmek, HTML web sayfalarını ayrıştırmak, kimlik doğrulama gerçekleştirmek, web formlarını doldurup göndermek vb. için kullanabilirsiniz. Bu makalede, kullanımın temel örneklerini ele alacağız. Web hizmetleriyle etkileşime geçmek için PowerShell'deki Invoke-WebRequest cmdlet'i.

Invoke-WebRequest Cmdlet ile Web Sayfası İçeriğini Alın

Invoke-WebRequest cmdlet'i, GET yöntemiyle HTTP, HTTPS veya FTP isteğini belirtilen web sayfasına göndermenizi ve sunucudan bir yanıt almanızı sağlar. Bu cmdlet, Windows'ta PowerShell 3.0 sürümünden beri mevcuttur.

Windows'ta Invoke-WebRequest komutu için iki takma ad vardır:

iwk

Ve

wget

Aşağıdaki komutu çalıştırın:

Invoke-WebRequest -Uri "https://a-d.site"

İpucu. İnternete bir proxy sunucusu aracılığıyla bağlıysanız, proxy sunucusu aracılığıyla Web'e erişmek için PowerShell'i uygun şekilde yapılandırmanız gerekir. Proxy parametrelerini ayarlamazsanız, IWK komutunu çalıştırdığınızda bir hata alırsınız:

Invoke-WebRequest:  Unable to connect to the remote server
CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

Komut, sayfayı yükledi ve içeriğini PowerShell konsolunda görüntüledi. Döndürülen yanıt, yalnızca sayfanın HTML kodu değildir. Invoke-WebRequest cmdlet'i, HtmlWebResponseObject türünde bir nesne döndürür. Böyle bir nesne, bir HTML belgesinin formlar, bağlantılar, resimler ve diğer önemli öğelerin bir koleksiyonudur. Bu nesnenin tüm özelliklerine bakalım:

$WebResponseObj = Invoke-WebRequest -Uri "https://a-d.site"
$WebResponseObj| Get-Member

HtmlWebResponseObject nesnesinde bulunan web sayfasının ham HTML kodunu almak için şunu çalıştırın:

$WebResponseObj.content

Web sunucusu tarafından döndürülen HTTP başlıkları ile birlikte HTML kodunu listeleyebilirsiniz:

$WebResponseObj.rawcontent

Yalnızca web sunucusu HTTP durum kodunu ve HTML sayfasının HTTP başlıklarını kontrol edebilirsiniz:

$WebResponseObj.Headers

Gördüğünüz gibi, sunucu bir 200 yanıtı döndürdü. Bu, isteğin başarılı olduğu ve web sunucusunun uygun olduğu ve düzgün çalıştığı anlamına gelir.

Key               Value
---               -----
Transfer-Encoding chunked
Connection        keep-alive
Vary              Accept-Encoding,Cookie
Cache-Control     max-age=3, must-revalidate
Content-Type      text/html; charset=UTF-8
Date              Wed, 13 Jul 2022 02:28:32 GMT
Server            nginx/1.20.2
X-Powered-By      PHP/5.6.40

Bir web sayfasının son değişiklik zamanını almak için:

$WebResponseObj.ParsedHtml | Select lastModified

Bir web kaynağına bağlanırken bir Kullanıcı Aracısı dizesi belirtebilirsiniz. PowerShell'de bir dizi yerleşik Kullanıcı Aracısı dizesi vardır:

invoke-webRequest -Uri $uri -userAgent ([Microsoft.PowerShell.Commands.PSUserAgent]::Chrome)

PowerShell'deki kullanılabilir aracıların listesi şu şekilde görüntülenebilir:

[Microsoft.PowerShell.Commands.PSUserAgent].GetProperties() | Select-Object Name, @{n='UserAgent';e={ [Microsoft.PowerShell.Commands.PSUserAgent]::$($_.Name) }}

Veya kendi UserAgent dizginizi ayarlayabilirsiniz:

Invoke-WebRequest -Uri $uri -UserAgent 'MyApplication/1.1'

Invoke-WebRequest'i Kimlik Doğrulaması ile Kullanma

Bazı web kaynaklarına erişmek için kimlik doğrulaması gerekir. Invoke-WebRequest cmdlet'iyle (Temel, NTLM, Kerberos, OAuth veya sertifika kimlik doğrulaması) çeşitli kimlik doğrulama türleri kullanabilirsiniz.

Temel Kimlik Doğrulamayı gerçekleştirmek için (base64'te kodlanmış ad ve parola ile kimlik doğrulama), önce kullanıcı adını ve parolayı almanız gerekir:

$cred = Get-Credential
wget -Uri 'https://somesite.com' -Credential $cred

Geçerli Windows kullanıcı kimlik bilgilerini NTLM veya Kerberos kimlik doğrulaması gerçekleştirmek üzere kullanmak için -UseDefaultCredentials seçeneğini ekleyin:

Invoke-WebRequest 'https://somesite.com' -UseDefaultCredentials

DefaultCredentials, Temel kimlik doğrulamasıyla çalışmıyor.

Bir sertifikayla kimlik doğrulaması yapmak için parmak izini belirtmeniz gerekir:

Invoke-WebRequest 'https://somesite.com' -CertificateThumbprint xxxxxxxxxxxxxxxxxxxxxxxxxxxxx

PowerShell komut dosyalarınızda modern Taşıyıcı/OAuth belirteci kimlik doğrulamasını kullanabilirsiniz.

  1. Öncelikle, REST API sağlayıcınızdan bir OAuth belirteci almanız gerekir (bu yazının kapsamı dışındadır);

  2. Simgeyi ConvertTo-SecureString cmdlet'i ile dönüştürün:

    $Token = "12345678912345678901234567890" | ConvertTo-SecureString -AsPlainText -Force
  3. Artık OAuth kimlik doğrulaması gerçekleştirebilirsiniz:

    $Params = @{
    Uri = "https://somesite.com"
    Authentication = "Bearer"
    Token = $Token }
    Invoke-RestMethod @Params

HTML'yi PowerShell ile Web Sayfasını Ayrıştırın ve Kazıyın

Invoke-WebRequest cmdlet'i, herhangi bir web sayfasının içeriğini hızlı ve kolay bir şekilde ayrıştırmanıza olanak tanır. Bir HTML sayfasını işlerken, bağlantı koleksiyonları, web formları, resimler, komut dosyaları vb. oluşturulur.

Bir web sayfasındaki belirli nesnelere nasıl erişileceğine bakalım. Örneğin, hedef HTML web sayfasındaki tüm giden bağlantıların (A HREF nesneleri) bir listesini almak istiyorum:

$SiteAdress = "https://a-d.site"
$HttpContent = Invoke-WebRequest -URI $SiteAdress
$HttpContent.Links | Foreach {$_.href }

Bağlantı metninin kendisini (InnerText öğesinde bulunan) almak için aşağıdaki komutu kullanabilirsiniz:

$HttpContent.Links | fl innerText, href

Yalnızca belirli bir CSS sınıfına sahip bağlantıları seçebilirsiniz:

$HttpContent.Links | Where-Object {$_.class -eq "page-numbers"} | fl innerText, href

Veya URL adresindeki belirli bir metin:

$HttpContent.Links | Where-Object {$_.href -like "*powershell*"} | fl innerText,href

Ardından, bu sayfadaki tüm resimlerin bir listesini görüntüleyin:

$Img.Images

Bu resimlere giden tam URL yollarından oluşan bir koleksiyon oluşturun:

$images = $Img.Images | select src

WebClient sınıfının yeni bir örneğini başlatın:

$wc = New-Object System.Net.WebClient

Ve sayfadaki tüm görüntü dosyalarını (orijinal dosya adlarıyla birlikte) c:oo1s\ klasörüne indirin:

$images | foreach { $wc.DownloadFile( $_.src, ("c:\tools\"+[io.path]::GetFileName($_.src) ) ) }

Invoke-WebRequest cmdlet kullanımına ilişkin ilginç bir örnek “PowerShell Kullanarak Harici IP Adresi Alın” makalesinde bulunabilir.

PowerShell Wget (Invoke-WebRequest) ile HTTP/FTP Üzerinden Dosya Nasıl İndirilir?

Invoke-WebRequest, bir web sayfasından veya FTP sitesinden dosya indirmenize izin verir (Windows'ta Wget veya cURL gibi çalışır). Varsayalım ki, PowerShell kullanarak HTTP'den bir dosya indirmek istiyorsunuz. Aşağıdaki PowerShell komutunu çalıştırın:

wget "https://download-installer.cdn.mozilla.net/pub/firefox/releases/102.0.1/win64/en-US/Firefox%20Setup%20102.0.1.exe" -outfile “c:\tools\firefox_setup.exe”

Bu komut, dosyayı HTTP sitesinden indirecek ve belirtilen dizine kaydedecektir.

BITS'yi eşzamanlı modda kullanarak bir Windows web sunucusundan da dosya indirebilirsiniz.

Bir dosyanın boyutunu wget ile indirmeden önce MB cinsinden alabilirsiniz:

$url = "https://download-installer.cdn.mozilla.net/pub/firefox/releases/102.0.1/win64/en-US/Firefox%20Setup%20102.0.1.exe"
(Invoke-WebRequest $url -Method Head).Headers.'Content-Length'/1Mb

Aşağıda, bir hedef web sayfasındaki *.pdf dosyalarına giden tüm bağlantıları bulan ve bulunan tüm dosyaları web sitesinden bilgisayarınıza toplu olarak indiren bir PowerShell betiği örneği verilmiştir (her pdf dosyası rastgele bir adla kaydedilir):

$OutDir="C:\docs\download\PDF"
$SiteAdress = "https://sometechdocs.com/pdf"
$HttpContent = Invoke-WebRequest -URI $SiteAdress
$HttpContent.Links | Where-Object {$_.href -like "*.pdf"} | %{Invoke-WebRequest -Uri $_.href -OutFile ($OutDir + $(Get-Random 200000)+".pdf")}

Hedef dizindeki script sonucunda sayfadan tüm pdf dosyaları indirilecektir. Her dosya rastgele bir adla kaydedilir.

Modern PowerShell Core'da (6.1 ve daha yeni), Invoke-WebRequest cmdlet'i devam ettirme modunu destekler. PowerShell Core sürümünüzü güncelleyin ve Invoke-WebRequest komutundaki -Sürdür seçeneğini kullanarak bir iletişim kanalının veya sunucunun kullanılamaması durumunda dosyayı indirmeye otomatik olarak devam edebilirsiniz:

Invoke-WebRequest -Uri $Uri -OutFile $OutFile -Resume

PowerShell ile HTML Formu Nasıl Doldurulur ve Gönderilir?

Birçok web hizmeti, çeşitli verilerin HTML formlarına doldurulmasını gerektirir. Invoke-WebRequest ile herhangi bir HTML formuna erişebilir, gerekli alanları doldurabilir ve doldurulan formu sunucuya geri gönderebilirsiniz. Bu örnekte, PowerShell kullanarak standart web formu aracılığıyla Facebook'ta nasıl oturum açılacağını göstereceğiz.

Aşağıdaki komut ile bağlantı çerezleri ile ilgili bilgileri ayrı bir session değişkenine kaydedeceğiz:

$fbauth = Invoke-WebRequest https://www.facebook.com/login.php -SessionVariable session

Bir sonraki komutu kullanarak, oturum açma HTML formunu (login_form) doldurmak için alanların listesini görüntüleyin:

$fbauth.Forms["login_form"].Fields

Tüm alanlara istenen değerleri atayın:

$fbauth.Forms["login_form"].Fields["email"] = "somemail@gmail.com"
$fbauth.Forms["login_form"].Fields["pass"] = "Coo1P$wd"

Vesaire.

Doldurulmuş formu sunucuya göndermek (göndermek) için HTML formunun action niteliğini çağırın:

$Log = Invoke-WebRequest -method POST -URI ("https://www.facebook.com/login.php" + $fbauth.Forms["login_form"].Action) -Body $fbauth.Forms["login_form"].Fields -WebSession $session

POST yöntemiyle bir web sayfasına veri göndermek için JSON biçimini de kullanabilirsiniz:

$headers = @{
'Content-Type'='application/json'
'apikey'='0987654321'
}
$jsonbody = @{
"siteUrl" ="https://somesite.com"
"email" = "max@somesite.com"
}
Invoke-WebRequest -Method 'Post' -Uri $url -Body ($jsonbody |ConvertTo-Json) -Headers $headers -ContentType "application/json"

Invoke-WebRequest: SSL/TLS Sertifika Kontrollerini Yoksay

Diğer bir konu da Invoke-WebRequest cmdlet'inin Internet Explorer ile yakından ilişkili olmasıdır. Örneğin, IE'nin yüklenmediği (veya kaldırılmadığı) Windows Server Core sürümlerinde, Invoke-WebRequest cmdlet'i kullanılamaz.

Invoke-WebRequest: The response content cannot be parsed because the Internet Explorer engine is not available, or Internet Explorer’s first-launch configuration is not complete. Specify the UseBasicParsing parameter and try again.

Bu durumda, Invoke-WebRequest yerine WebClient sınıfı kullanılabilir. Örneğin, belirtilen bir URL'den dosya indirmek için komutu kullanın.

(New-Object -TypeName 'System.Net.WebClient').DownloadFile($Url, $FileName)

Bir HTTPS sitesinde geçersiz bir SSL sertifikası kullanılıyorsa veya PowerShell bu tür SSL/TLS protokolünü desteklemiyorsa Invoke-WebRequest cmdlet'i bağlantıyı keser.

Invoke-WebRequest : The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
Invoke-WebRequest : The request was aborted: Could not create SSL/TLS secure channel.

Varsayılan olarak Windows PowerShell (Windows 10, Windows Server 2016 ve Windows'un eski sürümlerinde) bağlantılar için eski ve güvenli olmayan TLS 1.0 protokolünü kullanır (PowerShell modülü yükleme hatasını açıklayan blog gönderisine bakın: Install-Module: Unable URI'den indirmek için).

Windows'ta eski TLS 1.0 ve TLS 1.1 protokolleri devre dışı değilse, TLS 1.2'yi PowerShell bağlantılarında kullanmak için aşağıdaki komutu çalıştırmanız gerekir:

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

HTTPS sitesinde kendinden imzalı bir sertifika kullanılıyorsa, Invoke-WebRequest cmdlet'i buradan veri almayı reddeder. Geçersiz bir SSL sertifikasını yoksaymak (atlamak) için aşağıdaki PowerShell kodunu kullanın:

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
$result = Invoke-WebRequest -Uri "https://somesite.com"

PowerShell Core'da, Invoke-WebRequest cmdlet'inde, geçersiz SSL/TLS sertifikalarını yoksaymanıza izin veren ek bir parametre -SkipCertificateCheck bulunur.

Invoke-WebRequest cmdlet'inin bir diğer önemli dezavantajı, oldukça düşük performansıdır. Bir dosya indirilirken, HTTP akışı tamamen belleğe alınır ve yalnızca tam indirme tamamlandıktan sonra diske kaydedilir. Bu nedenle, Invoke-WebReques kullanarak büyük dosyaları indirirken, RAM'iniz bitebilir.

İlgili makaleler