Частина 12. Структурована обробка даних за допомогою PowerShell

24.11.2023 4 хвилин Автор: Cyber Witcher

Автоматизація даних з PowerShell: Основні навички та команди

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

В інформаційних системах повсюдно використовуються дані з певною структурою (конфігураційні файли, журнали транзакцій, дані з APls зовнішніх систем і т.д.). PowerShell має вбудовані інструменти для роботи з найпоширенішими форматами цих даних.  У цій статті ви знайдете інформацію про структуровану обробку даних за допомогою PowerShell. Ми детально розглядаємо різні методи та команди PowerShell для роботи з даними, включаючи читання, аналіз, трансформацію та збереження в різних форматах. Ця стаття надасть вам практичні знання та навички, які можна використовувати для підвищення ефективності обробки даних у вашій повсякденній роботі.

Робота з даними CSV

У найпростішому випадку структурований файл містить табличні дані і являє собою набір рядків, що складаються з окремих полів, відокремлених один від одного певним символом. Часто в якості роздільника вибирають кому, тому такі файли і називаються  (Значення, розділені комами, розділені комами).

У першому рядку CSV-файла можуть бути перераховані назви полів, а в інших містяться самі дані. Наприклад:

Name, Lastname, Age
Иван,Петров,22
Сергей,Андреев,34
Оль га,Белова,2 5
Мария,Никитина,41

Розглянемо, як за допомогою PowerShell можна читати та змінювати дані в CSV-файлах.

Читання з CSV-файлу

Для розгляду прикладів створимо в каталозі C:\Script файл test.csv з такими анкетними даними (ім’я, прізвище та вік):

Name, Lastname, Age
Иван,Петров,22
Сергей,Андреев,34
Оль га,Белова,2 5
Мария,Никитина,41

В принципі, вміст, як і будь-який інший текстовий файл, можна прочитати в масив рядків за допомогою командлета Get-Content.

PS C:\Script> $names = Get-Content .\test.csv
PS C:\Script> Get-Member -Inputobject $names
TypeName: System.Object[]
PS C:\Script> $names | Get-Member
TypeName: System.String
. z. .
PS C:\Script> $names
Name,Lastname,Age
Иван,Петров,22
Сергей,Андреев, 34
Оль га,Белова,2 5
Мария,Никитина, 41

Однак командлет Get-Content нічого не знає про внутрішню структуру рядків, тому вам доведеться проаналізувати вміст, щоб витягти його складові частини з рядків.

Тому для розбору структурованих  даних з нього краще використовувати спеціальний командлет Import-Csv, який відразу перетворює дані з файлу в масив об’єктів з потрібними полями.

За допомогою Import-Csv зчитуємо дані з файлу test.csv в змінну $names і виводимо її вміст:

PS C:\Script> $names = Import-Csv -Path .\test.csv
PS C:\Script> $names
Name Lastname Age
Иван Петров 22
Сергей Андреев 34
Ольга Белова 25
Мария Никитина 41

Як бачите, командлет Import-Csv зрозумів, що перший рядок файлу містить заголовок, який визначає структуру кожного рядка. Як і у випадку з Get-Content, змінна $names є масивом об’єктів:

PS C:\Script> Get-Member -Inputobject $names
TypeName: System.Object[]
Name MemberType Definition
Count AliasProperty Count = Length
Add
Address
Method
Method
int IList.Add(System...
System.Objects, msco...

Однак тепер кожен елемент масиву $names є не простим рядком, а об’єктом типу PSCustomObject, який має поля Name, LastName та Ade:

PS C:\Script> $nanes | Get-Member
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Age NoteProperty string Age=22
Lastname NoteProperty string Lastname=neTpoB
Name NoteProperty string Name=HBaH

За допомогою цього масиву ми можемо легко шукати, сортувати або групувати дані за допомогою командлетів, розглянутих у главі 5. Для прикладу відсортуємо записи з нашої таблиці за віком:

PS C:\Script> $names | Sort-Object Age
Name Lastname Age
Иван Петров 22
Ольга Белова 25
Сергей Андреев 34
Мария Никитина 41

Назви полів при імпорті можна змінити за допомогою -Header:

PS C:\Script> Import-Csv -Path .\test.csv -Header 'Имя', 'Фамилия', 'Возраст'
Имя Фамилия Возраст
Name Lastname Age
Иван Петров 22
Сергей Андреев 34
Ольга Белова 25
Мария Никитина 41

За замовчуванням import-csv вважає розділником кому. Якщо у файлі як розділювача використовується інший символ, його потрібно вказати в параметрі -Delimiter. Наприклад, замінимо у файлі test.csv коми на символ крапки з комою:

PS C:\Script> (Get-Content .\test.csv -Raw).Replace(',', ';') | Set-Content
.\test.csv
PS C:\Script> Get-Content .\test.csv
Name;Lastname;Age
Иван;Петров;22
Сергей;Андреев;3 4
Оль га;Белова;2 5
Мария;Никитина;41
Імпортувати такий файл можна наступною командою:
PS C:\Script> Import-Csv -Path .\test.csv -Delimiter
Name Lastname Age
Иван Петров 22
Сергей Андреев 34
Ольга Белова 25
Мария Никитина 41

Запис у файл CSV

За допомогою командлета Export-Csv можна сформувати CSV-файл із масиву об’єктів PowerShell. Наприклад, отримаємо список усіх запущених на локальному комп’ютері служб (статус, ім’я та ім’я, що відображається):

Збережемо цей список у змінній $services:

PS C:\Script> $services = Get-Service | Where-Object Status -eq Running |
Select-Object Status, Name, DisplayName
Експортуємо масив об'єктів $services до CSV-файлу services.csv:
PS C:\Script> $services | Export-Csv -Path .\services.csv

Перевіримо вміст файлу services.csv:

PS C:\Script> Get-Content .\services.csv
#TYPE Selected.System.ServiceProcess.Servicecontroller
"Status","Name","DisplayName"
"Running","AdobeARMservice","Adobe Acrobat Update Service"
"Running","AMD External Events Utility","AMD External Events Utility"
"Running","AMD FUEL Service","AMD FUEL Service"

Як бачите, файл був створений коректно, але в його першому рядку міститься тип об’єктів, з яких він був отриманий (в нашому випадку це об’єкти типу Se1ected). Система. ServiceProcess . ServiceContr011er). Якщо вам не потрібна ця інформація у файлі, вам слід вказати параметр -NoTypeInformation під час виклику Export-Csv:

PS C:\Script> $services | Export-Csv -Path .\services.csv -NoTypeinformation

У цьому випадку перший рядок у файлі міститиме назви полів:

PS C:\Script> Get-Content .\services.csv
"Status","Name","DisplayName"
"Running","AdobeARMservice","Adobe Acrobat Update Service"
"Running","AMD External Events Utility","AMD External Events Utility"
"Running","AMD FUEL Service","AMD FUEL Service"
"Running","Appinfo","Application Information"

Обробка даних без доступу до файлу

PowerShell має командлети ConvertFrom-Csv і ConvertTo-Csv, які працюють подібно до ImportFrom-Csv та ExportTo-Csv, але не мають доступу до зовнішніх файлів.

Для прикладу повторимо наш приклад зі списком запущених сервісів:

PS C:\Script> $services = Get-Service | Where-Object Status -eq Running |
Select-Object Status, Name, DisplayName

Перетворюємо масив об’єктів $services на CSV:

PS C:\Script> $csv = $services | ConvertTo-Csv

У змінній $csv міститься рядок у CSV-форматі:

PS C:\Script> $csv | Get-Member
TypeName: System. String
PS C:\Script> $csv
#TYPE Selected.System.ServiceProcess.Servicecontroller
"Status", "Name","DisplayName"
"Running","AdobeARMservice","Adobe Acrobat Update Service"
"Running","AMD External Events Utility","AMD External Events Utility"
"Running","AMD FUEL Service","AMD FUEL Service"

Тепер конвертуємо рядок $csv у змінну $objs:

PS C:\Script> $objs = $csv | ConvertFrom-Csv

Масив Sobjs міститиме об’єкти типу Selected. System. Serviceprocess. Servicecontroller, який був вказаний у коментарі #type:

PS C:\Script> Get-Mamber -Inputobject $objs
TypeName: System.Object[]
PS C:\Script> $objs | Get-Member
TypeName: CSV:Selected.System.ServiceProcess.Servicecontroller
PS C:\Script> $objs
Status Name DisplayName
Running AdobeARMservice Adobe Acrobat Update Service
Running AMD External Events Utility AMD External EventsUtility
Running AMD FUEL Service AMD FUEL Service

Обробка даних у JSON-форматі

Дані у форматі JSON (JavaScript Object Notation) широко використовуються у веб-розробці, а також для зберігання налаштувань додатків. У PowerShell працювати з JSON МОЖНА З ДОПОМОГЮ командлетів ConvertFrom- Json І ConvertTo-Json. Примітка На відміну від CSV, спеціальних командлетів для імпорту/експорту JSON-файлів у PowerShell немає.

