Powershell прочитать файл json

Обновлено: 04.07.2024

В статье «Начинаем работать с REST и PowerShell», опубликованной в предыдущем номере журнала, мы рассмотрели пример получения данных о высоте уровня воды в реке почти в реальном времени от службы RESTful. Для доступа к службе RESTful использовалась команда Invoke-WebRequest, а из данных, возвращаемых веб-службой в формате XML, с помощью Xpath извлекалось нужное значение. В этой статье будет показано, как с помощью команды Invoke-RestMethod получить необходимые данные от службы геопозиционирования RESTful от Bing, поставляющей данные в формате JavaScript Object Notation (JSON), а не XML.

Служба геопозиционирования Bing преобразует пары «широта-долгота» в адреса и обратно через интерфейс RESTful. Вы можете бесплатно запрашивать Bing до 125 тыс. раз, но только при условии приобретения ключа Bing Maps (для этого необходимо зарегистрироваться со своей учетной записью Microsoft). Ключ выглядит так: P8xPNZEHQTY9fKoDRw0NyOjysoCN3zV-Tbh-AEQBNkRSk8fsPg9916a9gOL7cQ, но в примерах ниже я буду использовать BingKey. По почтовому индексу 12345 запросим город, страну и штат привычным для всех способом, а именно путем ввода универсального кода ресурса (URI) в адресной строке браузера:

В ответ на этот запрос получаем очень длинную строку текста в формате JSON (см. экран 1).

Строка текста в формате JSON
Экран 1. Строка текста в формате JSON

В ней locality, adminDistrict2, adminDistrict и countryRegion означают город, административный округ, штат и страну соответственно. Если заменить 12345 каким-либо другим пятизначным значением, то будет возвращено только название страны, countryRegion (это означает, что Bing не смог найти ответ; очевидно, поиск по почтовому индексу не такая простая задача), или значения соответствующих этому почтовому индексу города, штата и т. д.

Как и в случае с текстом XML, возвращаемая длинная строка в формате JSON — это текстовый способ представления объектов данных. Мы не ставим перед собой задачу изучения синтаксического анализа или создания XML или JSON, но минимальное знакомство с этими форматами может оказаться полезным, поэтому рассмотрим их на примере простого объекта данных (см. рисунок).

Простой объект данных
Рисунок. Простой объект данных

Этот объект я назвал Creatures («Животные»). Животные на данной схеме подразделяются на три категории, каждая из которых имеет атрибут type («Тип»), принимающий значение fish («Рыбы»), amphibians («Земноводные») и mammals («Млекопитающие»). Заметим, что запись type ничего не означает для XML или JSON; это просто слово, которое я выбрал. В рамках классификации Линнея, возможно, больше бы подошел термин Class («Класс»). Каждый тип подразделяется на два подтипа, классифицируемые по типу крови (теплокровные и холоднокровные) и количеству камер сердца. В формате XML эти данные выглядят так, как показано на экране 2.

Данные объекта в формате XML
Экран 2. Данные объекта в формате XML

Сравним это представление с представлением той же классификации животных в формате JSON (см. экран 3).

Данные объекта в формате JSON
Экран 3. Данные объекта в формате JSON

Оба формата справляются с задачей по-разному. После предварительного анализа ясно, что JSON для описания объектов использует фигурные скобки (<>) и массивы в квадратных скобках ([]), элементы которых (в нашем случае — три типа животных) разделены запятыми.

К сожалению, реальные веб-службы выдают данные JSON в виде длинной строки текста, а не удобной для восприятия структуры, показанной в нашем примере. Это может затруднять поиск нужных данных, если не прибегнуть к помощи подключаемого модуля Chrome под названием JSON Formatter (или JSONView — для пользователей Firefox). У Internet Explorer модуль структурной распечатки отсутствует, поэтому я предпочитаю не использовать IE с JSON.

