Командная строка и сценарии Windows

Работа в Windows PowerShell с объектными моделями WMI, COM и .NET

Разбить на страницы
Показывать лекцию целиком

Работа в Windows PowerShell с объектными моделями WMI, COM и .NET

Одна из основных задач, для решения которых создавалась оболочка PowerShell, было получение из командной строки доступа к различным объектным инфраструктурам, поддерживаемым операционной системой Windows. Раньше к подобным объектам можно было обращаться либо из полноценных приложений с помощью интерфейса прикладного программирования (API), либо из сценариев WSH. В любом случае для использования внешних объектов приходилось писать программный код и изучать их структуру, что значительно затрудняло работу с ними и препятствовало широкому распространению технологий автоматизации среди системных администраторов и пользователей Windows.

Для решения этой проблемы в PowerShell были разработаны специальные командлеты, позволяющие в интерактивном режиме из оболочки обращаться к объектам WMI, COM и .NET.

Доступ к WMI

В предыдущих лекциях мы уже обращались к объектам WMI из сценариев на языках VBScript и JScript, а также из оболочки WMIC. В PowerShell экземпляры объектов WMI можно получать с помощью командлета Get-WmiObject.

Подключение к подсистеме WMI. Получение списка классов

Для обращения к определенному объекту WMI нужно знать наименование класса, к которому он относится (например, Win32_Process или Win32_Service ). PowerShell позволяет в интерактивном режиме получить список всех классов WMI на локальном или удаленном компьютере. Для этого нужно выполнить командлет Get-WmiObject с параметром List:

PS C:\> Get-WmiObject -List

__SecurityRelatedClass                                      __NTLMUser9X
__PARAMETERS                                                __SystemSecurity
__NotifyStatus                                              __ExtendedStatus
Win32_PrivilegesStatus                                      Win32_TSNetworkAdapterSettingError
Win32_TSRemoteControlSettingError                           Win32_TSEnvironmentSettingError
Win32_TSSessionDirectoryError                               Win32_TSLogonSettingError
Win32_TerminalError                                         Win32_JobObjectStatus
Win32_TerminalServiceSettingError                           Win32_TSPermissionsSettingError
Win32_TSClientSettingError                                  Win32_TSGeneralSettingError
Win32_TSSessionSettingError                                 __SystemClass
. . .

В данном примере выводится список классов WMI на локальном компьютере. Если вам нужно подключиться к подсистеме WMI другой машине, то ее имя или IP-адрес нужно указать в качестве значения параметром ComputerName, например:

PS C:\> Get-WmiObject –ComputerName 10.169.1.15 -List

__SecurityRelatedClass                                      __NTLMUser9X
__PARAMETERS                                                __SystemSecurity
__NotifyStatus                                              __ExtendedStatus
Win32_PrivilegesStatus                                      Win32_TSNetworkAdapterSettingError
Win32_TSRemoteControlSettingError                           Win32_TSEnvironmentSettingError
. . . 
PS C:\> Get-WmiObject –ComputerName Comp1 -List

__SecurityRelatedClass                                      __NTLMUser9X
__PARAMETERS                                                __SystemSecurity
__NotifyStatus                                              __ExtendedStatus
Win32_PrivilegesStatus                                      Win32_TSNetworkAdapterSettingError
Win32_TSRemoteControlSettingError                           Win32_TSEnvironmentSettingError
. . .

По умолчанию командлет Get-WmiObject подключается к пространству имен Root\CIMV2. Сменить это пространство имен позволяет параметр Namespace, в качестве значения которого указывается нужное наименование. Например:

PS C:\> Get-WmiObject -Namespace Root -List

__SecurityRelatedClass                                      __NTLMUser9X
__PARAMETERS                                                __SystemSecurity
__NotifyStatus                                              __ExtendedStatus
__SystemClass                                               __Provider
__Win32Provider                                             __thisNAMESPACE
__IndicationRelated                                         __EventGenerator
. . .

Получение объектов WMI

Зная имя класса WMI, получить экземпляры этого класса очень просто. Например:

PS C:\> Get-WmiObject Win32_Service

ExitCode  : 1077
Name      : Alerter
ProcessId : 0
StartMode : Disabled
State     : Stopped
Status    : OK

ExitCode  : 0
Name      : ALG
ProcessId : 564
StartMode : Manual
State     : Running
Status    : OK
. . .

Данная команда выводит информацию о службах, зарегистрированных в системе. На самом деле объекты класса Win32_Service имеют намного больше свойств, чем по умолчанию отображается на экране; увидеть список всех свойств и методов объекта WMI можно, как и в случае .NET-объектов, с помощью командлета Get-Member:

