Создание объектов .NET и COM

Этот пример выполняется только на платформах Windows.

Существуют программные компоненты с интерфейсами платформы .NET Framework и COM, которые позволяют выполнять множество задач системного администрирования. PowerShell позволяет использовать эти компоненты, поэтому вы не ограничиваетесь задачами, которые могут выполняться с помощью командлетов. Многие командлеты в первоначальном выпуске PowerShell не работают на удаленных компьютерах. Мы покажем, как обойти это ограничение при управлении журналами событий с помощью класса платформа .NET Framework System.Diagnostics.EventLog непосредственно из PowerShell.

Использование нового объекта для доступа к журналу событий

Библиотека классов платформы .NET Framework включает класс System.Diagnostics.EventLog, позволяющий управлять журналами событий. Можно создать новый экземпляр класса платформа .NET Framework с помощью командлета с параметром New-Object TypeName. Например, следующая команда создает ссылку на журнал событий:

New-Object -TypeName System.Diagnostics.EventLog
  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----

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

Использование конструкторов с new-Object

Чтобы сослаться на определенный журнал событий, нужно указать его имя. New-Objectимеет параметр ArgumentList. Аргументы, передаваемые в этот параметр, используются специальным методом запуска объекта. Метод вызывается конструктором, так как он используется для создания объекта. Например, чтобы получить ссылку на журнал приложений, нужно указать строку "Application" в качестве аргумента:

New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
Max(K) Retain OverflowAction        Entries Name
------ ------ --------------        ------- ----
16,384      7 OverwriteOlder          2,160 Application

Примечание.

Так как большинство классов .NET содержатся в пространстве имен системы , PowerShell автоматически пытается найти классы, указанные в пространстве имен системы , если он не может найти совпадение с указанным именем типа. Это означает, что вместо этого System.Diagnostics.EventLogможно указатьDiagnostics.EventLog.

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

Вам может понадобиться сохранить ссылку на объект для использования в текущей оболочке. Хотя PowerShell позволяет работать с конвейерами, уменьшая потребность в переменных, иногда хранение ссылок на объекты в переменных упрощает управление этими объектами.

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

$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application

Если вы введите $AppLogего, вы увидите, что он содержит журнал приложений:

$AppLog
  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----
  16,384      7 OverwriteOlder          2,160 Application

Доступ к удаленному журналу событий с помощью New-Object

Команды, используемые в предыдущем разделе, предназначены для локального компьютера; Get-EventLog командлет может сделать это. Чтобы получить доступ к журналу приложений на удаленном компьютере, необходимо в качестве аргументов ввести имя журнала и имя (или IP-адрес) компьютера.

$RemoteAppLog = New-Object -TypeName System.Diagnostics.EventLog Application, 192.168.1.81
$RemoteAppLog
  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----
     512      7 OverwriteOlder            262 Application

Какие действия можно выполнить с переменной $RemoteAppLog после сохранения в ней ссылки на журнал событий?

Очистка журнала событий с помощью методов объекта

Для выполнения тех или иных действий у объектов часто имеются методы. Вы можете использовать Get-Member, чтобы отобразить методы, связанные с объектом. Следующая команда и выбранные выходные данные показывают некоторые методы класса EventLog :

$RemoteAppLog | Get-Member -MemberType Method
   TypeName: System.Diagnostics.EventLog

