Главная

Tuesday, 24 May 2016

PowerShell: форматирование в Out-GridView.

Всем привет.

Ох, как же я соскучился по Powershell. Извлечь информацию с помощью Powershell можно любую. Но надо же ее еще и отформатировать красиво, чтобы вы или ваш коллега могли визуально быстро сделать правильный вывод. Или на крайний случай иметь при себе шпаргалку на докладе шефу что "дела наши вот такие". Да и не следует забывать что Powershell по умолчанию выводит только часть информации, хотя может и больше.

Думаю не секрет, что вам как администратору главное умело использовать сортировку выводимой информации (Sort-Object) и ее группирование (Group-Object). Причем можно и нужно использовать оба эти механизма вместе для форматирования выводимой информации. При этом следует помнить - вывод будет разным в зависимости от того кто кому, sort в group или наоборот, передает данные по конвейеру.

Старайтесь форматирование вывода, будь то Format-List или Format-Table и т.п.,  ставить в конце команды! 

Отдельного внимания заслуживает вариант вывода с помощью Out-GridView. Такой вариант появился в 3-й версии Powershell, но получил особое развитие в 4-й. 
Что за зверь? Смотрим.

Самый просто пример команды:
Get-Service | Out-GridView

и мы получаем всплывающую (pop-up)  отдельную форму с выходными данными.


Более того эта табличная форма имеет интерактив. Она позволяет фильтровать полученные данные (пример выше) или отбирать данные по условию. Условие можно собрать на лету.


Здорово, не правда ли? Т.е. начальную аналитику результатов можно провести тут же "у кассы". 


Что же еще можно сделать с помощью Out-GridView?

Рассмотрим команду (в 4-й версии Powershell):

Get-Eventlog System -Newest 250 | Sort Source |
Group EntryType,Source | Out-GridView -OutputMode Single |
Select -ExpandProperty Group |
Format-Table -GroupBy Source -Property TimeGenerated,
Message -Wrap

Команда начинается с извлечения 250 последних записей из журнала системных событий. Элементы сортируются по свойству Source.
>Get-Eventlog System -Newest 250 | Sort Source |

Затем результаты группируются сначала по свойству EntryType,  затем по свойству Source.
>Group EntryType,Source |

Результаты направляются в Out-GridView
>Out-GridView -OutputMode Single |

И все? Нет, дальше начинается самое интересное.

Остальная часть команды выполняется после того, как вы выберите какой-нибудь элемент (строку  в таблице Out-GridView) и нажмете кнопку OK.
Команда разворачивает свойство Group,  которое представляет собой коллекцию элементов журнала событий, и форматирует оставшиеся результаты по новым условиям
>Select -ExpandProperty Group |
Format-Table -GroupBy Source -Property TimeGenerated,
Message -Wrap


Круто? Еще бы!

Там же есть возможность множественного выбора элементов. Просто меняем  -OutputMode Single на -OutputMode Multiple:

Get-Eventlog System -Newest 250 | Sort Source |
Group EntryType,Source | Out-GridView -OutputMode Multiple |
Select -ExpandProperty Group |
Format-Table -GroupBy Source -Property TimeGenerated,
Message -Wrap

И вот, я за один проход уже могу выбрать несколько интересных мне элементов.


Идем дальше? Хором - конечно!)

Меня заинтересовал один момент - я могу отфильтровать данные в Out-GridView на лету, а как же мне сохранить полученный результат? Увы, в последней версии Powershell такой штатной возможности нет. Но кто-то там из MVP на форуме писал что Microsоft уже работает над этим. Поразмыслим над этим и мы со своей стороны.

В Powershell есть возможность выполнить экспорт полученных данных во внешний файл. Например в XML-формат:
Get-Service | Export-CliXML C:\Scripts\Test.xml

Потом также весело, много времени спустя, можно эти данные затянуть обратно импортом для анализа в Out-GridView:
Import-CliXML C:\Scripts\Test.xml | Out-GridView

Фрагмент XML-файла таков:
  <Obj RefId="0">
    <TN RefId="0">
      <T>System.ServiceProcess.ServiceController</T>
      <T>System.ComponentModel.Component</T>
      <T>System.MarshalByRefObject</T>
      <T>System.Object</T>
    </TN>
    <ToString>System.ServiceProcess.ServiceController</ToString>
    <Props>
...
    </Props>
    <MS>
      <S N="Name">XTSvcMgr</S>
      <Ref N="RequiredServices" RefId="1785" />
    </MS>
  </Obj>
</Objs>

Т.е. в XML-файл выводится вся информация из вывода команды, а не стандартный вывод на консоль Powershell. Это очень хорошо.

А можно сделать экспорт вывода в другой формат, более популярный, например CSV ? Оказывается можно:
Get-Service | Export-Csv C:\Scripts\Test.csv

Вот так выглядит CSV-файл от команды get-date:
#TYPE System.DateTime
"DisplayHint","DateTime","Date","Day","DayOfWeek","DayOfYear","Hour","Kind","Millisecond","Minute","Month","Second","Ticks","TimeOfDay","Year"
"DateTime","6 ?????? 2016 ?. 10:48:35","06.04.2016 0:00:00","6","Wednesday","97","10","Local","170","48","4","35","635955365151701139","10:48:35.1701139","2016"

Разумеется также легко он импортируется для Out-GridView:
Import-csv C:\Scripts\Test.csv | Out-GridView

Ну и что в нем такого? -спросите вы. А вот что - теперь я могу взять любые данные, вписать их в CSV-файл и передать такой файл через импорт в Out-GridView. И выполнять нехитрую аналитику уже моих данных на лету в Powershell. Без посторонних инструментов.

Может быть это не совсем то что я хотел получить, но есть над чем работать. 

Успехов вам с Powershell.


4 comments:

  1. Out-GridView есть со второй версии.

    ReplyDelete
  2. Да вы правы, видимо я получил 2-ю версию на ХР без Out-GridView.

    ReplyDelete
  3. подскажите, как форматировать выходные данные в Out-GridView
    например, хочу получить список пользователей в группах домена.
    Import-Module ActiveDirectory
    get-adgroup -filter * -SearchBase "OU=Группы ,DC=domain,DC=local" | foreach {
    $group = Get-AdGroup $_.Name
    Get-ADUser -Filter {MemberOf -recursivematch $group.DistinguishedName}
    } | Out-GridView
    получаю таблицу с данными, НО мне надо еще добавить столбик с данными из $_.Name.
    Как это сделать?

    ReplyDelete
  4. Пробуйте добавить через фильтр новую колонку: ,@{Label='ComputerName';Expression={$_.Name}}

    ReplyDelete

А что вы думаете по этому поводу?