Частина 14. HTTP-запити до веб-ресурсів у PowerShell

25 листопада 2023 7 хвилин Автор: Cyber Witcher

Використання HTTP-запитів у PowerShell для взаємодії з веб-ресурсами

Управління процесами, послугами та серверами автоматизації за допомогою PowerShell – це фундаментальна здатність для будь-якого фахівця в сфері ІТ та кібербезпеки. PowerShell, розроблений Microsoft, є потужним інструментом для скриптингу та автоматизації, що дозволяє контролювати та управляти процесами та послугами на комп’ютерах та серверах. У цій статті ми розглядаємо, як використовувати PowerShell для моніторингу, запуску, зупинки та налаштування процесів та послуг, а також для управління серверами і їх конфігурацією. Ви навчитеся застосовувати різноманітні команди та скрипти для ефективного управління ІТ-інфраструктурою.

Ця стаття також надасть вам інформацію про створення скриптів для автоматизованого управління задачами, як-от регулярне оновлення серверів, моніторинг стану системи та виправлення помилок. В інтернеті існує величезна кількість корисних сервісів, з якими можна працювати, отримуючи доступ до їх ресурсів по протоколу NTTR. Веб-розробники постійно працюють із цими запитами HTTR для доступу до зовнішніх функцій API або для тестування власних додатків. Традиційно це робиться за допомогою спеціальних додатків (наприклад, Postman), консольних утиліт, таких як cURL і wget, а також NTTR-клієнтів, інтегрованих в середовища розробки. PowerShell пропонує два стандартних командлети для доступу до веб-ресурсів по протоколу NTTR: Invoke-WebRequest і Invoke-RestMethod.

Командлет Invoke-WebRequest

Ви можете використовувати командлет Invoke-WebRequest, щоб відправити запит на веб-сервер і отримати від нього відповідь.

Аналіз сторінок NTMI

Командлет Invoke-WebRequest добре підходить для парсингу  Tayuke: цей командлет може зберігати сторінки на локальний диск, цим він схожий на консольну утиліту wget і навіть має такий псевдонім:

PS C:\Script> Get-Alias wget
CommandType Name
Alias wget -> Invoke-WebRequest

