Командлет 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 поток при загрузке файла целиком буферизируется в память, и только после окончания полной загрузки сохраняется на диск. Таким образом, при загрузке больших файлов вы можете столкнутся с нехваткой памяти.
Скажите как зайти на сайт с самоподписанным сертификатом
Игнорировать SSL сертификат можно так:
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://site.ru"
Очень вам признателен) Все отлично отрабатывает
Можно ли через Powershell выполнять переход по объектам на странице
и их измененять, если они не являются линками?
Я хочу подключаться к Vsheild и добавлять изменения в объект библиотеки (см.скриншот по ссылке http://hostingkartinok.com/show-image.php?id=e456b42cdb1810768766f6eeeb22cf36) Пока функции PowerCli Этого не позволяют. Приходится искать сторонние методы.
вообще это реально или нет?
Если я правильно понял, нужно изменить какую-то форму на странице и сохранить изменения? Если да — пример работы есть выше в разделе «Заполнение и отправка веб-форм на Powershell»
Дело в том что уже на авторизованной странице нет ни форм, ни ссылок для перехода на следующую страницу. Есть объекты слева как видно на картинке. Как осуществить выбор того или иного объекта?
Похоже страница выполнена на Java. Боюсь вам помочь не смогу — здесь лучше проконсультироваться с Web программистами… Они лучше понимают как можно выполнять навигацию по такому документу
Добрый день.
Подскажите, на основе Вашего примера, как можно пропарсить страничку вроде https://chocolatey.org/packages/flashplayeractivex
в поисках ссылки на дистрибутив
$url = ‘http://download.macromedia.com/get/flashplayer/current/licensing/win/install_flash_player_17_active_x.msi’ ,
которая находится под примерами вызова команд
Files > Show > \chocolateyInstall.ps1 Show >
Т.е. как получить вожделенную ссылку на дистрибутив с веб-страницы?
А если нет таких форм?
Например, вот сайт:
_http://www.stn.by/ips_renovation_login.php
Задача туда зайти и получить ссылку после входа.
как работать с sFTP — кто-нибудь пробовал?
например, тот же curl, это позволяет….
На Windows 7 для Invoke-WebRequest сначала придется поставить WMF 3.0 или выше.
А как можно перед скачиванием файла узнать его размер, дату создания и пр.? Нужно для того, чтобы не скачивать большой файл (1,2Гб) каждый раз повторно, а ждать когда он изменится (название файла не меняется).
Попробуйте получить размер файла так:
$url = "site.ru/bigfile.iso"
(Invoke-WebRequest $url -Method Head).Headers.'Content-Length'
Спасибо, работает!
народ кто может подсказать как открыть
«http://api.weatherstack.com/current?access_key=637af1c4660c987dcf5825c34aae2513&query=London»
в PowerShell?
При запуске команды Invoke-WebRequest у меня в консоли PowerShell появляется ошибка
Invoke-WebRequest : Запрос был прерван: Не удалось создать защищенный канал SSL/TLS.
Причем только у некоторых сайтов. Что делать?
Похоже вы пытаетесь подключится к сайту с новым SSL сертификатом, попробуте принудительно указать тип протокола TLS, например:
Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri https://www.java.com
Спасибо, помогло!
Попробуйте Invoke-WebRequest -Uri https://api.telegram.org
Если найдете решение буду вам очень признателен.
Судя по ошибке, которая появляется в PowerShell и тому, что этот сайт не открывается, это не веб страница. Invoke-WebRequest тут бессилен, смотрите в сторого API Telegram
Нашел решение, может кто-нибудь так же как и я будет гуглить несколько дней и наткнется….
Накатываете обновление KB2992611.
В коде, если это powershell добавляете :
[Net.ServicePointManager]::SecurityProtocol =
[Net.SecurityProtocolType]::Tls13 -bor `
[Net.SecurityProtocolType]::Tls12 -bor `
[Net.SecurityProtocolType]::Tls11 -bor `
[Net.SecurityProtocolType]::Tls
Отлично, что разобрались и оставили решение 🙂
Как в командной строке получить с сервера информацию о погоде используя API : weatherstack.com (бывший apixu.com)?
Точнее как получить я понимаю, не понимаю как полученный результат упорядочить.
(Invoke-webrequest «ссылка на API сайта» -usebasicparsing).content — что добавить?
Судя по описанию на этом сервисе вам нужно получить некий токен доступа, а потом обращаться через него. На выходе API отдает json файл, который нужно распарсить в powershell.
$req = Invoke-RestMethod ‘http://api.weatherstack.com/current?access_key=xxxxxxxxx&query=Moscow’
$req.Request
О, скиллбокс! Сам ищу ответ…
Подскажите пожалуйста команду для скачки списка URL из файла (ну например urls.txt) с условием, чтобы файл на сервере был не меньше 100кб например.
Проверьте, что вас сервис, где лежит файл отдает его размер:
$Info = Invoke-WebRequest -Uri 'http://...' -Method Head
$Info.Headers['Content-Length'] / 1KB
Как обновлять полученную информацию с сайта путем — (invoke-webrequest «сайт»).content.
Имею в виду чтобы не вводить эту команду постоянно для получения новой информации, как сделать так чтобы оно само обновлялось и выводило новую инфу?
Вам нужно сравнивать ищменилось ли содержимое страницы или просто в бесконечном цикле выводить содержимое (например раз в 10 сек):
While($true)
{
$i++
$WebResponseObj = Invoke-WebRequest -Uri "!https://winitpro.ru"
$WebResponseObj.content
sleep 10
}
Добрый день. Подскажите решение для одного «затыка»
делаю $a = Invoke-WebRequest -Uri «somesite.com»
Затем мне нужна выборка по модификации страницы
делаю так $a.headers.Expires
получаю ответ
а вот последнее изменение
$a.headers.Last-Modified не работает, да и не может работать хотя сам key присутствует
Впрочем любой key в Headers обрабатывается нормально кроме тех которые содержат — тире
Подскажите как это мудло победить?
Спасибо заранее, очень нужна помощь для лаболаторки
Разобрался, надо это чудище в одинарные скобки закрывать :))
Спасибо за отличный форум и мануалы
Добрый день!
Не могу разобраться как отправить запрос с конкретными cookies через Invoke-WebRequest. Есть сайт, доступ на который можно получить только с определенными заголовками, но никак не получается их указать.
Здравствуйте!
Подскажите пожалуйста, можно ли командлетом Invoke-WebRequest посчитать время загрузки любого сайта. Либо вывести результат, о невозможности загрузки.
Получить время загрузки страницы
$url = '_https://winitpro.ru'
$timeTaken = Measure-Command -Expression {
$site = Invoke-WebRequest -Uri $url -UseBasicParsing
}
$milliseconds = $timeTaken.TotalMilliseconds
$milliseconds = [Math]::Round($milliseconds, 0)
write-host $milliseconds
Здравствуйте! Подскажите, пожалуйста, командлетом Invoke-WebRequest можно получить определенный header сайта, а именно Remote Address (его айпи)?
В PowerShell есть командлет для резолва IP адреса.
Если нужно через Invoke-webrequest, то только через внешний сайт. Вот пример через гугл:
$site=»_winitpro.ru»
$rawresp=Invoke-WebRequest «_https://dns.google/resolve?name=$site&type=A»
$rawjson = ConvertFrom-Json -InputObject $rawresp.Content
$rawjson.answer.data
В блоке про скачивание файлов опечатка:
«Выполните такую команду PowerShell:» и дальше wget
Добрый день, касаемо авторизации Invoke-Webrequest, на мэйл ру используются 2 поля, логин и пароль, мне надо зайти на сайт, где только одно поле — пароль. При использовании только поля .Forms[«LoginExternal»].Fields[«Password»] скрипт выдаёт ошибку: Не удается индексировать в массив NULL.
D:\test2.ps1:4 знак:1
+ $Testsite.Forms[«LoginExternal»].Fields[«Password»] = «1234»
Код скрипта:
$uri = ‘localhost’
$Testst = Invoke-WebRequest $uri -SessionVariable session -userAgent ([Microsoft.PowerShell.Commands.PSUserAgent]::Chrome)
$Testst.Forms[«LoginExternal»].Fields
$Testst.Forms[«LoginExternal»].Fields[«Password»] = «1234»
$Log = Invoke-WebRequest -method POST -URI ($uri + $Testst.Forms[«LoginExternal»].Action) -Body $Testst.Forms[«LoginExternal»].Fields -WebSession $session
Ошибка:
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.