Командлет Invoke-WebRequest можно использовать для обращения к HTTP/HTTPS/FTP ресурсам прямо из консоли PowerShell. С помощью этой команды вы можете отправить HTTP запросы, скачивать файлы с любых веб-сайтов, парсить HTML веб-страницы, заполнять и отправлять веб-формы. В этой статье мы рассмотрим несколько базовых примеров использования командлета Invoke-WebRequest для работы с веб-сервисами.
- Получить содержимое веб-страницы с помощью командлета Invoke-WebRequest
- Использование Invoke-WebRequest с аутентификацией
- Парсинг HTML страниц с помощью Powershell
- Как скачать файл по HTTP с помощью PowerShell?
- Заполнение и отправка веб-форм на Powershell
- Invoke-WebRequest: игнорировать проверку SSL/TLS сертификатов
Получить содержимое веб-страницы с помощью командлета Invoke-WebRequest
Командлет Invoke-WebRequest доступен в Windows начиная с версии PowerShell 3.0. Командлет Invoke-WebRequest позволяет отправить HTTP запрос с методом GET к указанной веб странице и получить ответ от севера.
iwk
и
wget
.Выполните следующую команду:
Invoke-WebRequest -Uri "https://winitpro.ru"
Команда загрузила страницу и отобразила ее содержимое в консоли PowerShell. Возвращенный ответ представляет собой не просто HTML код страницы. Командлет Invoke-WebRequest возвращает объект типа HtmlWebResponseObject. Такой объект представляет собой набор коллекции форм, ссылок, изображений и других важных элементов HTML документа. Посмотрим все свойства данного объекта:
$WebResponseObj = Invoke-WebRequest -Uri "https://winitpro.ru"
$WebResponseObj| Get-Member
Чтобы получить сырой HTML код веб страницы, который содержится в данном объекте, выполните:
$WebResponseObj.content
Вы можете вывести HTML код страницы вместе с HTTP заголовками, которые вернул веб сервер:
$WebResponseObj.rawcontent
Можно получить только код ответа веб-сервера и HTTP заголовки HTML страницы:
$WebResponseObj.StatusCode
$WebResponseObj.Headers
Как вы видите, веб сервер вернул ответ 200, т.е. запрос выполнен успешно и веб сервер доступен и работает корректно.
Key Value --- ----- Transfer-Encoding chunked Connection keep-alive Vary Accept-Encoding,Cookie Strict-Transport-Security max-age=31536000; Cache-Control max-age=3, must-revalidate Content-Type text/html; charset=UTF-8 Date Mon, 11 Jul 2022 08:18:05 GMT Server nginx/1.20.2 X-Powered-By PHP/5.6.40
Чтобы получить время последней модификации веб-страницы:
$WebResponseObj.ParsedHtml | Select lastModified
Вы можете указать строку User Agent при подключении к веб-ресурсу. В PowerShell есть набор встроенных строк User Agent:
invoke-webRequest -Uri $uri -userAgent ([Microsoft.PowerShell.Commands.PSUserAgent]::Chrome)
Список доступных агентов можно вывести так:
[Microsoft.PowerShell.Commands.PSUserAgent].GetProperties() | Select-Object Name, @{n='UserAgent';e={ [Microsoft.PowerShell.Commands.PSUserAgent]::$($_.Name) }}
Либо вы можете задать собственную строку:
Invoke-WebRequest -Uri $uri -UserAgent 'MyApplication/1.1'
Использование Invoke-WebRequest с аутентификацией
Для доступа к некоторым веб ресурсам нужно выполнить аутентификацию. Вы можете использовать различные типы аутентификации совмести с командлетом Invoke-WebRequest (базовую, NTLM, Kerberos или аутентификацию по сертификату).
Для выполнения базовой аутентификации (Basic auth, аутентификация по имени и паролю зашифрованным в base64) сначала нужно получить имя пользователя и пароль:
$cred = Get-Credential
wget -Uri 'https://site.com' -Credential $cred
Для использования текущих учетных данных пользователя Windows для выполнения NTLM или Kerberos аутентификации, используйте параметр UseDefaultCredentials:
Invoke-WebRequest 'http://site.com' -UseDefaultCredentials
Для аутентификации по сертификату, нужно указать его отпечаток:
Invoke-WebRequest 'http://site.com' -CertificateThumbprint xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Вы можете использовать современную Bearer/OAuth аутентификацию с помощью токена в ваших PowerShell скриптах.
- Сначала нужно получить токен OAuth у вашего провайдера REST API
- Сконвертируйте токен с помощью ConvertTo-SecureString:
$Token = "123123123123123123123123123123123" | ConvertTo-SecureString -AsPlainText –Force
- Теперь вы можете выполнить OAuth аутентфикацию:
$Params = @{
Uri = "https://yoursite.com"
Authentication = "Bearer"
Token = $Token }
Invoke-RestMethod @Params
Парсинг HTML страниц с помощью Powershell
Командлет Invoke-WebRequest позволяет довольно быстро и удобно парсить содержимое любых веб-страниц. При обработке HTML страницы из ее содержимого формируются коллекции ссылок (links), веб-форм (forms), изображений (images), скриптов (scripts) и т.д.
Рассмотрим, как обратиться к конкретным объектам на веб-странице. Например, мы хотим получить список всех исходящих ссылок (объекты HREF) на полученной веб-странице:
$SiteAdress = "http://winitpro.ru"
$HttpContent = Invoke-WebRequest -URI $SiteAdress
$HttpContent.Links | Foreach {$_.href }
Чтобы получить и сам текст ссылки (содержится в элементе InnerText), можно воспользоваться такой конструкцией:
$HttpContent.Links | fl innerText, href
Можно выбрать только ссылки с определенным CSS классом:
$HttpContent.Links | Where-Object {$_.class -eq "page-numbers"} | fl innerText, href
Или определенным текстом в url:
$HttpContent.Links | Where-Object {$_.href -like "*exchange*"} | fl innerText,href
Теперь рассмотрим, как получить все изображения на данной странице:
$Img.Images
Сформируем коллекцию из полных url путей к используемым изображениям:
$images = $Img.Images | select src
Инициализируем новый экземпляр класса WebClient:
$wc = New-Object System.Net.WebClient
И скачаем все изображения со страницы (с оригинальными именами) в каталог c:\tools\:
$images | foreach { $wc.DownloadFile( $_.src, ("c:\tools\"+[io.path]::GetFileName($_.src) ) ) }
Как скачать файл по HTTP с помощью PowerShell?
Invoke-WebRequest позволяет скачивать файлы с указанной веб-страницы или ftp сайта (работает как аналог Wget или cURL для Windows). Допустим, вы хотите скачать с HTTP сайта файл. Выполните такую команду PowerShell:
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”
Этак команда скачает файл с HTTP сайта и поместит его в указанный каталог.
Вы можете получить размер файла в Мб перед его загрузкой:
$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
Ниже приведен пример PowerShell скрипта, который найдет все ссылки на *.pdf файлы на веб странице и скачает все найденный файлы с сайта на ваш компьютер (каждый файл сохраняется под произвольным именем):
$OutDir="C:\Downloads\docs\PDF"
$SiteAdress = "https://www.site.ru/free-pdf-books/"
$HttpContent = Invoke-WebRequest -URI $SiteAdress
$HttpContent.Links | Where-Object {$_.href -like "*.pdf"} | %{Invoke-WebRequest -Uri $_.href -OutFile ($OutDir + $(Get-Random 100000)+".pdf")}
Заполнение и отправка веб-форм на Powershell
Многие веб-сервисы для работы требуют ввода различных данных в HTML формы. С помощью Invoke-WebRequest можно получить доступ к любой HTML-форме, заполнить необходимые поля и передать заполненную форму обратно на сервер. В этом примере мы покажем, как с помощью Powershell авторизоваться в почтовом ящике популярного российского сервиса mail.ru через его стандартную веб форму.
С помощью следующей конструкции сохраним информацию о куках (Cookies) подключения в отдельной сессионной переменной:
$mailru = Invoke-WebRequest https://e.mail.ru/login -SessionVariable session
Следующей командой отобразим список заполняемых полей в HTML форме авторизации (форма называется LoginExternal):
$mailru.Forms["LoginExternal"].Fields
Присвоим нужные значения всем полям:
$mailru.Forms["LoginExternal"].Fields["Login"] = "[email protected]"
$mailru.Forms["LoginExternal"].Fields["Password"] = "Str0NgP$$w0rd"
И т.д….
Чтобы передать заполненную форму на веб сервер, вызовем атрибут HTML-формы action.
$Log = Invoke-WebRequest -method POST -URI ("https://e.mail.ru/login" + $mailru.Forms["LoginExternal"].Action) -Body $mailru.Forms["LoginExternal"].Fields -WebSession $session
Также вы можете использовать формат JSON для отправки данных на веб страницу через метод POST:
$headers = @{
'Content-Type'='application/json'
'apikey'='1234567890'
}
$jsonbody = @{
"siteUrl" ="https://site.com"
"email" = "[email protected]"
}
Invoke-WebRequest -Method 'Post' -Uri $url -Body ($jsonbody |ConvertTo-Json) -Headers $headers -ContentType "application/json"
Invoke-WebRequest: игнорировать проверку SSL/TLS сертификатов
Командлет Invoke-WebRequest тесно связан с Internet Explorer. Например, в редакциях Windows Server Core, в которых IE не установлен (или удален), командлет Invoke-WebRequest использовать нельзя.
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.
Вместо Invoke-WebRequest можно использовать класс WebClient:
(New-Object -TypeName 'System.Net.WebClient').DownloadFile($Url, $FileName)
Если на HTTP сайте используется некорректный SSL сертификат, или PowerShell не поддерживает этот тип протокола TLS, то командлет Invoke-WebRequest отказывается получать данные с него.
Invoke-WebRequest : The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
Invoke-WebRequest : Запрос был прерван: Не удалось создать защищенный канал SSL/TLS.
Invoke-WebRequest : The request was aborted: Could not create SSL/TLS secure channel.
По умолчанию в Windows PowerShell (ранние билды Windows 10, Windows Server 2016 и более старые версии Windows) для подключения используется устаревший и небезопасный протокол TLS 1.0 (см. статью об ошибке установки PowerShell модуля: Install-Module: Unable to download from URI).
Если в Windows не отключены протоколы TLS 1.0 и TLS 1.1, нужно выполнить следующую команду, чтобы в текущей сессии PowerShell для подключения использовался протокол TLS 1.2:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Если вам нужно игнорировать самоподписанный сертификат SSL сертификат, используйте следующий 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;
}
}
"@
$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://site.ru"
Еще один существенный недостаток командлета Invoke-WebRequest — довольно низкая скорость работы. HTTP поток при загрузке файла целиком буферизируется в память, и только после окончания полной загрузки сохраняется на диск. Таким образом, при загрузке больших файлов вы можете столкнутся с нехваткой памяти.