Структурная печать важна, поскольку позволяет получить иерархическое представление, которое помогает извлечь нужные данные. Реализованная в PowerShell поддержка JSON не предусматривает чего-либо, подобного Xpath. Фрагмент структурной распечатки данных, полученных в ответ на запрос по почтовому индексу 12345, показан на экране 4. Здесь хорошо видно, что объект resourceSets содержит объект по имени resources, который содержит объект по имени address, а тот в свою очередь содержит нужные нам объекты adminDistrict (административный округ), adminDistrict2 (штат) и locality (город). Будь это объект PowerShell, мы бы смогли извлечь locality с помощью точечной нотации

Ответ на запрос по почтовому индексу
Экран 4. Ответ на запрос по почтовому индексу

Однако мы имеем дело с объектом JSON, а не PowerShell, и именно здесь нам пригодится команда Invoke-RestMethod, которая, по сути, является дубликатом Invoke-WebRequest, за исключением того, что она ориентирована на объекты JSON и автоматически представляет их в виде объекта PowerShell:

Теперь объекты JSON «живут» в переменной $Result как объекты PowerShell. Для того чтобы вывести искомый город (locality), достаточно ввести

Словом, если выяснится, что веб-служба в ответ на запрос выдает данные в формате JSON, взгляните на структурную распечатку этих данных, чтобы узнать иерархию объекта, а затем с помощью Invoke-RestMethod преобразуйте данные JSON в объект PowerShell и примените точечную нотацию PowerShell для извлечения желаемого элемента.


Оглавление:

Работа с JSON, XML и CSV

В сценариях PowerShell довольно часто приходится разбирать данные в форматах JSON, XML и CSV. Обычно такая необходимость возникает при работе с интернет-сервисами или с конфигурационными файлами. Некоторые администраторы пытаются парсить данные с помощью регулярных выражений, но идти на такие жертвы необязательно: в PowerShell есть специальные командлеты для конвертации, притом в обе стороны.




Обратная задача решается сходным образом:



Для работы с XML и CSV нам потребуются и другие командлеты:


Работа с WMI и CIM

Windows Management Instrumentation (WMI) — это разработанная в Microsoft и адаптированная под Windows реализация стандарта WBEM (Web-Based Enterprise Management). В его основе лежит идея создания универсального решения для мониторинга распределенной информационной среды предприятия и управления ее компонентами. Структура данных WBEM в свою очередь основана на Common Information Model (CIM), реализующей объектно-ориентированный подход к представлению компьютерных систем. Дальнейшая разработка и поддержка WMI в Windows прекращена, Microsoft рекомендует использовать для управления инфраструктурой сходный механизм — объекты CIM. Для работы ними в PowerShell 3.0 появились специальные командлеты, которые мы будем рассматривать параллельно с аналогами для WMI. Если в коде есть вызовы командлетов для работы с WMI, его по возможности стоит переписать.


В рамках модели CIM (она же используется в WMI) данные операционной системы представлены в виде классов со свойствами и методами. Классы группируются в иерархически упорядоченные и логически связанные по технологии или области управления пространства имен. Существует корневое пространство имен Root, в котором имеются подпространства: CIMv2, Default, Secutiry и WMI. Для однозначной идентификации экземпляра класса (объекта) и описания состояния соответствующего ему ресурса используются свойства класса, которые обычно доступны только для чтения. Для управления ресурсом используются методы.

К экземпляру класса можно обратиться по полному пути, который имеет следующий вид:


где
ComputerName — имя компьютера;
NameSpace — пространство имен;
ClassName — имя класса;
KeyProperty1=Value1, KeyProperty2=Value2 — свойства объекта и значения, по которым он идентифицируется.