Давайте перетворимо на JSON вміст нашого CSV-файлу C:\Script\test.csv. Для цього ми спочатку імпортуємо цей файл у масив об’єктів PowerShell, а потім конвертуємо цей масив у JSON, передавши його конвеєром командлету convertToJson:

PS C:\Script> Import-Csv -Path .\test.csv
Name Lastname Age
Иван Петров 22
Сергей Андреев 34
Ольга Белова 25
Мария Никитина 41
PS C:\Script> Import-Csv -Path .\test.csv | ConvertTo-Json
[
{
"Name": "Иван",
"Lastname": "Петров",
"Age": "22"
},
"Name": "Сергей",
"Lastname": "Андреев",
"Age": "34"
{
"Name": "Ольга",
"Lastname": "Белова",
"Age": "25"
},
(
"Name": "Мария",
"Lastname": "Никитина",
"Age": "41"
}
]

Переконаємося, що в результаті виходить рядок:

PS C:\Script> $json = Import-Csv -Path .\test.csv | ConvertTo-Json
PS C:\Script> Get-Member -Inputobject $json
TypeName: System.String

За замовчуванням JSON-cTpoka генерується в структурованій формі, зручній для розуміння людиною: вкладені елементи мають відступи, поля розділені розривами рядків. Якщо JSON обробляється автоматично, ви можете використовувати опцію -Compress, щоб усунути непотрібні пробіли та розриви рядків для форматування. У цьому випадку поля і значення записуються послідовно, а JSON-cTpoka буде мати мінімальну довжину:

PS C:\Script> Import-Csv -Path .\test.csv | ConvertTo-Json -Compress
[{"Name":"Иван","Lastname":"Петров","Age":"22"},{"Name":"Сергей","Lastname":
"Андреев","Age":"34"},{"Name":"Ольга","Lastname":"Белова","Age":"25"},{"Name":"
Мария","Lastname":"Никитина","Age":"41"}]

Для створення файлу у форматі JSON отриманий в результаті конвертації рядок потрібно зберегти за допомогою командлетів set-content або Out-File:

PS C:\Script> Inport-Csv -Path .\test.csv | ConvertTo-Json | Set-Content
.\test.json

Зазначимо, що на відміну від експорту в CSV-файл, при конвертації масиву об’єктів у JSON інформація про початковий тип об’єктів втрачається. Для ілюстрації цього знову створимо масив $services, в якому зберігатиметься список запущених на локальному комп’ютері служб:

PS C:\Script> $services = Get-Service | Where-Object Status -eq Running |
Select-Object Status, Name, DisplayName
Елементами цього масиву будуть об'єкти типу Selected.System.Serviceprocess.
Servicecontroller:
PS C:\Script> $services | Get-Member
TypeName: Selected.System.ServiceProcess.Servicecontroller
Перетворимо масив $services в JSON и сохраним результат в переменной $json_
services:
PS C:\Script> $json_services = $services | ConvertTo-Json

Тепер виконаємо зворотне перетворення – конвертуємо рядок $json_services у масив $objs З ДОПОМОГЮ командлета ConvertFrom-Json:

PS C:\Script> $objs = $json_services | ConvertFrom-Json

Перевіримо, який тип мають елементи масиву $objs:

PS С:\Users\andrv> $objs | Get-Member
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
DisplayName NoteProperty string DisplayName=Adobe Acrob
Name NoteProperty string Name=AdobeARMservice
Status NoteProperty int Status=4

Як бачимо, в результаті перетворення з JSON-рядка $json_services створюються об’єкти типу System.Management.Automation.PSCustomObject. Ці об’єкти мають ті ж поля, що були у початкових об’єктів типу Selected. System. Serviceprocess.servicecontroller, проте специфічні методи для керування службами в перетворених з JSON об’єктах будуть недоступні.

Підсумки

  • Для роботи з найбільш поширеними форматами структурованих даних PowerShell використовуються командлети ConvertFrom-*, ConvertTo-*.

  • Читати та змінювати CSV-файли можна за допомогою командлетів import-csv та export-csv.

Підписатися
Сповістити про
0 Коментарі
Найстаріші
Найновіше Найбільше голосів
Інші статті по темі
Знайшли помилку?
Якщо ви знайшли помилку, зробіть скріншот і надішліть його боту.