Invoke-WebRequest: Отправка HTTP запросов, загрузка файлов и обработка HTML веб-страниц в PowerShell

Командлет Invoke-WebRequest можно использовать для обращения к HTTP/HTTPS/FTP ресурсам прямо из консоли PowerShell. С помощью этой команды вы можете отправить HTTP запросы, скачивать файлы с любых веб-сайтов, парсить HTML веб-страницы, заполнять и отправлять веб-формы. В этой статье мы рассмотрим несколько базовых примеров использования командлета Invoke-WebRequest для работы с веб-сервисами.

Получить содержимое веб-страницы с помощью командлета Invoke-WebRequest

Командлет Invoke-WebRequest доступен в Windows начиная с версии PowerShell 3.0. Командлет Invoke-WebRequest позволяет отправить HTTP запрос с методом GET к указанной веб странице и получить ответ от севера.

В Windows есть два алиаса для команды Invoke-WebRequest: iwk и wget .

Выполните следующую команду:

Invoke-WebRequest -Uri "https://winitpro.ru"

получить html код страницы Invoke-WebRequest с помощью powershell

Совет. Если вы подключены к Интернет через прокси-сервер, нужно правильно настроить PowerShell для доступа через прокси-сервер.

Команда загрузила страницу и отобразила ее содержимое в консоли PowerShell. Возвращенный ответ представляет собой не просто HTML код страницы. Командлет Invoke-WebRequest возвращает объект типа HtmlWebResponseObject. Такой объект представляет собой набор коллекции форм, ссылок, изображений и других важных элементов HTML документа. Посмотрим все свойства данного объекта:

$WebResponseObj = Invoke-WebRequest -Uri "https://winitpro.ru"
$WebResponseObj| Get-Member

свойства объекта HtmlWebResponseObject

Чтобы получить сырой HTML код веб страницы, который содержится в данном объекте, выполните:

$WebResponseObj.content

Вы можете вывести HTML код страницы вместе с HTTP заголовками, которые вернул веб сервер:

$WebResponseObj.rawcontent

powershell: получить html код страницы и http заголовки

Можно получить только код ответа веб-сервера и 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

получить время последнего изменения 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) }}

powershell изменить useragent в запросе

Либо вы можете задать собственную строку:

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

DefaultCredentials не работает с Basic аутентфикацией.

Для аутентификации по сертификату, нужно указать его отпечаток:

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 }

Invoke-WebRequest вывести список ссылок на html странице

Чтобы получить и сам текст ссылки (содержится в элементе 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

powershell фильтр объектов на html странице

Теперь рассмотрим, как получить все изображения на данной странице:

$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) ) ) }

Пример парсинга html страницы на powershell

С помощью Invoke-WebRequest можно узнать внешний IP адреса компьютера из PowerShell через специальный веб-сервис.

Как скачать файл по 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”

windows: скачать файл по http с помощью wget из powershell

Этак команда скачает файл с HTTP сайта и поместит его в указанный каталог.

Так же вы можете скачать файлы с веб-сервера Windows при помощи BITS в синхронном режиме.

Вы можете получить размер файла в Мб перед его загрузкой:

$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

invoke-webrequest: получить размер файла перед его загрузкой

Ниже приведен пример 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 Core (6.1 и выше) команделт Invoke-WebRequest поддерживает режим докачки. Обновите вашу версию PowerShell Core и вы можете использовать опцию Resume в команде Invoke-WebRequest для автоматического возобновления загрузки файла при проблемах на канале или недоступности сервера.

Заполнение и отправка веб-форм на Powershell

Многие веб-сервисы для работы требуют ввода различных данных в HTML формы. С помощью Invoke-WebRequest можно получить доступ к любой HTML-форме, заполнить необходимые поля и передать заполненную форму обратно на сервер. В этом примере мы покажем, как с помощью Powershell авторизоваться в почтовом ящике популярного российского сервиса mail.ru через его стандартную веб форму.

powershell аутентификация с помощью веб форм на mailru

С помощью следующей конструкции сохраним информацию о куках (Cookies) подключения в отдельной сессионной переменной:

$mailru = Invoke-WebRequest https://e.mail.ru/login -SessionVariable session

Следующей командой отобразим список заполняемых полей в HTML форме авторизации (форма называется LoginExternal):

$mailru.Forms["LoginExternal"].Fields

Присвоим нужные значения всем полям:

$mailru.Forms["LoginExternal"].Fields["Login"] = "testmail@mail.ru"

$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" = "support@site.com"
}
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.

Invoke-WebRequest Не удалось создать защищенный канал SSL/TLS

По умолчанию в 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"

В версиях PowerShell Core у командлета Invoke-WebRequest доступен параметр –SkipCertificateCheck, который позволяет игнорировать некорректные сертификаты.

Еще один существенный недостаток командлета Invoke-WebRequest — довольно низкая скорость работы. HTTP поток при загрузке файла целиком буферизируется в память, и только после окончания полной загрузки сохраняется на диск. Таким образом, при загрузке больших файлов вы можете столкнутся с нехваткой памяти.


Предыдущая статья Следующая статья


Комментариев: 38 Оставить комментарий

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Я не робот( Обязательно отметьте)