Erstellen von .NET- und COM-Objekten
Dieses Beispiel kann nur auf Windows-Plattformen ausgeführt werden.
Es gibt Softwarekomponenten mit .NET Framework- und COM-Schnittstellen, mit denen Sie viele Systemverwaltungsaufgaben ausführen können. Mit PowerShell können Sie diese Komponenten verwenden und sind somit nicht auf die Aufgaben beschränkt, die mithilfe von Cmdlets ausgeführt werden können. Viele der Cmdlets im ursprünglichen Release von PowerShell funktionieren nicht auf Remotecomputern. Wir zeigen, wie diese Einschränkung beim Verwalten von Ereignisprotokollen mithilfe der .NET Framework-Klasse System.Diagnostics.EventLog direkt aus PowerShell heraus umgangen werden können.
Verwenden von „New-Object“ für den Zugriff auf das Ereignisprotokoll
Die .NET Framework-Klassenbibliothek enthält eine Klasse namens System.Diagnostics.EventLog, die zum Verwalten von Ereignisprotokollen verwendet werden kann. Zum Erstellen einer neuen Instanz einer .NET Framework-Klasse können Sie das Cmdlet New-Object
mit dem Parameter TypeName verwenden. Der folgende Befehl erstellt z. B. einen Ereignisprotokollverweis:
New-Object -TypeName System.Diagnostics.EventLog
Max(K) Retain OverflowAction Entries Name
------ ------ -------------- ------- ----
Obwohl der Befehl eine Instanz der EventLog-Klasse erstellt hat, enthält die Instanz keine Daten. Der Grund hierfür ist, dass Sie kein bestimmtes Ereignisprotokoll angegeben haben. Wie erhalten Sie ein echtes Ereignisprotokoll?
Verwenden von Konstruktoren mit „New-Object“
Um auf ein bestimmtes Ereignisprotokoll zu verweisen, müssen Sie den Namen des Protokolls angeben. New-Object
verfügt über einen ArgumentList-Parameter. Die Argumente, die Sie als Werte an diesen Parameter übergeben, werden von einer speziellen Startmethode des Objekts verwendet. Die Methode wird als Konstruktor bezeichnet, da sie zum Konstruieren des Objekts dient. Um beispielsweise einen Verweis auf das Anwendungsprotokoll zu erhalten, geben Sie die Zeichenfolge „Application“ als Argument ein:
New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
Max(K) Retain OverflowAction Entries Name
------ ------ -------------- ------- ----
16,384 7 OverwriteOlder 2,160 Application
Hinweis
Da die meisten .NET-Klassen im System-Namespace enthalten sind, versucht PowerShell automatisch, Klassen zu finden, die Sie im System-Namespace angeben, wenn keine Übereinstimmung für den angegebenen Typnamen gefunden wird. Dies bedeutet, dass Sie Diagnostics.EventLog
anstelle von System.Diagnostics.EventLog
angeben können.
Speichern von Objekten in Variablen
Möglicherweise möchten Sie einen Verweis auf ein Objekt speichern, damit Sie es in der aktuellen Shell verwenden können. Obwohl PowerShell Ihnen ermöglicht, viele Aufgaben mit Pipelines zu erledigen und damit die Notwendigkeit von Variablen zu verringern, vereinfacht das Speichern von Verweisen auf Objekte in Variablen manchmal die Bearbeitung dieser Objekte.
Die Ausgabe eines beliebigen gültigen PowerShell-Befehls kann in einer Variable gespeichert werden. Variablennamen beginnen immer mit $
. Wenn Sie den Verweis auf ein Anwendungsprotokoll in einer Variable namens $AppLog
speichern möchten, geben Sie den Namen der Variable an, gefolgt von einem Gleichheitszeichen und dem Befehl zum Erstellen des Anwendungsprotokollobjekts:
$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
Wenn Sie dann $AppLog
eingeben, sehen Sie, dass es das Anwendungsprotokoll enthält:
$AppLog
Max(K) Retain OverflowAction Entries Name
------ ------ -------------- ------- ----
16,384 7 OverwriteOlder 2,160 Application
Zugreifen auf ein Remoteereignisprotokoll mit „New-Object“
Die im vorherigen Abschnitt verwendeten Befehle hatten den lokalen Computer als Ziel. Dazu kann auch das Cmdlet Get-EventLog
verwendet werden. Um auf das Anwendungsprotokoll auf einem Remotecomputer zuzugreifen, müssen Sie sowohl den Namen des Protokolls als auch einen Computernamen (oder eine IP-Adresse) als Argumente bereitstellen.
$RemoteAppLog = New-Object -TypeName System.Diagnostics.EventLog Application, 192.168.1.81
$RemoteAppLog
Max(K) Retain OverflowAction Entries Name
------ ------ -------------- ------- ----
512 7 OverwriteOlder 262 Application
Welche Aufgaben können Sie jetzt mit dem Verweis auf ein in der Variablen $RemoteAppLog
gespeichertes Ereignisprotokoll ausführen?
Löschen eines Ereignisprotokolls mit Objektmethoden
Objekte verfügen oft über Methoden, die aufgerufen werden können, um Aufgaben auszuführen. Sie können Get-Member
verwenden, um die einem Objekt zugeordneten Methoden anzuzeigen. Mit dem folgenden Befehl und der ausgewählten Ausgabe werden einige der Methoden der EventLog-Klasse angezeigt:
$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...
Die Clear()
-Methode kann zum Löschen des Ereignisprotokolls verwendet werden. Beim Aufrufen einer Methode müssen dem Methodennamen immer Klammern folgen, auch wenn die Methode keine Argumente erfordert. So kann PowerShell zwischen der Methode und einer möglichen Eigenschaft mit gleichem Namen unterscheiden. Geben Sie Folgendes ein, um die Methode Clear aufzurufen:
$RemoteAppLog.Clear()
$RemoteAppLog
Max(K) Retain OverflowAction Entries Name
------ ------ -------------- ------- ----
512 7 OverwriteOlder 0 Application
Beachten Sie, dass das Ereignisprotokoll gelöscht wurde und jetzt statt 262 Einträgen 0 Einträge enthält.
Erstellen von COM-Objekten mit „New-Object“
Sie können New-Object
verwenden, um mit Component Object Model-Komponenten (COM) zu arbeiten. Die Komponenten reichen von den verschiedenen in Windows Script Host (WSH) enthaltenen Bibliotheken bis hin zu ActiveX-Anwendungen wie Internet Explorer, die auf den meisten Systemen installiert sind.
New-Object
verwendet zum Erstellen von COM-Objekten .NET Framework Runtime Callable Wrapper, es gelten somit die gleichen Einschränkungen wie für .NET Framework beim Aufrufen von COM-Objekten. Zum Erstellen eines COM-Objekts müssen Sie den Parameter ComObject mit dem programmatischen Bezeichner bzw. der ProgId der COM-Klasse angeben, die Sie verwenden möchten. Eine vollständige Erläuterung der Einschränkungen der COM-Verwendung und Informationen zu den auf einem System verfügbaren ProgIds würden über den Rahmen dieses Leitfadens hinaus gehen, aber die meisten bekannten Objekte aus Umgebungen wie WSH können in PowerShell verwendet werden.
Sie können die WSH-Objekte erstellen, indem Sie diese ProgIDs angeben: WScript.Shell, WScript.Network, Scripting.Dictionary und Scripting.FileSystemObject. Mit den folgenden Befehlen werden diese Objekte erstellt:
New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObject
Die meisten Funktionen dieser Klassen werden zwar auch auf andere Weise in Windows PowerShell bereitgestellt, aber einige Aufgaben wie das Erstellen einer Verknüpfung lassen sich mit den WSH-Klassen einfacher erledigen.
Erstellen einer Desktopverknüpfung mit „WScript.Shell“
Eine Aufgabe, die mit einem COM-Objekt schnell und einfach ausgeführt werden kann, ist das Erstellen einer Verknüpfung. Angenommen, Sie möchten auf dem Desktop eine Verknüpfung zum Basisordner für PowerShell erstellen. Zuerst müssen Sie einen Verweis auf WScript.Shell erstellen, den wir in einer Variablen namens $WshShell
speichern:
$WshShell = New-Object -ComObject WScript.Shell
Get-Member
funktioniert mit COM-Objekten, sodass Sie die Member des Objekts untersuchen können, indem Sie Folgendes eingeben:
$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
verfügt über einen optionalen InputObject-Parameter, den Sie anstelle von Piping als Eingabe für Get-Member
verwenden können. Dieselbe Ausgabe wie oben hätten Sie auch über den Befehl Get-Member -InputObject $WshShell erhalten. Wenn Sie InputObject verwenden, wird das Argument als ein einzelnes Element behandelt. Dies bedeutet, dass bei mehreren Objekte in einer Variablen diese von Get-Member
als ein Array von Objekten behandelt werden. Beispiel:
$a = 1,2,"three"
Get-Member -InputObject $a
TypeName: System.Object[]
Name MemberType Definition
---- ---------- ----------
Count AliasProperty Count = Length
...
Die Methode WScript.Shell CreateShortcut akzeptiert ein einziges Argument, und zwar, den Pfad zur zu erstellenden Verknüpfungsdatei. Wir könnten den vollständigen Pfad zum Desktop eingeben, aber es gibt einen einfacheren Weg. Der Desktop wird normalerweise durch einen Ordner namens „Desktop“ im Basisordner des aktuellen Benutzers dargestellt. Windows PowerShell verfügt über eine Variable $HOME
, die den Pfad zu diesem Ordner enthält. Sie können den Pfad zum Basisordner mithilfe dieser Variablen angeben und dann den Namen des Ordners „Desktop“ sowie den Namen für die zu erstellende Verknüpfung hinzufügen. Geben Sie dazu Folgendes ein:
$lnk = $WshShell.CreateShortcut("$HOME\Desktop\PSHome.lnk")
Wenn Sie ein Element, das wie ein Variablenname aussieht, in doppelten Anführungszeichen angeben, versucht PowerShell, dieses Element durch einen entsprechenden Wert zu ersetzen. Wenn Sie einzelne Anführungszeichen verwenden, versucht PowerShell nicht, den Variablenwert zu ersetzen. Geben Sie beispielsweise die folgenden Befehle ein:
"$HOME\Desktop\PSHome.lnk"
C:\Documents and Settings\aka\Desktop\PSHome.lnk
'$HOME\Desktop\PSHome.lnk'
$HOME\Desktop\PSHome.lnk
Wir verfügen jetzt über eine Variable namens $lnk
, die einen neuen Verknüpfungsverweis enthält. Wenn Sie die zugehörigen Elemente anzeigen möchten, können Sie sie über die Pipeline an Get-Member
übergeben. In der folgenden Ausgabe werden die zum Abschließen der Erstellung unserer Verknüpfung zu verwendenden Elemente angezeigt:
$lnk | Get-Member
TypeName: System.__ComObject#{f935dc23-1cf0-11d0-adb9-00c04fd58a0b}
Name MemberType Definition
---- ---------- ----------
...
Save Method void Save ()
...
TargetPath Property string TargetPath () {get} {set}
Sie müssen den TargetPath angeben, d. h. den Anwendungsordner für PowerShell, und dann die Verknüpfung durch Aufrufen der Save
-Methode speichern. Der Pfad des PowerShell-Anwendungsordners ist in der $PSHome
-Variable gespeichert, also geben Sie Folgendes ein:
$lnk.TargetPath = $PSHome
$lnk.Save()
Verwenden von Internet Explorer in PowerShell
Viele Anwendungen (einschließlich Microsoft Office-Anwendungen und Internet Explorer) können mithilfe von COM automatisiert werden. Die folgenden Beispiele verdeutlichen einige der typischen Techniken und Probleme im Zusammenhang mit COM-basierten Anwendungen.
Sie erstellen eine Internet Explorer-Instanz, indem Sie die ProgID von Internet Explorer angeben, InternetExplorer.Application:
$ie = New-Object -ComObject InternetExplorer.Application
Dieser Befehl startet Internet Explorer, zeigt die Anwendung aber nicht an. Wenn Sie Get-Process
eingeben, können Sie sehen, dass ein Prozess mit dem Namen iexplore
ausgeführt wird. Auch wenn Sie PowerShell beenden, wird der Prozess weiterhin ausgeführt. Sie müssen den Computer neu starten oder ein Tool wie Task-Manager verwenden, um den Prozess iexplore
zu beenden.
Hinweis
Für COM-Objekte, die als separate Prozesse gestartet werden, so genannte ActiveX-EXE-Dateien, kann beim Start ein Benutzeroberflächenfenster angezeigt werden, muss aber nicht. Wenn sie ein Fenster erstellen, es aber nicht sichtbar machen, wie Internet Explorer, wechselt der Fokus in der Regel auf den Windows-Desktop. Sie müssen das Fenster sichtbar machen, um damit zu interagieren.
Durch Eingabe von $ie | Get-Member
können Sie Eigenschaften und Methoden für Internet Explorer anzeigen. Um das Internet Explorer-Fenster anzuzeigen, legen Sie die Eigenschaft Visible auf $true
fest, indem Sie Folgendes eingeben:
$ie.Visible = $true
Anschließend können Sie mithilfe der Navigate
-Methode zu einer bestimmten Webadresse navigieren:
$ie.Navigate("https://devblogs.microsoft.com/scripting/")
Unter Verwendung anderer Elemente des Internet Explorer-Objektmodells können Sie Textinhalt von der Website abrufen. Mit dem folgenden Befehl können Sie den HTML-Text im Hauptteil der aktuellen Webseite anzeigen:
$ie.Document.Body.InnerText
Um Internet Explorer aus PowerShell heraus zu schließen, rufen Sie die Quit()
-Methode auf:
$ie.Quit()
Die Variable $ie
enthält keinen gültigen Verweis mehr, obwohl es sich noch um ein COM-Objekt zu handeln scheint. Wenn Sie die Variable verwenden, gibt PowerShell einen Automatisierungsfehler zurück:
$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 <<<<
Sie können entweder den verbleibenden Verweis mit einem Befehl wie $ie = $null
oder die Variable durch folgende Eingabe entfernen:
Remove-Variable ie
Hinweis
Es gibt keinen allgemeinen Standard, der festlegt, ob ActiveX-EXE-Dateien beendet oder weiterhin ausgeführt werden, wenn Sie einen Verweis darauf entfernen. Je nach Situation, also z. B. abhängig davon, ob die Anwendung angezeigt, ein bearbeitetes Dokument darin ausgeführt oder PowerShell noch ausgeführt wird, wird die Anwendung beendet oder auch nicht. Aus diesem Grund sollten Sie das Abbruchverhalten für jede ausführbare ActiveX-Datei testen, die Sie in PowerShell verwenden möchten.
Abrufen von Warnungen zu von .NET Framework umschlossenen COM-Objekten
In einigen Fällen verfügt ein COM-Objekt möglicherweise über einen zugeordneten .NET Framework Runtime-Callable Wrapper (RCW), der von New-Object
verwendet wird. Da das Verhalten des RCW möglicherweise vom Verhalten des normalen COM-Objekts abweicht, verfügt New-Object
über einen Strict-Parameter, der Sie auf den RCW-Zugriff hinweist. Wenn Sie den Parameter Strict angeben und dann ein COM-Objekt erstellen, das einen RCW verwendet, wird eine Warnung angezeigt:
$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
Das Objekt wird zwar erstellt, Sie werden jedoch darauf hingewiesen, dass es sich nicht um ein Standard-COM-Objekt handelt.