PS C:\> Get-WmiObject Win32_Service | Get-Member

   TypeName: System.Management.ManagementObject#root\cimv2\Win32_Service

Name                    MemberType   Definition
----                    ----------   ----------
Change                  Method       System.Management.ManagementBaseObject Chang…
ChangeStartMode         Method       System.Management.ManagementBaseObject Chang…
Create                  Method       System.Management.ManagementBaseObject Creat…
InterrogateService      Method       System.Management.ManagementBaseObject Inter…
PauseService            Method       System.Management.ManagementBaseObject Pause…
ResumeService           Method       System.Management.ManagementBaseObject Resum…
StartService            Method       System.Management.ManagementBaseObject Start…
StopService             Method       System.Management.ManagementBaseObject StopS…
UserControlService      Method       System.Management.ManagementBaseObject UserC…
AcceptPause             Property     System.Boolean AcceptPause {get;set;}
AcceptStop              Property     System.Boolean AcceptStop {get;set;}
Caption                 Property     System.String Caption {get;set;}
CheckPoint              Property     System.UInt32 CheckPoint {get;set;}
CreationClassName       Property     System.String CreationClassName {get;set;}
Description             Property     System.String Description {get;set;}
DesktopInteract         Property     System.Boolean DesktopInteract {get;set;}
DisplayName             Property     System.String DisplayName {get;set;}
ErrorControl            Property     System.String ErrorControl {get;set;}
. . .

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

PS C:\> Get-WmiObject Win32_Service | Format-Table Name, 
  AcceptStop

Name                           AcceptStop
----                           ----------
Alerter                             False
ALG                                  True
AppMgmt                             False
aspnet_state                        False
Ati HotKey Poller                   False
AudioSrv                             True
BITS                                 True
Browser                              True
cisvc                               False
ClipSrv                             False
clr_optimization_v2.0.50727_32      False
COMSysApp                           False
CryptSvc                             True
DcomLaunch                          False
Dhcp                                 True
dmadmin                             False
dmserver                            False
Dnscache                             True
ERSvc                                True
. . .

Выполнение WQL-запросов

Параметр Query командлета Get-WmiObject позволяет выполнять произвольные запросы на языке WQL. Например:

PS C:\> Get-WmiObject -Query 'select * from win32_process 
  where name="lsass.exe"'

ProcessName                : lsass.exe
Handles                    : 358
VM                         : 42233856
WS                         : 1511424
Path                       : C:\WINDOWS.1\system32\lsass.exe
__GENUS                    : 2
__CLASS                    : Win32_Process
__SUPERCLASS               : CIM_Process
__DYNASTY                  : CIM_ManagedSystemElement
__RELPATH                  : Win32_Process.Handle="884"
__PROPERTY_COUNT           : 45
. . .

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

В PowerShell имеется командлет New-Object, позволяющий создавать экземпляры внешних COM-объектов (в частности, можно обращаться к знакомым нам объектам WSH, серверам автоматизации из пакета Microsoft Office или браузеру Internet Explorer). Отметим, что "общение" с COM-объектами в оболочке происходит с помощью соответствующих механизмов .NET Framework (создаются экземпляры .NET-класса System.__ComObject ), поэтому на командлет New-Object действуют те же ограничения, какие действуют на платформу .NET во время вызова COM-объектов.

Для создания экземпляра COM-объекта нужно указать его программный идентификатор (ProgID) в качестве значения параметра ComObject, например:

PS C:\> New-Object -ComObject WScript.Shell