До появления PowerShell простого инструмента работы с WMI не существовало. Для доступа к объектам приходилось писать довольно сложные программы на высокоуровневых языках (C++, Visual Basic, Java Script) либо изучать оболочку WMIC (WMI Command Line, поддержка которой также прекращена) с собственным языком. Через PowerShell объекты WMI доступны рядовому пользователю из командной строки или в сценариях. Для начала подключимся к подсистеме WMI и получим список доступных классов с помощью командлета Get-WmiObject (псевдоним gwmi). Чтобы получить список классов CIM, используйте командлет Get-CimClass.



Мы вывели список классов на локальном компьютере, но можно подключиться и к удаленному:


По умолчанию командлеты Get-CimClass и Get-WmiObject подключаются к пространству имен Root\CIMV2, в котором хранится большое количество классов для управления системой. Для смены пространства имен применяется параметр -Namespace:


Как и в случае с объектами других типов, список свойств и методов выводится при помощи Get-Member. К методам объекта WMI можно обращаться напрямую или с помощью командлета Invoke-WmiMethod. Также к объектам WMI можно применять командлеты для сортировки, фильтрации, группировки и т.д.



Для получения объектов (экземпляров классов) CIM используется командлет Get-CimInstance. В отличие от WMI, результирующие CIM-объекты (resultant object или экземпляры класса) не содержат методов класса. Поскольку извлечь метод непосредственно невозможно, придется вызывать командлет Invoke-CimMethod. Рассмотрим класс Win32_Service — запущенные в системе службы) и его экземпляр для службы spooler на локальной машине:



Посмотрим на структуру результирующего объекта:



На этом этапе преимущества командлетов для работы с объектами CIM неочевидны. Они в первую очередь касаются удаленной работы в распределенной среде и будут подробно рассмотрены в последней статье цикла, посвященной решению практических задач администрирования.

Есть и специфичный для WMI инструментарий: язык запросов WMI Query Language (WQL), напоминающий SQL. WQL-запрос для поиска всех стартующих при запуске системы служб выглядит так:


Из PowerShell они выполняется следующим образом:



Работа с COM-объектами


Версия обычно не указывается:


Несколько примеров доступных ProgID: InternetExplorer.Application (приложение Internet Explorer), Word.Application (приложение Microsoft Word), WScript.Shell (класс Shell из объектной модели сервера сценариев Windows Script Host или WSH).

Создать экземпляр объекта можно с помощью рассмотренного в предыдущей статье командлета New-Object, а посмотреть его структуру — с помощью Get-Member:



Для работы с объектами используются свойства и методы. Скажем, чтобы создать на рабочем столе пользователя ярлык, нужно вызвать метод CreateShortcut():


Обратите внимание, что ярлык — это тоже объект COM:



Нам остается заполнить его свойства и сохранить:


Таким способом мы создали ярлык на рабочем столе активного пользователя, а теперь разберем работу с внешними сервисами автоматизации на примере COM-объекта Shell.Application. С его помощью можно автоматизировать некоторые действия в проводнике Windows:


или для краткости:



У объекта Shell.Application есть довольно много различных методов управления окнами. К примеру, для отображения содержимого заданного каталога используется Explore():


Справочная система вызывается с помощью метода Help():

Есть также три метода для вызова диалоговых окон поиска: FindFiles(), FindComputer() и FindPrinter().


Открыть диалоговое окно запуска программ можно с помощью метода FileRun(), а для вызова окна установки даты/времени нужен метод SetTime(). Есть, к примеру, методы для вызова окна настройки панели задач, элементов панели управления с указанием одного из доступных файлов cpl, для управления открытыми окнами:


Метод Windows() позволяет получить доступ к коллекции открытых в проводнике или в браузере Internet Explorer окон. Посмотрим доступные для этой коллекции свойства и методы:



Работа со службой каталогов ADSI