Name                      MemberType Definition
----                      ---------- ----------
...
Clear                     Method     System.Void Clear()
Close                     Method     System.Void Close()
...
GetType                   Method     System.Type GetType()
...
ModifyOverflowPolicy      Method     System.Void ModifyOverflowPolicy(Overfl...
RegisterDisplayName       Method     System.Void RegisterDisplayName(String ...
...
ToString                  Method     System.String ToString()
WriteEntry                Method     System.Void WriteEntry(String message),...
WriteEvent                Method     System.Void WriteEvent(EventInstance in...

Этот Clear() метод можно использовать для очистки журнала событий. При вызове метода всегда следует следовать имени метода по скобкам, даже если метод не требует аргументов. Это позволяет PowerShell различать метод и потенциальное свойство с тем же именем. Чтобы вызвать метод Clear, нужно ввести следующую команду:

$RemoteAppLog.Clear()
$RemoteAppLog
  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----
     512      7 OverwriteOlder              0 Application

Обратите внимание, что журнал событий был удален и теперь содержит 0 записей вместо 262.

Создание com-объектов с помощью New-Object

Для работы с компонентами объектной модели компонента (COM) можно использовать New-Object . Спектр этих компонентов довольно обширен — от различных библиотек, поставляемых с сервером сценариев Windows (WSH), до приложений ActiveX, например Internet Explorer, установленных на большинстве систем.

New-Objectиспользует платформа .NET Framework вызываемые среды выполнения оболочки для создания COM-объектов, поэтому они имеют те же ограничения, что и платформа .NET Framework при вызове COM-объектов. Чтобы создать СОМ-объект, необходимо задать параметр ComObject для программного идентификатора ProgId нужного класса СОМ-объекта. Полное обсуждение ограничений использования COM и определение доступных progIds в системе выходит за рамки область руководства этого пользователя, но большинство известных объектов из таких сред, как WSH, можно использовать в PowerShell.

Объекты сервера сценариев Windows можно создать, задав следующие программные идентификаторы: WScript.Shell, WScript.Network, Scripting.Dictionary и Scripting.FileSystemObject. Эти объекты создаются следующими командами:

New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObject

Хотя функциональность этих классов в большой степени может быть реализована другими способами в Windows PowerShell, некоторые действия (например создание ярлыков) проще выполнить с помощью классов сервера сценариев Windows.

Создание ярлыка на рабочем столе с помощью WScript.Shell

Одной из функций, быстро выполняемых с помощью СОМ-объектов, является создание ярлыков. Предположим, вы хотите создать ярлык на рабочем столе, который ссылается на домашнюю папку для PowerShell. Сначала необходимо создать ссылку на WScript.Shell, которая будет храниться в переменной с именем $WshShell:

$WshShell = New-Object -ComObject WScript.Shell

Get-Member работает с СОМ-объектами, поэтому элементы объекта можно просмотреть, введя следующее:

$WshShell | Get-Member
   TypeName: System.__ComObject#{41904400-be18-11d3-a28b-00104bd35090}

Name                     MemberType            Definition
----                     ----------            ----------
AppActivate              Method                bool AppActivate (Variant, Va...
CreateShortcut           Method                IDispatch CreateShortcut (str...
...

Get-Member имеет необязательный параметр InputObject , который можно использовать вместо конвейера для предоставления входных данных Get-Member. При использовании команды Get-Member -InputObject $WshShell в примере выше выходные данные были бы такими же. При указании параметра InputObject командлет обрабатывает свои аргументы как одно целое. Это означает, что если у вас есть несколько объектов в переменной, Get-Member они рассматриваются как массив объектов. Например:

$a = 1,2,"three"
Get-Member -InputObject $a
TypeName: System.Object[]
Name               MemberType    Definition
----               ----------    ----------
Count              AliasProperty Count = Length
...

Метод WScript.Shell CreateShortcut допускает использование одного аргумента — пути к создаваемому файлу ярлыка. Можно указать полный путь к рабочему столу, но существует и более простой способ. Рабочий стол обычно представлен папкой с именем Desktop внутри домашней папки текущего пользователя. В Windows PowerShell есть переменная $HOME , содержащая путь к этой папке. Таким образом, путь к домашней папке может быть задан указанием этой переменной, после чего нужно ввести только имя папки Desktop и имя создаваемого ярлыка:

$lnk = $WshShell.CreateShortcut("$HOME\Desktop\PSHome.lnk")

Если вы используете то, что выглядит как имя переменной в двойных кавычках, PowerShell пытается заменить соответствующее значение. Если вы используете одинарные кавычки, PowerShell не пытается заменить значение переменной. Например, попробуйте ввести следующие команды:

"$HOME\Desktop\PSHome.lnk"
C:\Documents and Settings\aka\Desktop\PSHome.lnk
'$HOME\Desktop\PSHome.lnk'
$HOME\Desktop\PSHome.lnk

Теперь у нас есть переменная с именем $lnk , содержащая новую ссылку на ярлык. Если вы хотите просмотреть его члены, вы можете передать Get-Memberего в . Выходные данные (см. ниже) показывают все элементы, необходимые, чтобы завершить создание ярлыка:

$lnk | Get-Member
TypeName: System.__ComObject#{f935dc23-1cf0-11d0-adb9-00c04fd58a0b}
Name             MemberType   Definition
----             ----------   ----------
...
Save             Method       void Save ()
...
TargetPath       Property     string TargetPath () {get} {set}

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

$lnk.TargetPath = $PSHome
$lnk.Save()

Использование Обозреватель Интернета из PowerShell

Многие приложения, включая семейство приложений Microsoft Office и Интернет Обозреватель, можно автоматизировать с помощью COM. В следующих примерах показаны некоторые типичные методы и проблемы, связанные с работой с com-приложениями.

Экземпляр Internet Explorer создается указанием программного идентификатора этого приложения InternetExplorer.Application:

$ie = New-Object -ComObject InternetExplorer.Application

Эта команда запускает интернет-Обозреватель, но не делает его видимым. При вводе Get-Processможно увидеть, что выполняется процесс с именем iexplore . На самом деле, если вы завершите работу PowerShell, процесс продолжится. Для завершения iexplore процесса необходимо перезагрузить компьютер или использовать такой инструмент, как диспетчер задач.

Примечание.

СОМ-объекты, запускаемые в виде отдельных процессов, обычно называются исполняемыми файлами ActiveX. При их запуске окно пользовательского интерфейса отображается не всегда. Если они создают окно, но не делают его видимым, например Интернет Обозреватель, фокус обычно перемещается на рабочий стол Windows. Для взаимодействия с ним необходимо сделать окно видимым.

Введя $ie | Get-Memberтекст, вы можете просматривать свойства и методы для Интернет-Обозреватель. Чтобы просмотреть окно Обозреватель в Интернете, задайте для свойства Visible значение$true, введя следующее:

$ie.Visible = $true

Затем можно перейти к определенному веб-адресу с помощью Navigate метода:

$ie.Navigate("https://devblogs.microsoft.com/scripting/")

С помощью других членов объектной модели Интернета Обозреватель можно получить текстовое содержимое на веб-странице. Следующая команда отображает HTML-текст в тексте текущей веб-страницы:

$ie.Document.Body.InnerText

Чтобы закрыть Internet Explorer из PowerShell, вызовите метод Quit():

$ie.Quit()

Переменная $ie больше не содержит действительную ссылку, хотя все еще отображается как СОМ-объект. Если вы пытаетесь использовать его, PowerShell возвращает ошибку автоматизации:

$ie | Get-Member
Get-Member : Exception retrieving the string representation for property "Appli
cation" : "The object invoked has disconnected from its clients. (Exception fro
m HRESULT: 0x80010108 (RPC_E_DISCONNECTED))"
At line:1 char:16
+ $ie | Get-Member <<<<

Можно удалить оставшуюся ссылку с помощью команды, например $ie = $null, или полностью удалить переменную, введя следующую команду:

Remove-Variable ie

Примечание.

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

Получение предупреждений о платформа .NET Framework-объектах COM

В некоторых случаях COM-объект может иметь связанный платформа .NET Framework вызываемой оболочкой среды выполнения (RCW), которая используетсяNew-Object. Так как поведение RCW может отличаться от поведения обычного COM-объекта, New-Object имеет строгий параметр, чтобы предупредить вас о доступе RCW. Если указать параметр Strict и создать СОМ-объект, использующий оболочку RCW, выводится предупреждение:

$xl = New-Object -ComObject Excel.Application -Strict
New-Object : The object written to the pipeline is an instance of the type "Mic
rosoft.Office.Interop.Excel.ApplicationClass" from the component's primary interop assembly. If
this type exposes different members than the IDispatch members , scripts written to work with this
object might not work if the primary interop assembly isn't installed. At line:1 char:17 + $xl =
New-Object <<<< -ComObject Excel.Application -Strict

Хотя объект по-прежнему создан, вы предупреждаете, что он не является стандартным COM-объектом.