
The Invoke-WebRequest Команда может использоваться для запроса HTTP/HTTPS/FTP ресурсов непосредственно из консоли PowerShell. С помощью этой команды можно отправлять HTTP-запросы (GET и POST), скачивать файлы с веб-сайта, разбирать HTML-страницы, выполнять аутентификацию, заполнять и отправлять веб-формы и т. д. В этой статье мы рассмотрим основные примеры использования команды Invoke-WebRequest в PowerShell для взаимодействия с веб-службами.
- Получение содержимого веб-страницы с помощью командлета Invoke-WebRequest
- Использование Invoke-WebRequest с аутентификацией
- Разбор и соскабливание HTML веб-страницы с помощью PowerShell
- Как скачать файл по HTTP/FTP с помощью PowerShell Wget (Invoke-WebRequest)?
- Как заполнить и отправить HTML-форму с помощью PowerShell?
- Invoke-WebRequest: Игнорирование проверок сертификатов SSL/TLS
Получение содержимого веб-страницы с помощью командлета Invoke-WebRequest
The Invoke-WebRequest Команда PowerShell позволяет отправить HTTP-, HTTPS- или FTP-запрос с методом GET на указанную веб-страницу и получить ответ от сервера.
iwk
и wget
.Выполните следующую команду:
Invoke-WebRequest -Uri "https://woshub.com"
Invoke-WebRequest: Unable to connect to the remote server CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
Команда загружает страницу и отображает ее содержимое в консоли PowerShell. Возвращаемый ответ – это не просто HTML-код страницы. Команда Invoke-WebRequest возвращает объект типа HtmlWebResponseObject. Такой объект представляет собой набор форм, ссылок, изображений и других важных элементов HTML-документа. Давайте рассмотрим все свойства этого объекта:
$WebResponseObj = Invoke-WebRequest -Uri "https://woshub.com"
$WebResponseObj| Get-Member
Чтобы получить исходный HTML-код веб-страницы, содержащейся в HtmlWebResponseObject объект, выполнить:
$WebResponseObj.content
Вы можете перечислить HTML-код вместе с HTTP-заголовками, возвращенными веб-сервером:
$WebResponseObj.rawcontent
Вы можете проверить только код HTTP-статуса веб-сервера и HTTP-заголовки HTML-страницы:
$WebResponseObj.Headers
Как видите, сервер вернул ответ 200. Это означает, что запрос прошел успешно, веб-сервер доступен и работает корректно.
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
Чтобы получить время последней модификации веб-страницы:
$WebResponseObj.ParsedHtml | Select lastModified
При подключении к веб-ресурсу можно указать строку User Agent. PowerShell имеет набор встроенных строк User Agent:
invoke-webRequest -Uri $uri -userAgent ([Microsoft.PowerShell.Commands.PSUserAgent]::Chrome)
Список доступных агентов в PowerShell можно отобразить следующим образом:
[Microsoft.PowerShell.Commands.PSUserAgent].GetProperties() | Select-Object Name, @{n='UserAgent';e={ [Microsoft.PowerShell.Commands.PSUserAgent]::$($_.Name) }}
Или вы можете задать собственную строку UserAgent:
Invoke-WebRequest -Uri $uri -UserAgent 'MyApplication/1.1'
Использование Invoke-WebRequest с аутентификацией
Для доступа к некоторым веб-ресурсам требуется аутентификация. Вы можете использовать различные типы аутентификации с командой Invoke-WebRequest (Basic, NTLM, Kerberos, OAuth или аутентификация с помощью сертификата).
Чтобы выполнить базовую аутентификацию (аутентификация по имени и паролю, закодированным в base64), сначала нужно получить имя пользователя и пароль:
$cred = Get-Credential
wget -Uri 'https://somesite.com' -Credential $cred
Чтобы использовать текущие учетные данные пользователя Windows для выполнения аутентификации NTLM или Kerberos, добавьте параметр -UseDefaultCredentials:
Invoke-WebRequest 'https://somesite.com' -UseDefaultCredentials
Чтобы аутентифицироваться с помощью сертификата, необходимо указать его отпечаток:
Invoke-WebRequest 'https://somesite.com' -CertificateThumbprint xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Вы можете использовать современную аутентификацию с помощью токенов Bearer/OAuth в сценариях PowerShell.
- Сначала вам нужно получить OAuth-токен от вашего провайдера REST API (это выходит за рамки данной статьи);
- Преобразуйте токен с помощью команды ConvertTo-SecureString:
$Token = "12345678912345678901234567890" | ConvertTo-SecureString -AsPlainText –Force
- Теперь вы можете выполнить аутентификацию OAuth:
$Params = @{
Uri = "https://somesite.com"
Authentication = "Bearer"
Token = $Token }
Invoke-RestMethod @Params
Разбор и соскабливание HTML веб-страницы с помощью PowerShell
Команда Invoke-WebRequest позволяет быстро и удобно разобрать содержимое любой веб-страницы. При обработке HTML-страницы создаются коллекции ссылок, веб-форм, изображений, скриптов и т. д.
Давайте рассмотрим, как получить доступ к определенным объектам на веб-странице. Например, я хочу получить список всех исходящих ссылок (объектов A HREF) на целевой веб-странице HTML:
$SiteAdress = "https://woshub.com"
$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 "*powershell*"} | fl innerText,href
Затем выведите список всех изображений на этой странице:
$Img.Images
Создайте коллекцию полных URL-путей к этим изображениям:
$images = $Img.Images | select src
Инициализируйте новый экземпляр класса WebClient:
$wc = New-Object System.Net.WebClient
Загрузите все файлы изображений со страницы (с оригинальными именами файлов) в папку c:\too1s\:
$images | foreach { $wc.DownloadFile( $_.src, ("c:\tools\"+[io.path]::GetFileName($_.src) ) ) }
Как скачать файл по HTTP/FTP с помощью PowerShell Wget (Invoke-WebRequest)?
Invoke-WebRequest позволяет загружать файлы с веб-страницы или FTP-сайта (работает как Wget или cURL в Windows). Предположим, вы хотите загрузить файл с HTTP с помощью PowerShell. Выполните следующую команду 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-сайта и сохранит его в указанном каталоге.
Вы можете узнать размер файла в МБ перед его загрузкой с помощью wget:
$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 на целевой веб-странице и массово загрузит все найденные файлы с веб-сайта на ваш компьютер (каждый pdf-файл сохраняется под случайным именем):
$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")}
В результате работы скрипта в целевой каталог будут загружены все PDF-файлы со страницы. Каждый файл сохраняется под случайным именем.
Invoke-WebRequest -Uri $Uri -OutFile $OutFile –Resume
Как заполнить и отправить HTML-форму с помощью PowerShell?
Многие веб-службы требуют заполнения различных данных в HTML-формах. С помощью Invoke-WebRequest вы можете получить доступ к любой HTML-форме, заполнить необходимые поля и отправить заполненную форму обратно на сервер. В этом примере мы покажем, как войти в Facebook через стандартную веб-форму с помощью PowerShell.
С помощью следующей команды мы сохраним информацию о cookies подключения в отдельной переменной сессии:
$fbauth = Invoke-WebRequest https://www.facebook.com/login.php -SessionVariable session
С помощью следующей команды выведите список полей для заполнения в HTML-форме входа в систему (login_form):
$fbauth.Forms["login_form"].Fields
Присвойте всем полям нужные значения:
$fbauth.Forms["login_form"].Fields["email"] = "[email protected]"
$fbauth.Forms["login_form"].Fields["pass"] = "Coo1P$wd"
И т.д.
Чтобы отправить (послать) заполненную форму на сервер, вызовите атрибут action HTML-формы:
$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
Вы также можете использовать формат JSON для отправки данных на веб-страницу с помощью метода POST:
$headers = @{
'Content-Type'='application/json'
'apikey'='0987654321'
}
$jsonbody = @{
"siteUrl" ="https://somesite.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. Например, чтобы загрузить файл с указанного URL, используйте команду.
(New-Object -TypeName 'System.Net.WebClient').DownloadFile($Url, $FileName)
Если на сайте HTTPS используется недействительный SSL-сертификат или PowerShell не поддерживает этот тип протокола SSL/TLS, команда Invoke-WebRequest разрывает соединение.
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.
По умолчанию Windows PowerShell (в ранних сборках Windows 10, Windows Server 2016 и старых версиях Windows) использует для соединений устаревший и небезопасный протокол TLS 1.0 (см. запись в блоге, описывающую ошибку установки модуля PowerShell: Install-Module: Unable to download from URI).
Если устаревшие протоколы TLS 1.0 и TLS 1.1 не отключены в Windows, для использования TLS 1.2 в соединениях PowerShell необходимо выполнить следующую команду:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Если на сайте HTTPS используется самоподписанный сертификат, команда Invoke-WebRequest отказывается получать от него данные. Чтобы проигнорировать (пропустить) недействительный сертификат 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://somesite.com"
Еще одним существенным недостатком команды Invoke-WebRequest является ее довольно низкая производительность. При загрузке файла HTTP-поток полностью буферизируется в памяти и только после полного завершения загрузки сохраняется на диск. Таким образом, при загрузке больших файлов с помощью Invoke-WebReques может закончиться оперативная память.