Под каталогом в общем случае подразумевается источник информации, в котором хранятся данные о некоторых объектах. Под службой каталога мы понимаем часть распределенной компьютерной системы, позволяющий обращаться к хранящимся объектам и манипулировать ими. Служба каталога может объединять данные об объектах сети и осуществляющих манипуляцию ими сервисов — она представляет собой единую точку входа для взаимодействия с сетевыми ресурсами. В гетерогенной компьютерной сети таких служб может быть множество: локальный диспетчер SAM (Security Account Manager) для не входящих в домен компьютеров, Active Directory и т.д.

Для взаимодействия с разными службами каталогов требуются различные инструменты, что создает определенные неудобства. Начиная с Windows 2000 корпорация Microsoft внедрила в операционные системы унифицированную технологию ADSI (Active Directory Service Interface) для не зависящего от конкретного сетевого протокола доступа. Чтобы находить объекты, для каталога определяется пространство имен. Поскольку разные службы каталогов используют различные способы именования, ADSI определяет позволяющее однозначно идентифицировать любой объект соглашение. Вводится понятие состоящих из двух частей строк связывания (binding string) или ADsPath. Первая часть имени определяет службу каталогов (провайдера ADSI), а вторая — расположение объекта в каталоге. Приведем примеры обозначения разных провайдеров ADSI:

LDAP:// используется для основанной на LDAP службы каталогов, в т.ч. для Active Directory;

WinNT:// используется для локальных компьютеров.


Чтобы работать с локальными учетными записями, придется подключиться к компьютеру с соответствующим именем (для подключения к локальному компьютеру вместо имени достаточно использовать точку):


Для примера создадим на локальной машине нового пользователя Ivanov:


Теперь подключимся к нему:

Форматирование вывода

Интерактивная работа часто требует выводить данные на экран. В других оболочках команды и утилиты сами занимаются форматированием вывода, но возвращаемые функциями и командлетами бинарные объекты обычно не умеют этого делать. В PowerShell вывод форматируют четыре специальных командлета, которым объекты «скармливаются» через конвейер. Более подробные сведения них можно получить с помощью Get-Help:

Format-Table форматирует вывод в виде таблицы, столбцы которой содержат значения свойств объекта или вычисляемые значения. Поддерживается возможность группировки данных;

Format-List выводит объект как список свойств, каждое из которых отображается на новой строке. Поддерживается возможность группировки данных;

Format-Custom форматирует вывод с использованием пользовательского представления;

Format-Wide форматирует объекты в виде широкой таблицы, в которой отображается только одно свойство каждого объекта.

Если ни один из перечисленных командлетов не вызван, применяется соответствующий типу отображаемых данных модуль форматирования. Правила отображения хранятся в конфигурационных файлах в формате XML с расширением .ps1xml, которые находятся в каталоге $PSHome. Их список можно получить с помощью следующей команды:


Редактировать конфигурационные файлы вручную не рекомендуется, лучше создать собственные и включить их в список загружаемых с помощью командлета Update-FormatData. Если модуль форматирования по умолчанию для нужного типа не определен, PowerShell отображает на экране свойства объекта в виде списка.

На этом мы завершим описание работы с объектами в PowerShell, а заключительная статья цикла будет посвящена решению практических задач управления распределенной информационной средой предприятия. В ней нам пригодится весь описанный инструментарий. Основной упор будет сделан на объекты CIM и сравнение их с WMI. Прошлые части можно найти по ссылкам ниже.

Я пытаюсь выполнить цикл ниже JSON в Powershell.

не называя конкретно верхние теги (например, 17443, 17444), поскольку я не знаю их заранее, я не могу найти способ перебирать данные.

Я хочу вывести теги 3, 4 и 5 (название, имя, фамилия) для всех записей.

Как бы я это сделал?

любая помощь ценится

Я могу получить доступ к данным с помощью кода ниже, но хочу избежать указав 17443, 17444, и т. д.

в PowerShell 3.0 и выше (см.: определить установленную версию PowerShell) можно использовать ConvertFrom-Json командлет для преобразования строки JSON в структуру данных PowerShell.