SpecialFolders                   CurrentDirectory
--------------                     ----------------
{C:\Documents and Settings\All Users\Рабочий стол, ... 	
  C:\Documents and Settings\User

Перенаправив созданный объект по конвейеру на командлет Get-Member, можно увидеть список всех свойств и методов, имеющихся в COM-объекте:

PS C:\> New-Object -ComObject WScript.Shell | Get-Member

   TypeName: System.__ComObject#{41904400-be18-11d3-a28b-00104bd35090}

Name                     MemberType            Definition
----                     ----------            ----------
AppActivate              Method                bool AppActivate (Variant, Variant)
CreateShortcut           Method                IDispatch CreateShortcut (string)
Exec                     Method                IWshExec Exec (string)
ExpandEnvironmentStrings Method                string ExpandEnvironmentStrings (string)
LogEvent                 Method                bool LogEvent (Variant, string, string)
Popup                    Method                int Popup (string, Variant, Variant, Variant)
RegDelete                Method                void RegDelete (string)
RegRead                  Method                Variant RegRead (string)
RegWrite                 Method                void RegWrite (string, Variant, Variant)
Run                      Method                int Run (string, Variant, Variant)
SendKeys                 Method                void SendKeys (string, Variant)
Environment              ParameterizedProperty IWshEnvironment Environment (Variant) {get}
CurrentDirectory         Property              string CurrentDirectory () {get} {set}
SpecialFolders           Property              IWshCollection SpecialFolders () {get}

Как же теперь воспользоваться методами данного COM-объекта? Для этого удобнее всего сохранить ссылку на объект в переменной, это позволит обращаться к нему в любое время до окончания сеанса работы в PowerShell.

Сохранение объектов в переменных

Оболочка PowerShell поддерживает работу с переменными, которые, по сути, являются именованными объектами. В переменной можно сохранить вывод любой допустимой команды PowerShell. Имена переменных всегда начинаются с знака доллара ( $ ).

Для сохранения в переменной ссылки на COM-объект нужно выполнить следующую команду:

$Shell=New-Object -ComObject WScript.Shell

Убедимся, что в переменной $Shell на самом деле хранится экземпляр COM-объекта с программным идентификатором WScript.Shell:

PS C:\> $Shell | Get-Member

   TypeName: System.__ComObject#{41904400-be18-11d3-a28b-00104bd35090}

Name                     MemberType            Definition
----                     ----------            ----------
AppActivate              Method                bool AppActivate (Variant, Variant)
CreateShortcut           Method                IDispatch CreateShortcut (string)
Exec                     Method                IWshExec Exec (string)
ExpandEnvironmentStrings Method                string ExpandEnvironmentStrings (string)
LogEvent                 Method                bool LogEvent (Variant, string, string)
Popup                    Method                int Popup (string, Variant, Variant, Variant)
RegDelete                Method                void RegDelete (string)
RegRead                  Method                Variant RegRead (string)
RegWrite                 Method                void RegWrite (string, Variant, Variant)
Run                      Method                int Run (string, Variant, Variant)
SendKeys                 Method                void SendKeys (string, Variant)
Environment              ParameterizedProperty IWshEnvironment Environment (Variant) {get}
CurrentDirectory         Property              string CurrentDirectory () {get} {set}
SpecialFolders           Property              IWshCollection SpecialFolders () {get}

Пример: создание ярлыка на рабочем столе

С помощью COM-объекта WScript.Shell можно быстро создавать ярлыки для папок и файлов. Для примера мы создадим на рабочем столе активного пользователя ярлык PSHome.lnk для папки, в которой установлена оболочка PowerShell.

Сначала создадим экземпляр COM-объекта WScript.Shell и сохраним ссылку на него в переменной $Shell:

PS C:\> $Shell = new-object -comobject WScript.Shell

У данного объекта имеется метод CreateShortcut, в качестве параметра которого нужно указывать путь к создаваемому ярлыку. Путь к рабочему столу можно определить разными способами, например, с помощью переменной определенной в PowerShell переменной $Home, в которой хранится путь к личной папке активного пользователя:

PS C:\> $Home
C:\Documents and Settings\User

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

PS C:\> $lnk = $Shell.CreateShortcut("$Home\Рабочий стол\PSHome.lnk")

Здесь нужно учесть, что для получения значения переменной (в нашем случае $Home) ее имя нужно указывать внутри двойных кавычек, а не в одинарных.

Посмотрим, какие свойства и методы имеет объект, сохраненный в переменной $lnk:

PS C:\> $lnk | Get-Member

   TypeName: System.__ComObject#{f935dc23-1cf0-11d0-adb9-00c04fd58a0b}

Name             MemberType Definition
----             ---------- ----------
Load             Method     void Load (string)
Save             Method     void Save ()
Arguments        Property   string Arguments () {get} {set}
Description      Property   string Description () {get} {set}
FullName         Property   string FullName () {get}
Hotkey           Property   string Hotkey () {get} {set}
IconLocation     Property   string IconLocation () {get} {set}
RelativePath     Property    {get} {set}
TargetPath       Property   string TargetPath () {get} {set}
WindowStyle      Property   int WindowStyle () {get} {set}
WorkingDirectory Property   string WorkingDirectory () {get} {set}

Для создания ярлыка на папку достаточно сохранить путь к ней в свойстве TargetPath и вызвать метод Save для сохранения ярлыка. Путь к домашней папке PowerShell хранится в специальной переменной $PSHome, поэтому выполняем следующие команды:

PS C:\> $lnk.TargetPath = $PSHome
PS C:\> $lnk.Save()

Задача решена.

Пример: вывод текста в Microsoft Word

Ранее мы уже рассматривали сценарий WSH на языке VBScript, который управляет приложением Microsoft Word (см. листинг 7.12). Решим аналогичную задачу в PowerShell: запустим из оболочки Microsoft Word и напечатаем в нем строку текста.

Сделать это несложно. Сначала создаем экземпляр главного объекта сервера автоматизации Microsoft Word, который имеет программный идентификатор "Word.Application", и сохраняем ссылку на этот объект в переменной $word::

PS C:\> $word = new-object -comobject Word.Application

Создаем новый документ (метод Add коллекции Documents ) и сохраняем ссылку на документ в переменной $doc:

PS C:\> $doc = $word.Documents.Add()

Делаем окно с новым документом видимым:

PS C:\> $word.Visible = $true

Наконец, печатаем строку текста:

PS C:\> $word.Selection.TypeText("Привет!" )

Использование .NET-объектов. Вызов статических методов

Оболочка PowerShell базируется на платформе .NET и позволяет использовать все ее возможности из командной строки. В частности, тот же командлет New-Object, с помощью которого мы работали с объектами WMI и COM, позволяет создавать экземпляры .NET-объектов. Этой возможностью можно воспользоваться в случае, если для решения определенной задачи не удается найти подходящий командлет PowerShell, но существует .NET-объект, который обладает нужной функциональностью. Например, большинство командлетов PowerShell 1.0 не поддерживают работу с удаленными компьютерами, в частности нельзя управлять журналами событий операционной системы на удаленном компьютере. Однако можно в оболочке создать экземпляр .NET-объекта System.Diagnostics.EventLog, сопоставив его с журналом событий на определенном компьютере и воспользоваться методами этого объекта для очистки журнала или настройки параметров протоколирования событий.

Также в .NET имеются классы, экземпляры которых нельзя создать с помощью командлета New-Object. Такие классы называются статическими, так как они не создаются, не уничтожаются и не меняются. В частности, статическим является класс System.Math, методы которого часто используются для математических вычислений.

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

PS C:\> [System.Math]

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    Math                                     System.Object

Методы статического класса также называются статическими. Для просмотра статических методов класса нужно передать имя этого класса (в квадратных скобках) по конвейеру командлету Get-Member с параметром Static:

PS C:\> [System.Math] | Get-Member -Static

   TypeName: System.Math

Name            MemberType Definition
----            ---------- ----------
Abs             Method     static System.Single Abs(Single value), stati. . .
Acos            Method     static System.Double Acos(Double d)
Asin            Method     static System.Double Asin(Double d)
Atan            Method     static System.Double Atan(Double d)
Atan2           Method     static System.Double Atan2(Double y, Double x. . .
BigMul          Method     static System.Int64 BigMul(Int32 a, Int32 b)
Ceiling         Method     static System.Double Ceiling(Double a), stati. . .
Cos             Method     static System.Double Cos(Double d)
Cosh            Method     static System.Double Cosh(Double value)
DivRem          Method     static System.Int32 DivRem(Int32 a, Int32 b, . . .
Equals          Method     static System.Boolean Equals(Object objA, Obj. . .
Exp             Method     static System.Double Exp(Double d)
Floor           Method     static System.Double Floor(Double d), static. . .
IEEERemainder   Method     static System.Double IEEERemainder(Double x, . . .
Log             Method     static System.Double Log(Double d), static Sy. . .
Log10           Method     static System.Double Log10(Double d)
Max             Method     static System.SByte Max(SByte val1, SByte val. . .
Min             Method     static System.SByte Min(SByte val1, SByte val. . .
Pow             Method     static System.Double Pow(Double x, Double y)
ReferenceEquals Method     static System.Boolean ReferenceEquals(Object. . .
Round           Method     static System.Double Round(Double a), static. . .
Sign            Method     static System.Int32 Sign(SByte value), static. . .
Sin             Method     static System.Double Sin(Double a)
Sinh            Method     static System.Double Sinh(Double value)
Sqrt            Method     static System.Double Sqrt(Double d)
Tan             Method     static System.Double Tan(Double a)
Tanh            Method     static System.Double Tanh(Double value)
Truncate        Method     static System.Decimal Truncate(Decimal d), st. . .
E               Property   static System.Double E {get;}
PI              Property   static System.Double PI {get;}

Как мы видим, методы класса System.Math реализуют различные математические функции, их легко распознать по названию.

Для доступа к определенному статическому методу или свойству используются два идущих подряд двоеточия ( .), как в обычных объектах. Например, для вычисления квадратного корня из числа (статического метода Sqrt ) и сохранения результата в переменную используется следующая конструкция:

PS C:\> $a=[System.Math]::Sqrt(25)
PS C:\> $a
5
Страницы:

Работа в Windows PowerShell с объектными моделями WMI, COM и .NET

Одна из основных задач, для решения которых создавалась оболочка PowerShell, было получение из командной строки доступа к различным объектным инфраструктурам, поддерживаемым операционной системой Windows. Раньше к подобным объектам можно было обращаться либо из полноценных приложений с помощью интерфейса прикладного программирования (API), либо из сценариев WSH. В любом случае для использования внешних объектов приходилось писать программный код и изучать их структуру, что значительно затрудняло работу с ними и препятствовало широкому распространению технологий автоматизации среди системных администраторов и пользователей Windows.

Для решения этой проблемы в PowerShell были разработаны специальные командлеты, позволяющие в интерактивном режиме из оболочки обращаться к объектам WMI, COM и .NET.

Доступ к WMI

В предыдущих лекциях мы уже обращались к объектам WMI из сценариев на языках VBScript и JScript, а также из оболочки WMIC. В PowerShell экземпляры объектов WMI можно получать с помощью командлета Get-WmiObject.

Подключение к подсистеме WMI. Получение списка классов

Для обращения к определенному объекту WMI нужно знать наименование класса, к которому он относится (например, Win32_Process или Win32_Service ). PowerShell позволяет в интерактивном режиме получить список всех классов WMI на локальном или удаленном компьютере. Для этого нужно выполнить командлет Get-WmiObject с параметром List:

PS C:\> Get-WmiObject -List

__SecurityRelatedClass                                      __NTLMUser9X
__PARAMETERS                                                __SystemSecurity
__NotifyStatus                                              __ExtendedStatus
Win32_PrivilegesStatus                                      Win32_TSNetworkAdapterSettingError
Win32_TSRemoteControlSettingError                           Win32_TSEnvironmentSettingError
Win32_TSSessionDirectoryError                               Win32_TSLogonSettingError
Win32_TerminalError                                         Win32_JobObjectStatus
Win32_TerminalServiceSettingError                           Win32_TSPermissionsSettingError
Win32_TSClientSettingError                                  Win32_TSGeneralSettingError
Win32_TSSessionSettingError                                 __SystemClass
. . .

В данном примере выводится список классов WMI на локальном компьютере. Если вам нужно подключиться к подсистеме WMI другой машине, то ее имя или IP-адрес нужно указать в качестве значения параметром ComputerName, например:

PS C:\> Get-WmiObject –ComputerName 10.169.1.15 -List

__SecurityRelatedClass                                      __NTLMUser9X
__PARAMETERS                                                __SystemSecurity
__NotifyStatus                                              __ExtendedStatus
Win32_PrivilegesStatus                                      Win32_TSNetworkAdapterSettingError
Win32_TSRemoteControlSettingError                           Win32_TSEnvironmentSettingError
. . . 
PS C:\> Get-WmiObject –ComputerName Comp1 -List

__SecurityRelatedClass                                      __NTLMUser9X
__PARAMETERS                                                __SystemSecurity
__NotifyStatus                                              __ExtendedStatus
Win32_PrivilegesStatus                                      Win32_TSNetworkAdapterSettingError
Win32_TSRemoteControlSettingError                           Win32_TSEnvironmentSettingError
. . .

По умолчанию командлет Get-WmiObject подключается к пространству имен Root\CIMV2. Сменить это пространство имен позволяет параметр Namespace, в качестве значения которого указывается нужное наименование. Например:

PS C:\> Get-WmiObject -Namespace Root -List

__SecurityRelatedClass                                      __NTLMUser9X
__PARAMETERS                                                __SystemSecurity
__NotifyStatus                                              __ExtendedStatus
__SystemClass                                               __Provider
__Win32Provider                                             __thisNAMESPACE
__IndicationRelated                                         __EventGenerator
. . .

Получение объектов WMI

Зная имя класса WMI, получить экземпляры этого класса очень просто. Например:

PS C:\> Get-WmiObject Win32_Service

ExitCode  : 1077
Name      : Alerter
ProcessId : 0
StartMode : Disabled
State     : Stopped
Status    : OK

ExitCode  : 0
Name      : ALG
ProcessId : 564
StartMode : Manual
State     : Running
Status    : OK
. . .

Данная команда выводит информацию о службах, зарегистрированных в системе. На самом деле объекты класса Win32_Service имеют намного больше свойств, чем по умолчанию отображается на экране; увидеть список всех свойств и методов объекта WMI можно, как и в случае .NET-объектов, с помощью командлета Get-Member:

PS C:\> Get-WmiObject Win32_Service | Get-Member

   TypeName: System.Management.ManagementObject#root\cimv2\Win32_Service

Name                    MemberType   Definition
----                    ----------   ----------
Change                  Method       System.Management.ManagementBaseObject Chang…
ChangeStartMode         Method       System.Management.ManagementBaseObject Chang…
Create                  Method       System.Management.ManagementBaseObject Creat…
InterrogateService      Method       System.Management.ManagementBaseObject Inter…
PauseService            Method       System.Management.ManagementBaseObject Pause…
ResumeService           Method       System.Management.ManagementBaseObject Resum…
StartService            Method       System.Management.ManagementBaseObject Start…
StopService             Method       System.Management.ManagementBaseObject StopS…
UserControlService      Method       System.Management.ManagementBaseObject UserC…
AcceptPause             Property     System.Boolean AcceptPause {get;set;}
AcceptStop              Property     System.Boolean AcceptStop {get;set;}
Caption                 Property     System.String Caption {get;set;}
CheckPoint              Property     System.UInt32 CheckPoint {get;set;}
CreationClassName       Property     System.String CreationClassName {get;set;}
Description             Property     System.String Description {get;set;}
DesktopInteract         Property     System.Boolean DesktopInteract {get;set;}
DisplayName             Property     System.String DisplayName {get;set;}
ErrorControl            Property     System.String ErrorControl {get;set;}
. . .

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

PS C:\> Get-WmiObject Win32_Service | Format-Table Name, 
  AcceptStop

Name                           AcceptStop
----                           ----------
Alerter                             False
ALG                                  True
AppMgmt                             False
aspnet_state                        False
Ati HotKey Poller                   False
AudioSrv                             True
BITS                                 True
Browser                              True
cisvc                               False
ClipSrv                             False
clr_optimization_v2.0.50727_32      False
COMSysApp                           False
CryptSvc                             True
DcomLaunch                          False
Dhcp                                 True
dmadmin                             False
dmserver                            False
Dnscache                             True
ERSvc                                True
. . .

Выполнение WQL-запросов

Параметр Query командлета Get-WmiObject позволяет выполнять произвольные запросы на языке WQL. Например:

PS C:\> Get-WmiObject -Query 'select * from win32_process 
  where name="lsass.exe"'

ProcessName                : lsass.exe
Handles                    : 358
VM                         : 42233856
WS                         : 1511424
Path                       : C:\WINDOWS.1\system32\lsass.exe
__GENUS                    : 2
__CLASS                    : Win32_Process
__SUPERCLASS               : CIM_Process
__DYNASTY                  : CIM_ManagedSystemElement
__RELPATH                  : Win32_Process.Handle="884"
__PROPERTY_COUNT           : 45
. . .

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

В PowerShell имеется командлет New-Object, позволяющий создавать экземпляры внешних COM-объектов (в частности, можно обращаться к знакомым нам объектам WSH, серверам автоматизации из пакета Microsoft Office или браузеру Internet Explorer). Отметим, что "общение" с COM-объектами в оболочке происходит с помощью соответствующих механизмов .NET Framework (создаются экземпляры .NET-класса System.__ComObject ), поэтому на командлет New-Object действуют те же ограничения, какие действуют на платформу .NET во время вызова COM-объектов.

Для создания экземпляра COM-объекта нужно указать его программный идентификатор (ProgID) в качестве значения параметра ComObject, например:

PS C:\> New-Object -ComObject WScript.Shell

SpecialFolders                   CurrentDirectory
--------------                     ----------------
{C:\Documents and Settings\All Users\Рабочий стол, ... 	
  C:\Documents and Settings\User

Перенаправив созданный объект по конвейеру на командлет Get-Member, можно увидеть список всех свойств и методов, имеющихся в COM-объекте:

PS C:\> New-Object -ComObject WScript.Shell | Get-Member

   TypeName: System.__ComObject#{41904400-be18-11d3-a28b-00104bd35090}

Name                     MemberType            Definition
----                     ----------            ----------
AppActivate              Method                bool AppActivate (Variant, Variant)
CreateShortcut           Method                IDispatch CreateShortcut (string)
Exec                     Method                IWshExec Exec (string)
ExpandEnvironmentStrings Method                string ExpandEnvironmentStrings (string)
LogEvent                 Method                bool LogEvent (Variant, string, string)
Popup                    Method                int Popup (string, Variant, Variant, Variant)
RegDelete                Method                void RegDelete (string)
RegRead                  Method                Variant RegRead (string)
RegWrite                 Method                void RegWrite (string, Variant, Variant)
Run                      Method                int Run (string, Variant, Variant)
SendKeys                 Method                void SendKeys (string, Variant)
Environment              ParameterizedProperty IWshEnvironment Environment (Variant) {get}
CurrentDirectory         Property              string CurrentDirectory () {get} {set}
SpecialFolders           Property              IWshCollection SpecialFolders () {get}

Как же теперь воспользоваться методами данного COM-объекта? Для этого удобнее всего сохранить ссылку на объект в переменной, это позволит обращаться к нему в любое время до окончания сеанса работы в PowerShell.

Сохранение объектов в переменных

Оболочка PowerShell поддерживает работу с переменными, которые, по сути, являются именованными объектами. В переменной можно сохранить вывод любой допустимой команды PowerShell. Имена переменных всегда начинаются с знака доллара ( $ ).

Для сохранения в переменной ссылки на COM-объект нужно выполнить следующую команду:

$Shell=New-Object -ComObject WScript.Shell

Убедимся, что в переменной $Shell на самом деле хранится экземпляр COM-объекта с программным идентификатором WScript.Shell:

PS C:\> $Shell | Get-Member

   TypeName: System.__ComObject#{41904400-be18-11d3-a28b-00104bd35090}

Name                     MemberType            Definition
----                     ----------            ----------
AppActivate              Method                bool AppActivate (Variant, Variant)
CreateShortcut           Method                IDispatch CreateShortcut (string)
Exec                     Method                IWshExec Exec (string)
ExpandEnvironmentStrings Method                string ExpandEnvironmentStrings (string)
LogEvent                 Method                bool LogEvent (Variant, string, string)
Popup                    Method                int Popup (string, Variant, Variant, Variant)
RegDelete                Method                void RegDelete (string)
RegRead                  Method                Variant RegRead (string)
RegWrite                 Method                void RegWrite (string, Variant, Variant)
Run                      Method                int Run (string, Variant, Variant)
SendKeys                 Method                void SendKeys (string, Variant)
Environment              ParameterizedProperty IWshEnvironment Environment (Variant) {get}
CurrentDirectory         Property              string CurrentDirectory () {get} {set}
SpecialFolders           Property              IWshCollection SpecialFolders () {get}

Пример: создание ярлыка на рабочем столе

С помощью COM-объекта WScript.Shell можно быстро создавать ярлыки для папок и файлов. Для примера мы создадим на рабочем столе активного пользователя ярлык PSHome.lnk для папки, в которой установлена оболочка PowerShell.

Сначала создадим экземпляр COM-объекта WScript.Shell и сохраним ссылку на него в переменной $Shell:

PS C:\> $Shell = new-object -comobject WScript.Shell

У данного объекта имеется метод CreateShortcut, в качестве параметра которого нужно указывать путь к создаваемому ярлыку. Путь к рабочему столу можно определить разными способами, например, с помощью переменной определенной в PowerShell переменной $Home, в которой хранится путь к личной папке активного пользователя:

PS C:\> $Home
C:\Documents and Settings\User

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

PS C:\> $lnk = $Shell.CreateShortcut("$Home\Рабочий стол\PSHome.lnk")

Здесь нужно учесть, что для получения значения переменной (в нашем случае $Home) ее имя нужно указывать внутри двойных кавычек, а не в одинарных.

Посмотрим, какие свойства и методы имеет объект, сохраненный в переменной $lnk:

PS C:\> $lnk | Get-Member

   TypeName: System.__ComObject#{f935dc23-1cf0-11d0-adb9-00c04fd58a0b}

Name             MemberType Definition
----             ---------- ----------
Load             Method     void Load (string)
Save             Method     void Save ()
Arguments        Property   string Arguments () {get} {set}
Description      Property   string Description () {get} {set}
FullName         Property   string FullName () {get}
Hotkey           Property   string Hotkey () {get} {set}
IconLocation     Property   string IconLocation () {get} {set}
RelativePath     Property    {get} {set}
TargetPath       Property   string TargetPath () {get} {set}
WindowStyle      Property   int WindowStyle () {get} {set}
WorkingDirectory Property   string WorkingDirectory () {get} {set}

Для создания ярлыка на папку достаточно сохранить путь к ней в свойстве TargetPath и вызвать метод Save для сохранения ярлыка. Путь к домашней папке PowerShell хранится в специальной переменной $PSHome, поэтому выполняем следующие команды:

PS C:\> $lnk.TargetPath = $PSHome
PS C:\> $lnk.Save()

Задача решена.

Пример: вывод текста в Microsoft Word

Ранее мы уже рассматривали сценарий WSH на языке VBScript, который управляет приложением Microsoft Word (см. листинг 7.12). Решим аналогичную задачу в PowerShell: запустим из оболочки Microsoft Word и напечатаем в нем строку текста.

Сделать это несложно. Сначала создаем экземпляр главного объекта сервера автоматизации Microsoft Word, который имеет программный идентификатор "Word.Application", и сохраняем ссылку на этот объект в переменной $word::

PS C:\> $word = new-object -comobject Word.Application

Создаем новый документ (метод Add коллекции Documents ) и сохраняем ссылку на документ в переменной $doc:

PS C:\> $doc = $word.Documents.Add()

Делаем окно с новым документом видимым:

PS C:\> $word.Visible = $true

Наконец, печатаем строку текста:

PS C:\> $word.Selection.TypeText("Привет!" )

Использование .NET-объектов. Вызов статических методов

Оболочка PowerShell базируется на платформе .NET и позволяет использовать все ее возможности из командной строки. В частности, тот же командлет New-Object, с помощью которого мы работали с объектами WMI и COM, позволяет создавать экземпляры .NET-объектов. Этой возможностью можно воспользоваться в случае, если для решения определенной задачи не удается найти подходящий командлет PowerShell, но существует .NET-объект, который обладает нужной функциональностью. Например, большинство командлетов PowerShell 1.0 не поддерживают работу с удаленными компьютерами, в частности нельзя управлять журналами событий операционной системы на удаленном компьютере. Однако можно в оболочке создать экземпляр .NET-объекта System.Diagnostics.EventLog, сопоставив его с журналом событий на определенном компьютере и воспользоваться методами этого объекта для очистки журнала или настройки параметров протоколирования событий.

Также в .NET имеются классы, экземпляры которых нельзя создать с помощью командлета New-Object. Такие классы называются статическими, так как они не создаются, не уничтожаются и не меняются. В частности, статическим является класс System.Math, методы которого часто используются для математических вычислений.

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

PS C:\> [System.Math]

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    Math                                     System.Object

Методы статического класса также называются статическими. Для просмотра статических методов класса нужно передать имя этого класса (в квадратных скобках) по конвейеру командлету Get-Member с параметром Static:

PS C:\> [System.Math] | Get-Member -Static

   TypeName: System.Math

Name            MemberType Definition
----            ---------- ----------
Abs             Method     static System.Single Abs(Single value), stati. . .
Acos            Method     static System.Double Acos(Double d)
Asin            Method     static System.Double Asin(Double d)
Atan            Method     static System.Double Atan(Double d)
Atan2           Method     static System.Double Atan2(Double y, Double x. . .
BigMul          Method     static System.Int64 BigMul(Int32 a, Int32 b)
Ceiling         Method     static System.Double Ceiling(Double a), stati. . .
Cos             Method     static System.Double Cos(Double d)
Cosh            Method     static System.Double Cosh(Double value)
DivRem          Method     static System.Int32 DivRem(Int32 a, Int32 b, . . .
Equals          Method     static System.Boolean Equals(Object objA, Obj. . .
Exp             Method     static System.Double Exp(Double d)
Floor           Method     static System.Double Floor(Double d), static. . .
IEEERemainder   Method     static System.Double IEEERemainder(Double x, . . .
Log             Method     static System.Double Log(Double d), static Sy. . .
Log10           Method     static System.Double Log10(Double d)
Max             Method     static System.SByte Max(SByte val1, SByte val. . .
Min             Method     static System.SByte Min(SByte val1, SByte val. . .
Pow             Method     static System.Double Pow(Double x, Double y)
ReferenceEquals Method     static System.Boolean ReferenceEquals(Object. . .
Round           Method     static System.Double Round(Double a), static. . .
Sign            Method     static System.Int32 Sign(SByte value), static. . .
Sin             Method     static System.Double Sin(Double a)
Sinh            Method     static System.Double Sinh(Double value)
Sqrt            Method     static System.Double Sqrt(Double d)
Tan             Method     static System.Double Tan(Double a)
Tanh            Method     static System.Double Tanh(Double value)
Truncate        Method     static System.Decimal Truncate(Decimal d), st. . .
E               Property   static System.Double E {get;}
PI              Property   static System.Double PI {get;}

Как мы видим, методы класса System.Math реализуют различные математические функции, их легко распознать по названию.

Для доступа к определенному статическому методу или свойству используются два идущих подряд двоеточия ( .), как в обычных объектах. Например, для вычисления квадратного корня из числа (статического метода Sqrt ) и сохранения результата в переменную используется следующая конструкция:

PS C:\> $a=[System.Math]::Sqrt(25)
PS C:\> $a
5
Вернуться к учебному плану