PowerShell

Nov. 17th, 2007 06:05 pm
[personal profile] soonts
   Мой товарищ [livejournal.com profile] stepancheg, уставший от нестабильной работы новой Mac OS X, в ответ на моё предложение переходить на операционные системы производства Microsoft® посетовал на отсутствие в винде удобного терминала.

   Лично мне нравится шелл cmd.exe, в основном потому что я хорошо умею им пользоваться. Но и утверждать что он лучший в мире и его функциональность достаточна я не собираюсь, потому шо сам при решении несложных повседневных задач частенько использую и его расширения, и другие интерпретируемые языки:
  • Портированные из мира unix утилиты командной строки вроде egrep, sed и wget, но их не всегда достаточно.
  • Скриптовая среда WSH почти 10-летней давности, а именно VBScript, который я выучил и полюбил за годы работы в компании Quest. Но он не подходит для всех задач, например в нём непросто оперировать бинарными данными. Зато COM для него — родная технология, со всеми вытекающими последствиями: ADSI, ADODB, WMI, и прочие радости жизни.
  • Тоже портированные из unix/linux языки perl и python. Они очень хороши как скриптовые языки программирования, но из-за кросс-платформенности недостаточно поддерживают уникальные для windows программные интерфейсы. Зачастую приходится писать нетривиальный код для таких тривиальных вещей, как, например, создать ярлык или написать в windows event log.
   Год назад я пил пиво с корешем, разрабатывающим разнообразное ПО для администрирования windows (привет, Дэн!). И он мне поведал об интерпретаторе командной строки Windows PowerShell, а именно о том, шо что он родной для .NET и поэтому позволяет делать вообще всё. По причине изрядного подпития, я благополучно забыл про эту штуку.

   Однако сегодня, пребывая в подходящем состоянии духа :-), я вспомнил про этот PowerShell и решил выяснить, шо это за фигня.

   Почитал доки, выяснил, что по заверениям microsoft, он и правда умеет вообще всё, умеет работать на любой windows начиная с XP, на которой установлен .NET Framework версии 2.0, и будет поставляться со следующими версиями Windows.

   Зацените табличку "сравнение разных шеллов": по фичам этот PowerShell сопоставим только с интерактивными скриптовыми языками python и ruby, всякие юниксовые шеллы по сравнению с ним в полном пролёте (впрочем, как и мой любимый cmd.exe).

   Скачал на удивление маленький (всего 1.7MB) инсталлятор для 2003-го сервера, поставил. Запустил. Открылось обычное консольное окно, только с другой иконкой и окрашенное в тёмно-синий цвет. В такой же синий цвет я раскрасил приведённые ниже примеры, скопированные из этого консольного окна. Первым делом выяснил, что обе команды help и man работают как и ожидается, то есть делают одно и тоже — отображают справку. Однако число встроенных команд и прочей фигни зашкалило за 300, поэтому я напечатал и прочитал getting started guide. Был впечатлён. Ниже между двумя горизонтальными палочками — вольный перевод куска этого getting started guide из раздела “Введение”.

   Большинство интерпретаторов командной строки, включая как cmd.exe из windows, так и и SH, KSH, CSH, и BASH из мира *nix, работают, исполняя введённую команду или утилиту в новом процессе и отображая результат пользователю в виде текста. На протяжении многих лет эволюционировали разнообразные инструменты для поддержки такого типа взаимодействия, например sed, AWK и perl.
   У таких интерпретаторов часто есть встроенные команды, исполняемые в том же процессе: например, команда typeset в KSH и команда dir в cmd.exe. Из-за недостаточного набора встроенных команд было создано множество дополнительных утилит.

   Windows PowerShell в этом принципиально отличается от предшественников:
  • Windows PowerShell не обрабатывает текст. Вместо текста он обрабатывает объекты, входящие в платформу .NET.
  • Windows PowerShell поставляется с большим набором встроенных команд с однотипным интерфейсом.
  • Все команды используют один и тот же парсер, вместо различных парсеров для каждой утилиты. Поэтому намного проще научиться использовать эти команды
   Но что ещё лучше, Вам не обязательно отказываться от утилит к которым Вы привыкли: Вы можете использовать в PowerShell все традиционные утилиты из Windows, такие как Net, SC, и reg.exe

   Естественно, первым делом я попробовал. Здесь и далее жирным выделено то, что я напечатал.

PS C:\> cmd
Microsoft Windows [Version 5.2.3790]
(C) Copyright 1985-2003 Microsoft Corp.
C:\>echo The good old %COMSPEC%
The good old C:\WINDOWS\system32\cmd.exe
C:\>exit

PS C:\> "The good old " + $env:comspec # The same code for PowerShell. And by the way, "#" sign is reserved for comments.
The good old C:\WINDOWS\system32\cmd.exe

   В power shell локальная файловая система рассматривается как один из нескольких иерархических источников данных. Например, есть ещё реестр:

PS C:\> dir HKLM:\SYSTEM
   Hive: Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM
SKC  VC Name                           Property
---  -- ----                           --------
  4   0 ControlSet002                  {}
  4   0 ControlSet003                  {}
  4   0 ControlSet004                  {}
  1   0 LastKnownGoodRecovery          {}
  0  58 MountedDevices                 {\??\Volume{9d8b3102-65e9-11da-b12a-806e6f6e6963}, \??\Volume{9d8b3103-65e9-1...
  0   4 Select                         {Current, Default, Failed, LastKnownGood}
  2   6 Setup                          {SetupType, SystemSetupInProgress, CmdLine, SystemPrefix...}
  7   0 WPA                            {}
  4   0 CurrentControlSet              {}

   Слэши можно писать в любую сторону.

   Помните, выше было сказано, что PowerShell оперирует не с текстом, а с .NET объектами?
   Вот более сложный пример. where (алиас для встроенной команды Where-Object) фильтрует результат, например по атрибутам. Оператор сравнения -inotmatch означает "не подходит под регулярное выражение". Format-Custom выводит некоторые поля результата.

PS C:\> dir HKLM:/SYSTEM | where {$_.PSChildName -inotmatch "se[lt]" } | Format-Custom -property PSParentPath,PSC
hildName,SubKeyCount,ValueCount

class RegistryKey
{
  PSParentPath = Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM
  PSChildName = LastKnownGoodRecovery
  SubKeyCount = 1
  ValueCount = 0
}

class RegistryKey
{
  PSParentPath = Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM
  PSChildName = MountedDevices
  SubKeyCount = 0
  ValueCount = 58
}

class RegistryKey
{
  PSParentPath = Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM
  PSChildName = WPA
  SubKeyCount = 7
  ValueCount = 0
}
PS C:\>

   Самое замечательное, этот шелл родной для .NET, т.е. почти весь .NET framework доступен без какого-либо промежуточного кода. Например, вот 2 строчки в PowerShell, шоб показать MessageBox (если он Вам зачем-то понадобился) из windows forms:

PS C:\> [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

GAC    Version        Location
---    -------        --------
True   v2.0.50727     C:\WINDOWS\assembly\GAC_MSIL\System.Windows.Forms\2.0.0.0__b77a5c561934e089\System.Windows.For...

PS C:\> [System.Windows.Forms.MessageBox]::Show("Welcome to the .NET World!")
OK
PS C:\>

   Но ещё он родной для COM, как и VBScript. Например, вот две строчки, использующие COM объект "WScript.Shell" для отображения аналогичного MessageBox:

PS C:\> $sh = New-Object -comobject WScript.Shell
PS C:\> $sh.Popup("And COM is OK, too.")
1
PS C:\>

   Обращаю Ваше внимание, что приведённые выше примеры я написал не заглядывая во внешний хелп, за исключением документации в MSDN по объектам System.Windows.Forms.MessageBox и WScript.Shell:

PS C:\> man where

NAME
    Where-Object

SYNOPSIS
    Creates a filter that controls which objects will be passed along a command pipeline.


SYNTAX
    Where-Object [-filterScript]  [-inputObject ] []


DETAILED DESCRIPTION
    Creates a filter that controls which objects will be passed along a command pipeline. It filters objects passed to
    it as pipelined input or objects provided as the value of the InputObject parameter. It determines which objects to
     pass along the pipeline by evaluating a script block that may include a reference to an object being filtered. If
    the result of the evaluation is True, the object being processed is passed along the pipeline; otherwise, the objec
    t is discarded.


RELATED LINKS
    Select-Object
    about_where
    about_regular_expression

REMARKS
    For more information, type: "get-help Where-Object -detailed".
    For technical information, type: "get-help Where-Object -full".

PS C:\> man about_where

about_where

SHORT DESCRIPTION
    Filter objects based on object properties

LONG DESCRIPTION

    You use the where statement in a command pipeline to
    return a subset of the objects returned by the previous command. The
    where statement accepts an argument that specifies a filter based on
    the objects' properties that is applied to determine whether a given
    object should be passed down the pipeline.
   Дальше ещё пара страниц текста про операторы и синтакс.

   В общем, по-ходу PowerShell это исключительно удобный инструмент, к тому же очень простой в освоении — при условии что Вы умеете читать, писать и программировать на любом языке высокого уровня. Если есть под рукой Windows XP или выше — очень рекомендую заценить.

Date: 2007-11-17 03:16 pm (UTC)
From: [identity profile] freetiger.livejournal.com
powercmd охуенский

July 2017

S M T W T F S
      1
2345678
9101112131415
16171819202122
23242526272829
3031     

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Oct. 19th, 2017 09:52 pm
Powered by Dreamwidth Studios