Використовуйте цей командлет для переходу на просту сторінку, наприклад Приклад домену (https://example.com/index.html) (див. Малюнок 1). 14.1

За замовчуванням Invoke-WebRequest виконує HTTP-запит з методом GET до ресурсу на веб-сервері, з адресою ресурсу, вказаною як значення параметра -Uri. В результаті повертається об’єкт типу Htm1WebResponseObject, в якому зберігається інформація про відповідь сервера:

Головна сторінка сайту Example Domain у браузері
PS C:\Script> $web = Invoke-WebRequest -Uri https://exanple.com/index.ht3nl
PS C:\Script> $web | Get-Member
TypeName: Microsoft.PowerShell.Commands.HtmlWebResponseObject
PS C:\Script> $web
StatusCode : 200
StatusDescription : OK
Content : <!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8” />
<meta http-equiv="Content-type" content="text/html; char 
set=utf-8” />
<meta name="viewport" conten...
RawContent : HTTP/1.1 200 OK
Age: 497890
Vary: Accept-Encoding
X-Cache: HIT
Forms
Content-Length: 1256
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Mon, 12 Jul 2021 16:05:14 GMT
Exp...
: {}
Headers : {[Age, 497890], [Vary, Accept-Encoding], [X-Cache, HIT],
[Content-Length, 1256]... }
Images
InputFields
Links
: {}
: {}
: {@{innerHTML=More information...; innerText=More information
...; outerHTML=<A href="https://www.iana.org/domains/example
">More information...</A>; outerText=More information...;
tagName=A; href=https://www.iana.org/domains/example}}
ParsedHtml
RawContentLength
: mshtml.HTMLDocumentClass
: 1256

У полі statuscode міститься код відповіді від сервера (200 для нашого прикладу), у полі statusDescription — текстовий опис відповіді (ОК).

Вміст відповіді від сервера та НТТР-заголовки

Вміст відповіді від сервера зберігається як рядок у полі content. В нашому у випадку тут буде записаний HTML-код:

PS C:\Script> $web.Content
<!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name-'viewport” content="width=device-width, initial-scale=l" />
<style type="text/css">
body {
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI",
"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
div {
width: 600px;
margin: 5em auto;
padding: 2em;
background-color: #fdfdff;
border-radius: 0.5em;
box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
}
a:link, a:visited {
color: #38488f;
text-decoration: none;
@media (max-width: 700рх) {
div {
margin: 0 auto;
width: auto;
}
}
</style>
</head>
<body>
<div>
<hl>Example Domain</hl>
<p>This domain is for use in illustrative examples in documents. You may
use this domain in literature without prior coordination or asking
for permission.</p>
<p><a href=”https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>

У полі Rawcontent записується повна відповідь від сервера з НТТР-заголовками на початку:

PS C:\Script> $web.RawContent
НТТР/1.1 200 OK
Age: 497890
Vary: Accept-Encoding
X-Cache: HIT
Content-Length: 1256
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Mon, 12 Jul 2021 16:05:14 GMT
Expires: Mon, 19 Jul 2021 16:05:14 GMT
ETag: "3147526947+ident"
Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
Server: ECS (dcb/7F83)
<!doctype html>
<html>
<head>
<title>Example Domain</title>

Також заголовки відповіді виділяються окремо та зберігаються у вигляді хеш-таблиці у якості headers:

PS C:\Script> $web.headers
Key Value
Age 497890
Vary Accept-Encoding
X-Cache HIT
Content-Length 1256
Cache-Control max-,
Content-Type
Date
Expires
ETag
Last-Modified
Server
max-age=604800
text/html; charset=UTF-8
Mon, 12 Jul 2021 16:05:14 GMT
Mon, 19 Jul 2021 16:05:14 GMT
"3147526947+ident"
Thu, 17 Oct 2019 07:18:26 GMT 
ECS (dcb/7F83)

Збереження веб-ресурсів

Щоб зберегти відповідь від сервера у вигляді локального файлу, потрібно при викликі Invoke-WebRequest ВИКОРИСТОВУВАТИ КЛЮЧ -OutFile і вказати шлях до потрібного файлу.

PS C:\Script> Invoke-WebRequest -Uri https://exanple.com/index.html
-OutFile page.html

Перевіримо вміст файлу page.html і переконаємося, що в ньому записано HTML розмітку збереженої сторінки:

PS C:\Script> type .\page.html
<!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content=”text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=l" />
<style type="text/css">
body {
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI",
"Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
div {
width: 600px;
margin: 5em auto;
padding: 2em;
background-color: ttfdfdff;
border-radius: 0.5em;
box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
a:link, a:visited {
color: #38488f;
text-decoration: none;
}
@media (max-width: 700px) {
div {
margin: 0 auto;
width: auto;
}
}
</style>
</head>
<body>
<div>
<hl>Example Domain</hl>
<p>This domain is for use in illustrative examples in documents. You may
use this domain in literature without prior coordination or asking
for permission.</p>
<p><a href="https://www.iana.оrg/domains/example”>More information... </ax/p>
</div>
</body>
</html>

Подібним чином можна зберігати не лише HTML-файли, а й ресурси інших типів (текстові, графічні чи мультимедійні файли тощо), до яких можна звернутись на сайт.

Пошук HTML-елементів на сторінці

У властивостях Forms (форми), Images (зображення), InputFields (ПОЛЯ ВВЕДЕННЯ) І Links (посилання) об’єкта HtmiwebResponseObject зберігаються масиви об’єктів, які описують відповідні елементи HTML-розмітки, отриманої від сервера. Обробляючи ці колекції, можна отримати інформацію про елементи, що цікавлять нас, на завантаженій сторінці.

Виділимо на цій сторінці усі посилання на сайт habr.com. Для цього потрібно відфільтрувати масив $web. Links, залишивши в ньому об’єкти, які мають значення властивості href відповідає масці *habr.com*:

PS C:\Script> $habr_links = $web.Links | Where-Object href -like '*habr.com*'

В $habr_iinks містить два об’єкти PSCustomObject, що містять різні HTML-атрибути для посилань:

PS C:\Script> $habr_links.count
2
PS C:\Script> $habr_links | Get-Member

Наприклад, виведемо значе:

PS C:\Script> $habr_links | ForEach-Object {$_.href + " - " + $_.innerText }
https://habr.com/ru/company/ruvds/blog/487876/ -
Что такое Windows PowerShell и с чем его едят? / Хабр
https://habr.com/ru/company/ruvds/blog/487876/ -
habr.com >ru/company/ruvds/blog/487876/

У властивості ParsedHtml об’єкта HtmlWebResponseObject міститься об’єкт типу mshtmi.HTMLDocumentciass, який надає доступ до DOM-дерева завантаженої HTML сторінки.

PS С:\Users\andrv> $html = $web. ParsedHtml
PS C:\Users\andrv> Get-Member -Inputobject $html
TypeName: mshtmi.HTMLDocumentciass

Виконання POST-запитів

Командлет Invoke-WebRequest дозволяє не тільки виконувати GET-запити, але й викликати інші методи, визначені у протоколі HTTP (delete, head, merge, patch, post, put, trace). І тому потрібний метод вказується як значення параметра -Method. Розглянемо приклад виконання запиту з HTTP-методом post, який часто використовується для передачі даних із веб-форм або завантаження файлів на сервер. Звертатись ми будемо до ресурсу http://httpbin.org/post, в результаті сервер має повідомити нам про отримані дані. Передаватимемо два параметри з іменами name і lastName, які помістимо у хэш-таблицу $params:

PS С:\Users\andrv> $params = @{name='Andrey'; lastName='Popov'}

Виконаємо Invoke-WebRequest з методом post, помістивши параметри, що передаються у тіло запиту (параметр -Body):

PS С:\Users\andrv> Invoke-WebRequest -Uri http://httpbin.org/post -Method POST
-Body $params
StatusCode
StatusDescription
Content
: 200
: OK
: {
"args": {},
"data": "",
"files": {},
"form": {
"lastName": "Popov",
"name": "Andrey"
},
"headers": {
"Content-Length": "26",
"Content-Type": "application/x-www-form..
RawContent : HTTP/1.1 200 OK
Connection: keep-alive
Access-Control-Allow-Origin: ★
Access-Control-Allow-Credentials: true
Content-Length: 503
Content-Type: application/json
Date: Fri, 16 Jul 2021 03:03:13 GM...
Forms
Headers
: {}
: {[Connection, keep-alive], [Access-Control-Al
low-Origin, *], [Access-Control-Allow-Credent
ials, true], [Content-Length, 503]...}
Images
InputFields
Links
ParsedHtml
RawContentLength
: {}
: {}
: {}
: mshtml.HTMLDocumentClass
: 503

Параметри командлет invoke-webRequest, що надсилаються на сервер, автоматично призводить до формату application/x-www-form-urlencoded, який використовується при передачі даних з веб-форм. Відповідь у полі content говорить про те, що сервер прийняв наші параметри і визначив, що вони були відправлені з форми. Іноді потрібно передавати на сервер дані у форматі JSON, а не в application/x-www-form-urlencoded. У цьому випадку потрібно вказати параметр -contentType зі значенням application/json. Наприклад:

PS С:\Users\andrv> $json_params = "{ 'nameAndrey', ' lastNamePopov' }"
PS C:\Users\andrv> Invoke-WebRequest -Uri http://httpbin.org/post -ContentType
"application/json" -Method POST -Body $json_params
StatusCode : 200
StatusDescription : OK
Content : {
"args": {},
"data": "{ ’name':'Andrey’, 'lastNamePopov
’ Г,
"files": {},
"form": {},
"headers": {
"Content-Length": "39",
"Content-Type": "application/json",
"Host": "...
RawContent : HTTP/1.1 200 OK
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Content-Length: 475
Content-Type: application/json
Date: Fri, 16 Jul 2021 03:43:04 GM...
Forms
Headers
: {}
: {[Connection, keep-alive], [Access-Control-Allo
w-Origin, *], [Access-Control-Allow-Credentials
, true], [Content-Length, 475]...}
Images
InputFields
Links
ParsedHtml
RawContentLength
: И
: {}
: (}
: mshtml.HTMLDocumentClass
: 475

Як бачимо, при такому способі відправки запиту серверний скрипт, що обробляє звернення до ресурсу http://httpbin.org/post, витягнув отримані дані і при формуванні свого JSON-відповіді помістив їх у поле data, а не в полі form. Командлет Invoke-RestMethod якщо ми звертаємося до веб-сервісу, який підтримує REST API, то відповідь сервера швидше за все міститиме структуровані дані у форматі JSON або XML. Так, у попередньому прикладі за допомогою командлета Invoke-WebRequest посилали POST-запит на ресурс http://httpbin.org/post і отримували у відповідь JSON рядок:

post -Method POST -Body @ {name=' Andrey ’ ; lastName= ’ Popov' }
PS C:\Users\andrv> $web.Content
{
"args”: {},
’’data”:
"files": {},
"form": {
"lastName": "Popov",
"name": "Andrey"
},
"headers": {
"Content-Length": "26",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "Mozilla/5.0 (Windows NT; Windows NT 10.0; ru-RU)
WindowsPowerShell/5.1.19041.1023",
"X-Amzn-Trace-Id": "Root=l-60f2a42c-18f152db3b76b5d66dl73e31"
},
"json": null,
"origin": "85.95.179.209",
"url": "http://httpbin.org/post"

Щоб працювати з полями відповіді, ми повинні перетворити JSON на об’єкт PowerShell за допомогою командлета convertFrom-Json (ми розглядали подібні перетворення у розділі 12):

PS С:\Users\andrv> $response = $web.Content | ConvertFrom-Json
PS C:\Users\andrv> $response
args :
data :
files :
form : @{lastName=Popov;name=Andrey}
headers : @{Content-Tength=26; Content-Type=application/x-www-form-urlencoded;
Host-httpbin.org; User-Agent=Mozilla/5.0 (Windows NT; Windows NT 10.0;
ru-RU) Windows PowerShell/5.1.19041.1023;
X-Amzn-Trace-Id=Root=l-60f2a42c-18f152db3b76b5d66dl73e31}
j son :
origin : 85.95.179.209
url : http://httpbin.org/post
PS C:\Users\andrv> $response.form.name
Andrey

У подібних випадках, коли від сервера ми отримуємо структуровані дані, зручніше користуватися командлетом invoke-RestMethod, який діє аналогічно Invoke-WebRequest і має такі ж параметри, але при цьому автоматично перетворює відповідь від сервера в об’єкт PowerShell. Виконаємо наш запит за допомогою invoke-RestMethod, зберігши результат у змінній $result:

PS С:\Users\andrv> $result = Invoke-RestMethod -Uri http://httpbin.org/
post -Method POST -Body @ (name='Andrey' ; lastName=' Popov'}

Проверим тип и содержимое переменной $ result:

PS С:\Users\andrv> Get-Member -Inputobject $result
TypeName: System.Management.Automation.PSCustomObject
uri NoteProperty string url=http://httpbin.org/post
PS C:\Users\andrv> $result
Name MemberType Definition
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
args NoteProperty System.Management.Automation.PSCusto
data NoteProperty string data=
files NoteProperty System.Management.Automation.PSCusto
form NoteProperty System.Management.Automation.PSCusto
headers NoteProperty System.Management.Automation.PSCusto
j son NoteProperty object json=null
origin NoteProperty string origin=85.95.179.209
args :
data :
files :
form : @(lastName=Popov;name=Andrey}
headers : @{Content-Length=26; Content-Type=application/x-www-form-urlencoded;
Host=httpbin.org; User-Agent=Mozilla/5.0 (Windows NT; Windows NT 10.0;
ru-RU) Windows PowerShell/5.1.19041.1023;
X-Amzn-Trace-Id=Root=l-60f2a897-6354ce272644b6d412560a9b}
j son :
origin : 85.95.179.209
uri : http://httpbin.org/post

Як бачимо, замість рядка у форматі JSON ми отримуємо PowerShell-об’єкт типу System.Management.Automation. PSCustomObject І можемо відразу звертатися До потрібних
властивостям:

PS С:\Users\andrv> $result.form.lastName
Popov

Отже, для виконання HTTP-запитів до веб-ресурсів, що повертають HTML-сторінки, зручніше використовувати командлет Invoke-webRequest, а для роботи із зовнішніми REST API, що повертають структуровані дані, краще підійде командлет Invoke-RestMethod.

Підсумки

  • Для звернення до веб-ресурсів за протоколом HTTP у PowerShell є два стандартні командлети: Invoke-webRequest та Invoke-RestMethod.

  • Ці командлети діють аналогічно один одному, за винятком того, що Invoke-RestMethod автоматично перетворює відповідь від сервера на об’єкт PowerShell.

Інші статті по темі
ОсвітаСамонавчання
Читати далі
Частина 4. Знайомимося з PowerShell (Робота в оболонці PowerShell)
Дізнайтесь основні концепції, синтаксис та приклади використання команд та сценаріїв для автоматизації рутинних завдань та захисту даних. Підвищуйте продуктивність та оптимізуйте роботу з системою завдяки PowerShell.
859
ОсвітаСамонавчання
Читати далі
Частина 5. Знайомимося з PowerShell (Робота з об’єктами)
Робота з об'єктами PowerShell - це повний посібник, призначений для навчання користувачів роботі з об'єктами в командній оболонці PowerShell. У цьому посібнику представлені основні концепції та техніки роботи з об'єктами, включаючи створення, зчитування, зміну та видалення даних.
755
ОсвітаСамонавчання
Читати далі
Частина 6. Знайомимося з PowerShell (Управління виведенням команд)
Управління виведенням команд у PowerShell" - детальний посібник, який допоможе вам керувати та оптимізувати виведення результатів команд в PowerShell, забезпечуючи більш ефективну та зручну роботу з цією командною оболонкою.
843
ОсвітаСамонавчання
Читати далі
Частина 8. PowerShell як мова програмування (Оператори та керуючі інструкції)
PowerShell надає детальний огляд різних типів операторів і керуючих інструкцій, які дозволяють програмістам ефективно працювати зі скриптами та автоматизувати рутинні завдання в середовищі Windows.
868
ОсвітаСамонавчання
Читати далі
Частина 10. PowerShell як мова програмування (Обробка помилок при виконанні команд)
Обробка помилок у PowerShell: Забезпечення стабільності та безпеки виконання програм та скриптів. Дізнайтесь про конструкції try-catch та команду -ErrorAction для ефективної обробки помилок у PowerShell та забезпечення надійного функціонування ваших проектів.
726
ОсвітаСамонавчання
Читати далі
Частина 13. Управління процесами, послугами та сервери автоматизації за допомогою PowerShell
У цьому розділі ми розглянемо проблеми, пов'язані із запуском із PowerShell із двома важливими компонентами операційної системи Windows: запущеними процесами та службами, що працюють у фоновому режимі.
931
Знайшли помилку?
Якщо ви знайшли помилку, зробіть скріншот і надішліть його боту.