это удобно и неудачно в то же время - удобно, потому что очень легко потреблять JSON, неудачно, потому что ConvertFrom-Json дает PSCustomObjects, и их трудно перебирать как ключевое значение пары.

в этом конкретном JSON ключи кажутся динамическими / неизвестными заранее, например "17443" или "17444" . Это означает, что нам нужно что-то, что может превратить PSCustomObject в список ключевых значений, который foreach могу понять.

теперь мы можем пересечь график объектов и создать список выходных объектов с помощью Title , FirstName и LastName

теперь мы можем сделать очень похожую операцию-даже немного проще, чем выше, потому что JavaScriptSerializer дает вам регулярные словари, которые легко перебирать как пары ключ-значение через GetEnumerator() метод:

если у вас JSON больше 4 МБ, установите JavaScriptSerializer.MaxJsonLength свойства соответственно.

если Вы читаете из файла, используйте Get-Content -Raw -Encoding UTF-8 .

  • ConvertFrom-Json() предоставляет пользовательский объект PowerShell ( PSCustomObject ), который отражает данные в строке JSON.
  • вы можете цикл, хотя свойства пользовательского объекта с Get-Member -type NoteProperty
  • вы можете получить доступ к свойствам объекта динамически с помощью $object."$propName" синтаксис, как вариант $object."$(some PS expression)" .
  • вы можете создать свой собственный объект и инициализировать его с помощью группы свойств с помощью New-Object PSObject -Property @ , либо [PSCustomObject]@ < .. >`

вот простое решение на основе регулярных выражений. Предполагая, что $sRawJson содержит вход JSON:

date

04.12.2018

directory

PowerShell

comments

комментариев 36 Совет. Командлет Invoke-WebRequest доступен в Windows PowerShell 3.0, поэтому перед началом работы убедитесь, что у вас используется эта или более свежая версия. Если на компьютере установлено несколько версий Posh, переключиться между ними можно так.

Использование командлета Invoke-WebRequest

Попробуем выполнить следующую команду:

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

Invoke-WebRequest обработка html страниц в powershell

Совет. Если вы подключены к Интернет через прокси-сервер то для корректной работы командлетов PoweShell, воспользуйтесь советами из статьи: Как настроить PowerShell для доступа через прокси-сервер.

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

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

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

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

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

Как вы видите, веб сервер вернул ответ 200, т.е. запрос выполнен успешно и веб сервер доступен и работает корректно.

Получаем список всех HTML ссылок на странице

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

Чтобы получить и сам текст ссылки (содержится в элементе InnerText), можно воспользоваться такой конструкцией:

Можно выбрать только ссылки с определенным CSS классом:

Или определенным текстом в url:

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

Парсинг HTML страниц с помощью Powershell

Командлет Invoke-WebRequest позволяет довольно быстро и удобно парсить содержимое любых веб-страниц. При обработке HTML страницы из ее содержимого формируются коллекции ссылок (links), веб-форм (forms), изображений (images), скриптов (scripts) и т.д.

С помощью Powershell получим содержимое главной страницы нашего сайта:

$Img = Invoke-WebRequest "https://winitpro.ru/"

Затем выведем список всех изображений на данной странице:

Сформируем коллекцию из полных url путей к используемым изображениям:

$images = $Img.Images | select src

Инициализируем новый экземпляр класса WebClient:

И скачаем все изображения со страницы (с оригинальными именами) в каталог c:\tools\:

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

В качестве интересного примера использования командлета Invoke-WebRequest можно привести способ узнать внешнего IP адреса компьютера из PowerShell.

Аналог wget на powershell: как скачать файл по http

Invoke-WebRequest "https://download.mozilla.org/?product=firefox-32.0.3-SSL&os=win&lang=ru" -outfile “c:\tools\firefox setup 32.0.3.exe”

Таким образом вы с легкостью можете на определенной веб-странице найти все ссылки, попадающие под конкретные критерии (класс ссылки, разрешение в имени файла, url адрес), и скачать файлы по полученным ссылкам. Например, имеется некий сайт с кучей ссылок на PDF документы. Ваша задача скачать все эти файлы на ваш компьютер. Костяк PowerShell скрипта для массовой скачки файлов может выглядеть так:

В результате выполнения скрипта в целевом каталоге будут загружены все pdf файлы со страницы. Каждый файл сохраняется под произвольным именем.

В PowerShell 6.1 команделт Invoke-WebRequest поддерживает режим докачки. Таким образом с помощью параметра Invoke-WebRequest -Uri $Uri -OutFile $OutFile –Resume вы можете возобновить загрузку файла в случае падения канала или сервера.

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

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

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

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

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

Чтобы передать заполненную форму на веб сервер, вызовем атрибут HTML-формы action.

$Log = Invoke-WebRequest -method POST -URI ("https://e.mail.ru/login" + $mailru.Forms["LoginExternal"].Action) -Body $mailru.Forms["LoginExternal"].Fields -WebSession $session

Недостатки командлета Invoke-WebRequest

Другая проблема – командлет Invoke-WebRequest тесно связан с Internet Explorer. Например, в редакциях Windows Server Core, в которых IE не установлен, командлет Invoke-WebRequest использовать нельзя.

Для открытия файлов и чтения его содержимого используется команда Powershell Get-Content. В этой статье рассмотрим работу команды с открытием файла, построчным чтением, поиском по содержимому строки на примерах.

Получение данных

Get - Content - Path 'C:\Windows\System32\drivers\etc\hosts'


Если у вас множество файлов или вы не уверены в назывании, то вы можете использовать подстановку. Символы подстановок бывают следующих типов:

Каждый из символов выше можно применять вместе и неограниченное число раз, в любой части пути и имени.

В этом примере я открою сразу два файла: lmhosts и hosts:


Следующие примеры вернут аналогичный результат:

Get - Content - Path 'C:\Windows\System32\drivers\etc\[l,h]*ost*'

Для похожей фильтрации есть следующие параметры, которые так же позволяют использовать символы подстановок:


Полное и построчное чтение с поиском

По умолчанию, если мы будем передавать результат команды через конвейер Powershell вывод будет построчный. Это может составить проблему, так как при дополнительных условиях у нас будет возвращаться одна строка, а не весь текст:

Get - Content - Path 'C:\file*.txt' | Select - String - Pattern 'Line 8' Get - Content - Path 'C:\file*.txt' - Raw | Select - String - Pattern 'Line 8'


Если вам вдруг понадобится выводить по 2 или более строк за раз, можно указать их количество через ReadCount:

Get - Content - Path 'C:\file*.txt' - ReadCount 2 | Select - String - Pattern 'Line 8'


Разделение файла


$ content = Get - Content - Path 'C:\delimiter.txt' - Delimiter ';'

Подсчет количества строк

Построчный вывод с командой Powershell позволяет посчитать количество строк во всем файле. Для подсчета используется команда Measure-Object:

Если нужна только цифра, а не объект, можно сделать так:


Кодировки

В параметре -Encoding можно указать следующие кодировки:

  • ASCII
  • BigEndianUnicode
  • BigEndianUTF32
  • Byte
  • Default
  • OEM
  • Unicode
  • UTF7
  • UTF8
  • UTF32

Чтения файла под другим пользователем

В этом командлете не предусмотрена возможность открытия файла под другим пользователем. При любых попытках вы будете получать ошибки:

  • Access to the path is denied
  • The FileSystem provider supports credentials only on the New-PSDrive cmdlet. Perform the operation again withoutspecifying credentials.

Для обхода этих ошибок, если у вас нет другого выхода, нужно использовать Invoke-Command (команда удаленного подключения). Для ее настройки могут потребоваться дополнительные настройки описанные в другой статье.

Читайте также: