Задачи автоматизации различных операций, выполняемых системными администраторами, существуют со времен появления первых локальных сетей. Для решения этих задач используются разные программные средства, однако самым распространенным является написание сценариев, например, на языке VBScript или Perl. Но в последнее время все большую популярность получает Windows PowerShell, новая командная оболочка Windows, разработанная в первую очередь для системных администраторов. Она включает интерактивную командную строку и среду исполнения сценариев, которые можно использовать вместе или по отдельности. Ранее PowerShell именовался Monad и поставлялся в виде отдельного приложения, но в Windows Server 2008 (который, по официальным данным, выйдет в феврале следующего года) данный инструмент будет установлен по умолчанию. Также стоит отметить, что Powershell будет работать не только на Server 2008, но и на любой системе, где есть .Net 2.0 (Windows XP, Vista, Server 2003). В отличие от большинства оболочек, которые принимают и возвращают текст, оболочка Windows PowerShell, разработанная на основе среды CRL .NET и платформы .NET Framework, принимает и возвращает объекты .NET, а также использует в своей работе только объекты. Это фундаментальное изменение делает возможным применять совершенно новые средства и методы администрирования и конфигурирования систем Windows.
Как и многие другие оболочки, Windows PowerShell обеспечивает доступ к файловой системе на компьютере. Кроме того, в состав оболочки Windows PowerShell входят поставщики, позволяющие столь же легко работать с другими хранилищами данных, такими как реестр и сертификаты цифровых подписей.
Поговорим о том, какие средства предлагает данный инструмент системным администраторам и какие задачи можно решать с его помощью. Большинство оболочек, в том числе знакомая каждому админу Cmd.exe и оболочки SH, KSH, CSH и BASH систем UNIX, выполняют команду или служебную программу в новом процессе и представляют результаты пользователю в виде текста. За время существования этих оболочек были разработаны многие программы обработки текста, поддерживающие этот механизм взаимодействия, такие как sed, AWK и PERL. Некоторые команды встроены в эти оболочки и выполняются в процессе самой оболочки. Примерами могут служить команды typeset и dir в оболочках KSH и Cmd.exe соответственно. В большинстве оболочек встроенных команд немного, поэтому для них создано большое число служебных программ.
Однако Windows PowerShell сильно отличается от других оболочек:
- Windows PowerShell обрабатывает не текст, а объекты платформы .NET. Также PowerShell позволяет напрямую вызывать объекты .Net и таким образом управлять любыми Com ActiveX сущностями.
- Windows PowerShell включает множество встроенных команд, имеющих унифицированный интерфейс. Таких, например, как команды для работы с WMI (Get-WmiObject).
- Все команды оболочки обрабатываются одним синтаксическим анализатором, в то время как во многих других оболочках каждому средству соответствует отдельный анализатор. Это значительно облегчает изучение команд.
- Powershell позволяет запускать унаследованные VBS-сценарии, так что вы без труда сможете использовать уже имеющиеся наработки.
И что самое важное: в оболочке Windows PowerShell можно использовать традиционные средства Windows, такие как Net, SC и Reg.exe. Думаю, всем администраторам приходилось неоднократно сталкиваться с данными средствами, и возможность использовать их в своих сценариях будет также не лишней.
Основные понятия
В PowerShell существует несколько важных понятий. Одно из них это командлет – команда Windows PowerShell, предназначенная для работы с объектами и выполняющая определенные функции.
Командлеты можно идентифицировать по их именам, которые составлены из глагола и существительного, разделенных дефисом (-), например Get-Help, Get-Process и Start-Service. Большинство командлетов Windows PowerShell очень просты, и предполагается, что они будут использоваться вместе с другими командлетами. Например, командлеты категории «get» только возвращают данные, командлеты «set» только задают или изменяют значения элементов данных, командлеты «format» только форматируют данные, а командлеты «out» только направляют вывод в указанное место назначения.
Хотя взаимодействие с оболочкой Windows PowerShell осуществляется при помощи ввода команд в виде текста, оболочка Windows PowerShell основана не на тексте, а на объектах. Выходным элементом любой команды является объект. Объект, полученный на выходе одной команды, можно послать на вход другой команды. В результате оболочка Windows PowerShell позволяет, с одной стороны, администраторам работать с хорошо знакомым интерфейсом командной строки, с другой, использовать мощный функционал работы с объектами. Windows PowerShell расширяет концепцию пересылки данных между командами, позволяя пересылать объекты, а не просто текст, что является порой очень полезным.
Установка
Обсудив основные понятия PowerShell, приступим к установке. Требования к системе достаточно стандартны: Windows XP с пакетом обновлений 2, Windows 2003 с пакетом обновлений 1 или более поздние версии Windows. Также требуется Microsoft .NET Framework 2.0, который можно скачать по адресу [1]. Процесс установки на локальную машину стандартен, необходимо лишь запустить установочный файл. Также авторы PowerShell предусмотрели возможность автоматической установки оболочки. Для этого необходимо запустить файл дистрибутива с параметром /quiet. Например:
PowerShellSetup_x86_enu.exe /quiet
Так что вы можете без труда развернуть оболочку сразу на большом количестве машин. После установки PowerShell вам достаточно набрать в командной строке Windows PowerShell, и вы окажетесь в командной строке данной оболочки. Наберите «help», как видите, PowerShell содержит множество различных команд (см. рис. 1).
Отдельно хотелось бы отметить те команды, которые пришли из мира UNIX. На самом деле эти команды являются только алиасами к реальным командам Power Shell. Сделано это специально для удобства работы администраторов, привыкших к UNIX-среде. Для того чтобы получить список таких алиасов, наберите команду alias (см. рис. 2).
Рисунок 2. Команды PowerShell, пришедшие из UNIX
Строго говоря, это еще не все, при необходимости вы можете создавать свои командлеты (команды), специальные оснастки позволят вам без труда добавить их в оболочку.
Но пока напишем несколько простых сценариев с помощью имеющегося набора команд:
Листинг 1. Получение времени на локальной машине
$strComputer = "."
$colItems = get-wmiobject -class "Win32_UTCTime" -namespace "root\CIMV2" -computername $strComputer
foreach ($objItem in $colItems) {
write-host "Day: " $objItem.Day
write-host "Day Of Week: " $objItem.DayOfWeek
write-host "Hour: " $objItem.Hour
write-host "Milliseconds: " $objItem.Milliseconds
write-host "Minute: " $objItem.Minute
write-host "Month: " $objItem.Month
write-host "Quarter: " $objItem.Quarter
write-host "Second: " $objItem.Second
write-host "Week In Month: " $objItem.WeekInMonth
write-host "Year: " $objItem.Year
write-host
}
Как видите, синтаксис похож на VBScript, так что особых проблем с изучением возникнуть не должно. Сохраняем в текстовом файле с расширением PS1.
Настройка
Однако, если вы сейчас попробуете запустить данный сценарий, то получите сообщение об ошибке. Причиной этому является то, что по умолчанию выполнение сценариев в PowerShell запрещено. Это сделано специально для предотвращения возможных проблем с безопасностью. По умолчанию после установки вам доступно только выполнение команд в интерактивном режиме. Для защиты пользовательских данных и целостности операционной системы в оболочке Windows PowerShell реализованы некоторые средства обеспечения безопасности, в том числе политика выполнения. Политика выполнения определяет, можно ли выполнять сценарии, и если да, должны ли они быть подписаны цифровой подписью. Кроме того, она определяет, можно ли загружать конфигурационные файлы.
Прежде всего посмотрите текущий статус политики выполнения. Сделать это можно с помощью команды:
get-executionpolicy
В случае установки по умолчанию вы должны получить статус Restricted. Для того чтобы сменить этот статус, воспользуйтесь командой:
set-executionpolicy статус_политики
Рассмотрим, какие статусы политики выполнения возможны:
- Restricted – эта политика выполнения по умолчанию. Допускает отдельные команды, но сценарии выполнять нельзя.
- AllSigned – здесь выполнение сценариев разрешено, но необходимо наличие цифровой подписи надежного издателя на всех сценариях и файлах конфигураций, включая сценарии, написанные на локальном компьютере. Также при такой политике запрашивают подтверждение перед выполнением сценариев надежных издателей. Однако при этом существует опасность того, что подписанные, но вредоносные сценарии выполняются.
- RemoteSigned – при таком статусе политики выполнение сценариев также разрешено. Необходимо наличие цифровой подписи надежного издателя на всех сценариях и файлах конфигураций, загруженных из Интернета (включая электронную почту и программы мгновенного обмена сообщениями). Нет необходимости в цифровых подписях на сценариях, запускаемых с локального компьютера. Не запрашивают подтверждения перед выполнением сценариев надежных издателей. Подписанные, но вредоносные сценарии также выполняются.
- Unrestricted – самая демократичная политика, позволяет запускать неподписанные сценарии. Сценарии и файлы конфигурации, загруженные из Интернета (включая Microsoft Outlook, Outlook Express и Windows Messenger), выполняются после предупреждения, что данный файл был загружен из Интернета. Как и следовало ожидать, при таком статусе также возможно выполнение вредоносных сценариев. Думаю, использование данного статуса политики выполнения возможно только на тестовых машинах, так как в реальных сетях это крайне небезопасно.
В зависимости от специфики выполняемых серверами задач я бы рекомендовал использовать RemoteSigned, в случаях, когда выполняются преимущественно сценарии собственного написания, и AllSigned, когда выполняются сценарии, полученные из внешних источников.
Итак, устанавливаем статус политики RemoteSigned:
set-executionpolicy RemoteSigned
Запускаем PS1-файл. Для этого достаточно просто набрать в командной строке PowerShell имя файла. Результатом выполнения сценария будет информация о времени на локальной машине.
Итак, на примере такого незамысловатого сценария мы настроили систему политики выполнения сценариев PowerShell и убедились в работоспособности интерпретатора. Пришло время рассмотреть более сложные, прикладные сценарии.
Мониторинг событий
Начнем с «классики» применения сценариев, а именно с задач мониторинга и сбора статистики. Например, с получения информации обо всех событиях в журнале. Для этого нам необходимо обойти все записи в журнале и получить их свойства:
Листинг 2. Получение информации о события�
$strComputer = "." //Выполняем на локальной машине
$colItems = get-wmiobject -class "Win32_NTLogEvent" -namespace "root\CIMV2" -computername $strComputer
# Обходим все записи в журнале
foreach ($objItem in $colItems) {
# Категория
write-host "Category: " $objItem.Category
# Значение категории
write-host "Category String: " $objItem.CategoryString
# Имя компьютера
write-host "Compute rName: " $objItem.ComputerName
write-host "Data: " $objItem.Data # данные
# Код события
write-host "Event Code: " $objItem.EventCode
# Идентификатор события
write-host "Event Identifier: " $objItem.EventIdentifier
# Тип события
write-host "Event Type: " $objItem.EventType
# Добавленные комментарии (если есть)
write-host "Insertion Strings: " $objItem.InsertionStrings
# Файл журнала
write-host "Logfile: " $objItem.Logfile
# Текст сообщения
write-host "Message: " $objItem.Message
# Номер записи
write-host "Record Number: " $objItem.RecordNumber
# Имя источника
write-host "Source Name: " $objItem.SourceName
# Время создания сообщения
write-host "Time Generated: " $objItem.TimeGenerated
# Время записи
write-host "Time Written: " $objItem.TimeWritten
write-host "Type: " $objItem.Type # Тип
write-host "User: " $objItem.User # Имя пользователя
write-host
}
Как видите, сценарий прост в написании. В репозитории Microsoft [4] вы найдете большое количество сценариев PowerShell, предназначенных для работы с объектами Active Directory, файлами, операционной системой, сетью и т. д. Однако все эти сценарии ориентированы на получение свойств различных объектов и не осуществляют создание каких-либо объектов средствами PowerShell.
Работаем с групповыми политиками
Итак, давайте создадим новый объект групповых политик (GPO), используя Windows PowerShell. Такой сценарий будет иметь следующий вид:
Листинг 3. Создание нового объекта групповой политики
Dim GPM # Объявляем массив GPM
# Объект класса GPMgmt.GPM
Set GPM = CreateObject("GPMgmt.GPM")
# Переменная данного класса
$gpm = New-Object -ComObject GPMgmt.GPM
# Получаем константы данного класса
$gpmConstants = $gpm.GetConstants()
$gpmDomain =$gpm.GetDomain("Mydomain.local", "", $gpmConstants.UseAnyDC)
# Подключаемся к домену, замените Mydomain.local на нужный
# Создаем новую политику
$gpmNewGpo = $gpmDomain.CreateGPO()
# С именем PowerShell GPO
$gpmNewGpo.DisplayName = "PowerShell GPO"
Рассмотрим более подробно данный сценарий, так как в нем отражены преимущества PowerShell. В начале сценария мы создаем экземпляр класса GPMgmt.GPM, который дает доступ к большинству функций GPMC:
$gpm = New-Object -ComObject GPMgmt.GPM
Строка является точкой входа, которая позволяет нам редактировать групповые политики. В этом случае нам нужно создать новый объект групповой политики, для этого мы подключаемся к домену командой:
$gpmDomain =$gpm.GetDomain("Mydomain.local", "", $gpmConstants.UseAnyDC)
И затем, собственно, создается новый объект групповой политики:
$gpmNewGpo = $gpmDomain.CreateGPO()
$gpmNewGpo.DisplayName = "PowerShell GPO"
Теперь, когда вы знаете, как создать объект GPO, давайте откроем существующий объект. Для этого нам придется немного модифицировать уже имеющуюся программу. У вас все еще есть ссылка на домен, $gpmDomain, поэтому добавьте следующее:
Листинг 4. Получение информации о групповой политике
$gpmExistingGpo = $gpmDomain.GetGPO("{31B2F340-016D-11D2-945F-00C04FB984F9}")
# Открываем уже существующую групповую политику, используя ее GUID
$gpmExistingGpo.DisplayName
# Получаем имя данной политики. Сохраняем отчет в файл
$gpmExistingGpo.GenerateReportToFile($gpmConstants.ReportHTML,".\DefaultDomainPolicyReport.html")
Вы получите полный отчет в формате HTML о параметрах политики домена по умолчанию, но вы можете использовать любой из методов и свойств, например, ModificationTime, который сообщит вам, когда объект GPO в последний раз изменялся, чтобы узнать, когда изменялись какие-либо из параметров объекта GPO.
Напишем еще один небольшой сценарий на PowerShell, который предоставит нам сведения об объектах групповой политики, изменявшихся за последние сутки:
Листинг 5. Получение информации об изменениях GPO за последние сутки
$gpmSearchCriteria = $gpm.CreateSearchCriteria()
# Мы хотим получить информацию обо всех групповых политика�
# в домене, поэтому критерий поиска нам вводить не нужно
$gpmAllGpos = $gpmDomain.SearchGPOs($gpmSearchCriteria)
# Ищем все групповые политики в домене
foreach ($gpmGpo in $gpmAllGpos)
{
if ($gpmGpo.ModificationTime -ge (get-date).AddDays(-1)) {$gpmGpo.DisplayName}
# Проверяем, какие групповые политики изменялись за последние 24 часа
}
Обратите внимание на знак операции -ge, означающий «больше или равно». Он может показаться вам странным, если вы привыкли к знакам операций «и» в других языках написания сценариев или программирования. Однако эти знаки операций используются для перенаправления, например, для перенаправления выходных данных в файл, и поэтому не могут использоваться в качестве знаков операций сравнения в Windows PowerShell.
Интересные нововведения
Кроме описанных выше синтаксических конструкций, позволяющих автоматизировать различные задачи системного администрирования, PowerShell обладает также и рядом принципиально новых решений, таких как демонстрации возможных последствий работы сценария. То есть с помощью конструкции -whatif демонстрируется то, что будет сделано, и предсказывается эффект, но никаких изменений в системе и действий над объектами не производится. Приведу пример работы небольшого сценария, в котором рекурсивно обходится папка c:\Program Files, ищет файлы *.ini и пытается их удалить:
> get-childitem “c:\Program Files” -include *.ini -recurse | remove-item –whatif
What if: Performing operation “Remove File” on Target
“C:\Program Files\ABBYY Lingvo 12\LingvoCE\Setup.ini”.
What if: Performing operation “Remove File” on Target
“C:\Program Files\ABBYY Lingvo 12\LingvoPalm\SetupPalm.ini”.
What if: Performing operation “Remove File” on Target
“C:\Program Files\ABBYY Lingvo 12\BITSetup.ini”.
What if: Performing operation “Remove File” on Target
“C:\Program Files\Adobe\Acrobat 7.0\Setup Files\RdrBig709\ENU\0×009.ini”.
What if: Performing operation “Remove File” on Target
“C:\Program Files\Adobe\Acrobat 7.0\Setup Files\RdrBig709\ENU\Abcy.ini”.
В результате работы сценария система сообщает нам о найденных файлах и действиях, которые могли бы быть применены к этим файлам, но сами файлы не удаляются.
Другой пример:
> get-childitem “c:\Program Files” -include *.ini -recurse | remove-item –confirm
Confirm
Are you sure you want to perform this action?
Performing operation “Remove File” on Target
“C:\Program Files\ABBYY Lingvo 12\LingvoCE\Setup.ini”.
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is “Y”):
Здесь вместо -whatif используется команда -confirm. В результате перед выполнением действия на консоль выводится запрос на подтверждение выполнения указанного действия. Стоит отметить, что параметры -whatif и -confirm можно применять практически к любым командам Powershell.
Также хотелось бы сказать несколько слов об объектности интерпретатора PowerShell. Вот, например, поиск процесса по маске notep*:
> get-process notep*
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
——- —— —– —– —– —— — ———–
47 3 1724 3772 33 0,41 236 notepad
47 3 1704 3732 33 0,30 2900 notepad
Все внутри PowerShell – это объекты на примере поиска в памяти процесса notepad и присвоения объекта переменной $prc:
> $prc= get-process notep*
Получаем содержимое объекта $prc:
> $prc*
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
——- —— —– —– —– —— — ———–
47 3 1724 3772 33 0,41 236 notepad
47 3 1704 3732 33 0,30 2900 notepad
К любому атрибуту объекта PowerShell можно обратиться. Возьмем, например, атрибут Id:
> $prc.Id
236
2900
Также стоит обратить внимание на то, что Powershell поддерживает режим автодополнения команд и параметров, как в bash. К примеру, напечатав в командной строке $prc и нажав клавишу <TAB>, получим $prc.Id. При этом автозаполнение действует не только для объектов, но и для параметров команд и путей файловой системы.
Далее рассмотрим свойства объекта и его методы. Знак «|», знакомый администраторам, работавшим с Shell и Perl, в PowerShell передает не просто текст, а настоящие объекты по конвейеру. Причем здесь можно создавать конвейеры любой длины. Например:
> $prc| format-list -property *
__NounName : Process
Name : notepad
Handles : 47
VM : 34541568
WS : 3862528
PM : 1765376
NPM : 2920
…
> $prc| get-member
TypeName: System.Diagnostics.Process
Name MemberType Definition
—- ———- ———-
Handles AliasProperty Handles = Handlecount
Name AliasProperty Name = ProcessName
NPM AliasProperty NPM = NonpagedSystemMemorySize
PM AliasProperty PM = PagedMemorySize
VM AliasProperty VM = VirtualMemorySize
WS AliasProperty WS = WorkingSet
…
Существует также несколько способов уничтожения процесса. Для примера остановим процесс notepad:
> $prc| stop-process
или
> get-process notep* | stop-process
или
> get-process notep* | kill
В результате выполнения любой из этих команд процесс notepad будет закрыт.
Приведу еще несколько примеров работы с конвейерами в PowerShell.
Произведем сортировку объектов по свойству WS (working set) и выбор 5 процессов, занимающих больше всего памяти:
> get-process | sort-object -property WS –descending | select-object -first 5
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
——- —— —– —– —– —— — ———–
605 27 52820 38652 226 476,11 2268 ICQLite
637 24 37692 32380 165 79,25 1716 IEXPLORE
445 17 28676 25672 490 187,44 2588 WINWORD
975 38 44960 20776 350 14,13 3120 OUTLOOK
283 5 26748 20392 136 2,78 1580 powershell
Другая задача – проверить, сколько свободного места есть на дисках, на которые возможна запись:
> gwmi win32_logicaldisk
DeviceID : A:
DriveType : 2
ProviderName :
FreeSpace :
Size :
VolumeName :
DeviceID : C:
DriveType : 3
ProviderName :
FreeSpace : 15472779264
Size : 52427898880
VolumeName :
DeviceID : D:
DriveType : 3
ProviderName :
FreeSpace : 58742120448
Size : 107611336704
VolumeName : Новый том
DeviceID : E:
DriveType : 5
ProviderName :
FreeSpace :
Size :
VolumeName :
Нам нужны диски, на которые можно писать. У них type=3:
> gwmi win32_logicaldisk -filter “drivetype = 3″
DeviceID : C:
DriveType : 3
ProviderName :
FreeSpace : 15472779264
Size : 52427898880
VolumeName :
DeviceID : D:
DriveType : 3
ProviderName :
FreeSpace : 58742120448
Size : 107611336704
VolumeName : Новый том
Затем нужно получить параметры deviceid, freespace:
> gwmi win32_logicaldisk -filter “drivetype = 3″ | select deviceid,freespace
deviceid freespace
——– ———
C: 15472590848
D: 58742120448
Данные выводятся в байтах, что неудобно, поэтому переводим их в гигабайты:
> gwmi win32_logicaldisk -filter “drivetype = 3″ | % { $_.deviceid; $_.freespace/1GB }
C: 14,4099731445313
D: 54,7078628540039
Для примера выберем все файлы, размер которых больше, чем 200 Кб, и отсортируем их в нисходящем порядке:
> Get-ChildItem C:\Windows | Where-Object {$_.Length -gt 200KB} | Sort-Object Length –Descending
Mode LastWriteTime Length Name
—- ————- —— —-
-a— 05.05.2005 4:28 14396416 RTHDCPL.EXE
-a— 04.05.2005 5:16 9697280 RTLCPL.EXE
-a— 04.05.2005 21:01 2805248 ALCWZRD.EXE
-a— 26.10.2007 16:59 2012987 WindowsUpdate.log
-ar– 04.08.2004 16:00 1086058 SET4.tmp
-a— 29.05.2007 15:01 1051257 iis6.log
-ar– 04.08.2004 16:00 1042903 SET3.tmp
-a— 04.08.2004 16:00 1032192 explorer.exe
-a— 16.11.2006 17:22 1030102 setupapi.log.0.old
-a— 17.04.2006 10:54 786065 setuplog.txt
-a— 10.07.2007 11:17 737280 iun6002.exe
-a— 29.05.2007 15:01 708085 FaxSetup.log
—– 17.04.2005 9:20 487424 RtlExUpd.dll
-a— 29.05.2007 15:01 364112 ocgen.log
-a— 22.10.2007 10:58 363933 setupapi.log
-a— 29.05.2007 15:01 336583 tsoc.log
-a— 22.10.2007 15:08 316640 WMSysPr9.prx
-a— 29.10.1998 15:45 306688 IsUninst.exe
-a— 04.08.2004 16:00 283648 winhlp32.exe
-a— 04.08.2004 16:00 256192 winhelp.exe
-a— 29.05.2007 15:01 248705 comsetup.log
-a— 29.05.2007 14:53 239096 msmqinst.log
-a— 18.06.2007 10:38 236773 svcpack.log
Приведу еще один небольшой пример сценария PowerShell, позволяющий получить список всех служб, зарегистрированных на компьютере, а также получить информацию об их статусе. Однако выводится данная информация будет уже не на консоль, а в HTML-файл:
get-service | ConvertTo-Html -Property Name,Status | foreach {
if ($_ -like “*<td>Running</td>*”)
{$_ -replace “<tr>”, “<tr bgcolor=green>”}
else {$_ -replace “<tr>”, “<tr bgcolor=red>”}} > .\get-service.html
Результатом выполнения данного сценария будет HTML-файл, аналогичный изображенному на рис. 3.
Немного о поиске справочной информации
Powershell обладает широкими возможностями по поиску справочной информации, получать которую можно находясь непосредственно в интерпретаторе, с помощью get-help. Вот несколько примеров:
// Получаем справочную информацию по команде get-process
> get-help get-process
// Получаем более детальную информацию по той же команде
> get-help get-process -detailed
// Получаем справочную информацию по командам, работающим с XML
> get-help *xml*
// Аналогичный пример, только для команд, работающих с WMI
> get-help *wmi*
Вместо get-help желающие могут использовать команду man. Таким образом любой специалист, который пришел из мира UNIX, сможет сделать так:
> man get-process
> man get-process -detailed
> man *xml*
Несмотря на то что примеры, которые приведены, работали только с текстовыми данными, это не означает, что Powershell не умеет работать с графикой. Если нам требуется создать и отобразить из скрипта какой-либо графический интерфейс, можно воспользоваться WPF (Windows Presentation Framework), встроенным в .NET.
Следующий скрипт на Powershell создает экранную форму с кнопкой «Push me» (см. рис. 4):
[void][reflection.assembly]::LoadWithPartialName(
“System.Windows.Forms”)
$form = new-object Windows.Forms.Form
$form.Text = “My First Form”
$button = new-object Windows.Forms.Button
$button.text=”Push Me!”
$button.Dock=”fill”
$button.add_click({$form.close()})
$form.controls.add($button)
$form.Add_Shown({$form.Activate()})
$form.ShowDialog()
Автор: Андрей Бирюков
Источник: журнал «Системный администратор»