Die Textausgabe von Befehlen im PowerShell-Interpreterfenster ist lediglich eine Möglichkeit, Informationen in einer für die menschliche Wahrnehmung geeigneten Form darzustellen. Eigentlich Mittwoch
Table of Contents:
Objekte in PowerShell
Erinnern wir uns daran, dass ein Objekt eine Sammlung von Datenfeldern (Eigenschaften, Ereignisse usw.) und Methoden zu deren Verarbeitung (Methoden) ist. Seine Struktur wird durch einen Typ angegeben, der normalerweise auf Klassen basiert, die in der einheitlichen .NET Core-Plattform verwendet werden. Es ist auch möglich, mit COM-, CIM- (WMI) und ADSI-Objekten zu arbeiten. Eigenschaften und Methoden werden benötigt, um verschiedene Aktionen an Daten auszuführen. Darüber hinaus können in PowerShell Objekte als Argumente an Funktionen und Cmdlets übergeben, ihre Werte Variablen zugewiesen werden, und das ist auch möglich
Anzeigen der Struktur von Objekten
Lassen Sie uns beispielsweise das Cmdlet Get-Process ausführen, mit dem Sie Informationen über die im System ausgeführten Prozesse abrufen können:
Es werden einige formatierte Textdaten angezeigt, die keinen Aufschluss über die Eigenschaften der zurückgegebenen Objekte und ihrer Methoden geben. Um die Ausgabe zu optimieren, müssen wir lernen, die Struktur von Objekten zu untersuchen, und das Cmdlet „Get-Member“ wird uns dabei helfen:
Get-Process | Get-Member
Hier sehen wir bereits den Typ und die Struktur und können mit Hilfe zusätzlicher Parameter beispielsweise nur die Eigenschaften des in der Eingabe enthaltenen Objekts anzeigen:
Get-Process | Get-Member -MemberType Property
Dieses Wissen wird benötigt, um Verwaltungsprobleme interaktiv zu lösen oder eigene Skripte zu schreiben, beispielsweise um Informationen über blockierte Prozesse mithilfe der Responding-Eigenschaft zu erhalten.
Objekte filtern
PowerShell ermöglicht die Weiterleitung von Objekten, die eine bestimmte Bedingung erfüllen, durch eine Pipeline:
Where-Object { блок сценария }
Das Ergebnis der Ausführung des Skriptblocks innerhalb der Klammern muss ein boolescher Wert sein. Wenn es wahr ist ($true), wird das in das Cmdlet „Where-Object“ eingegebene Objekt entlang der Pipeline weitergeleitet, andernfalls ($false) wird es gelöscht. Lassen Sie uns beispielsweise eine Liste der gestoppten Windows Server-Dienste anzeigen, d. h. diejenigen, deren Status-Eigenschaft auf „Gestoppt“ gesetzt ist:
Get-Service | Where-Object {$_.Status -eq "Stopped"}
Auch hier sehen wir eine Textdarstellung, aber wenn Sie den Typ und die interne Struktur der Objekte verstehen möchten, die die Pipeline durchlaufen, ist dies nicht schwierig:
Get-Service | Where-Object {$_.Status -eq "Stopped"} | Get-Member
Objekte sortieren
Bei der Pipeline-Verarbeitung von Objekten besteht häufig die Notwendigkeit, diese zu sortieren. Dem Cmdlet Sort-Object werden die Namen von Eigenschaften (Sortierschlüssel) übergeben und es gibt Objekte geordnet nach ihren Werten zurück. Es ist einfach, die Ausgabe laufender Prozesse nach der verbrauchten CPU-Zeit zu sortieren (CPU-Eigenschaft):
Get-Process | Sort-Object –Property cpu
Der Parameter -Property kann beim Aufruf des Cmdlets Sort-Object weggelassen werden; er wird standardmäßig verwendet. Verwenden Sie für die umgekehrte Sortierung den Parameter -Descending:
Get-Process | Sort-Object cpu -Descending
Auswählen von Objekten und deren Teilen
Mit dem Cmdlet „Select-Object“ können Sie mithilfe der Parameter „-First“ oder „-Last“ eine bestimmte Anzahl von Objekten am Anfang oder Ende einer Pipeline auswählen. Mit seiner Hilfe können Sie einzelne Objekte oder bestimmte Eigenschaften auswählen und darauf basierend auch neue Objekte erstellen. Schauen wir uns anhand einfacher Beispiele an, wie das Cmdlet funktioniert.
Der folgende Befehl zeigt Informationen zu den 10 Prozessen an, die die maximale Menge an RAM verbrauchen (WS-Eigenschaft):
Get-Process | Sort-Object WS -Descending | Select-Object -First 10
Sie können nur bestimmte Eigenschaften von Objekten auswählen, die die Pipeline durchlaufen, und darauf basierend neue erstellen:
Get-Process | Select-Object ProcessName, Id -First 1
Als Ergebnis des Pipeline-Vorgangs erhalten wir ein neues Objekt, dessen Struktur sich von der vom Cmdlet Get-Process zurückgegebenen Struktur unterscheidet. Überprüfen wir dies mit Get-Member:
Get-Process | Select-Object ProcessName, Id -First 1 | Get-Member
Beachten Sie, dass Select-Object ein einzelnes Objekt (-First 1) zurückgibt, das nur zwei der von uns angegebenen Felder enthält: Ihre Werte wurden vom ersten Objekt kopiert, das vom Cmdlet Get-Process an die Pipeline übergeben wurde. Eine Möglichkeit zum Erstellen von Objekten in PowerShell-Skripten basiert auf der Verwendung von Select-Object:
$obj = Get-Process | Select-Object ProcessName, Id -First 1
$obj.GetType()
Mit Select-Object können Sie berechnete Eigenschaften zu Objekten hinzufügen, als die dargestellt werden müssen
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}}
Schauen wir uns die Struktur von Objekten an, die das Förderband passieren:
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}} | Get-Member
ForEach-Object, Group-Object und Measure-Object
Für die Arbeit mit Objekten gibt es weitere Cmdlets. Lassen Sie uns als Beispiel über die drei nützlichsten sprechen:
Für jedes Objekt ermöglicht es Ihnen, PowerShell-Code für jedes Objekt in der Pipeline auszuführen:
ForEach-Object { блок сценария }
Gruppenobjekt gruppiert Objekte nach Eigenschaftswert:
Group-Object PropertyName
Wenn Sie es mit dem Parameter -NoElement ausführen, können Sie die Anzahl der Elemente in den Gruppen ermitteln.
Messobjekt aggregiert verschiedene Zusammenfassungsparameter nach Objektfeldwerten in der Pipeline (berechnet die Summe und ermittelt auch den Minimal-, Maximal- oder Durchschnittswert):
Measure-Object -Property PropertyName -Minimum -Maximum -Average -Sum
Typischerweise werden die besprochenen Cmdlets interaktiv verwendet und oft in Skripten erstellt.
Erstellen von .NET- und COM-Objekten (New-Object)
Es gibt viele Softwarekomponenten mit .NET Core- und COM-Schnittstellen, die für Systemadministratoren nützlich sind. Mit der Klasse System.Diagnostics.EventLog können Sie Systemprotokolle direkt von Windows PowerShell aus verwalten. Sehen wir uns ein Beispiel für die Erstellung einer Instanz dieser Klasse mithilfe des Cmdlets New-Object mit dem Parameter -TypeName an:
New-Object -TypeName System.Diagnostics.EventLog
Da wir kein spezifisches Ereignisprotokoll angegeben haben, enthält die resultierende Instanz der Klasse keine Daten. Um dies zu ändern, müssen Sie bei der Erstellung eine spezielle Konstruktormethode mit dem Parameter -ArgumentList aufrufen. Wenn wir auf das Anwendungsprotokoll zugreifen möchten, sollten wir die Zeichenfolge „Application“ als Argument an den Konstruktor übergeben:
$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
$AppLog
Bitte beachten Sie, dass wir die Ausgabe des Befehls in der Variablen $AppLog gespeichert haben. Obwohl Pipelines häufig im interaktiven Modus verwendet werden, erfordert das Schreiben von Skripts häufig die Pflege eines Verweises auf ein Objekt. Darüber hinaus sind die .NET Core-Kernklassen im System-Namespace enthalten: PowerShell sucht darin standardmäßig nach bestimmten Typen, daher ist es völlig korrekt, Diagnostics.EventLog anstelle von System.Diagnostics.EventLog zu schreiben.
Um mit dem Protokoll zu arbeiten, können Sie die entsprechenden Methoden verwenden:
$AppLog | Get-Member -MemberType Method
Nehmen wir an, es wird durch die Clear()-Methode gelöscht, wenn Zugriffsrechte vorhanden sind:
$AppLog.Clear()
Das Cmdlet New-Object wird auch zum Arbeiten mit COM-Komponenten verwendet. Davon gibt es eine ganze Menge – von den mit dem Windows-Skriptserver mitgelieferten Bibliotheken bis hin zu ActiveX-Anwendungen wie dem Internet Explorer. Um ein COM-Objekt zu erstellen, müssen Sie den Parameter -ComObject mit der programmatischen ProgId der gewünschten Klasse festlegen:
New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObject
Um eigene Objekte mit beliebiger Struktur zu erstellen, erscheint die Verwendung von New-Object zu archaisch und umständlich; dieses Cmdlet wird verwendet, um mit Softwarekomponenten außerhalb von PowerShell zu arbeiten. In zukünftigen Artikeln wird dieses Thema detaillierter besprochen. Zusätzlich zu .NET- und COM-Objekten werden wir auch CIM- (WMI) und ADSI-Objekte untersuchen.
Statische Methoden aufrufen
Einige .NET Core-Klassen können nicht instanziiert werden, einschließlich System.Environment und System.Math. Sie sind
[System.Environment] | Get-Member
Um nur statische Mitglieder anzuzeigen, rufen Sie Get-Member mit dem Parameter -Static auf (beachten Sie den Objekttyp):
[System.Environment] | Get-Member -Static
Um auf statische Eigenschaften und Methoden zuzugreifen, verwenden Sie zwei aufeinanderfolgende Doppelpunkte anstelle eines Punkts nach dem Literal:
[System.Environment]::OSVersion
Oder
$test=[System.Math]::Sqrt(25)
$test
$test.GetType()
Geben Sie PSCustomObject ein
Unter den zahlreichen in PowerShell verfügbaren Datentypen ist PSCustomObject erwähnenswert, das zum Speichern von Objekten mit beliebiger Struktur entwickelt wurde. Das Erstellen eines solchen Objekts mit dem Cmdlet New-Object gilt als klassische, aber umständliche und veraltete Methode:
$object = New-Object –TypeName PSCustomObject -Property @{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'}
Schauen wir uns die Struktur des Objekts an:
$object | Get-Member
Ab PowerShell 3.0 ist eine andere Syntax verfügbar:
$object = [PSCustomObject]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
Sie können auf eine der entsprechenden Arten auf die Daten zugreifen:
$object.Name
$object.'Name'
$value = 'Name'
$object.$value
Hier ist ein Beispiel für die Konvertierung einer vorhandenen Hashtabelle in ein Objekt:
$hash = @{'Name'='Ivan Danko'; 'City'='Moscow'; 'Country'='Russia'}
$hash.GetType()
$object = [pscustomobject]$hash
$object.GetType()
Einer der Nachteile von Objekten dieser Art besteht darin, dass sich die Reihenfolge ihrer Eigenschaften ändern kann. Um dies zu vermeiden, müssen Sie das Attribut [ordered] verwenden:
$object = [PSCustomObject][ordered]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
Es gibt andere Möglichkeiten, ein Objekt zu erstellen: Oben haben wir uns die Verwendung des Cmdlets angesehen
$object | Add-Member –MemberType NoteProperty –Name Age –Value 33
$object | Get-Member
Mit dem Cmdlet „Add-Member“ können Sie nicht nur Eigenschaften, sondern auch Methoden zu einem zuvor erstellten $object hinzufügen, indem Sie das Konstrukt „-MemberType ScriptMethod“ verwenden:
$ScriptBlock = {
# код
}
$object | Add-Member -Name "MyMethod" -MemberType ScriptMethod -Value $ScriptBlock
$object | Get-Member
Bitte beachten Sie, dass wir die Variable $ScriptBlock vom Typ ScriptBlock verwendet haben, um den Code für die neue Methode zu speichern.
Um Eigenschaften zu entfernen, verwenden Sie die entsprechende Methode:
$object.psobject.properties.remove('Name')
Erstellen Sie Ihre eigenen Klassen
Mit PowerShell 5.0 wurde die Möglichkeit zum Definieren eingeführt
class MyClass
{
# тело класса
}
Dies ist ein echter .NET Core-Typ mit einem Hauptteil, der seine Eigenschaften, Methoden und anderen Elemente beschreibt. Schauen wir uns ein Beispiel für die Definition der einfachsten Klasse an:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
}
Um ein Objekt (Klasseninstanz) zu erstellen, verwenden Sie das Cmdlet
$object = New-Object -TypeName MyClass
oder
$object = [MyClass]::new()
Lassen Sie uns die Struktur des Objekts analysieren:
$object | Get-Member
Vergessen Sie nicht den Gültigkeitsbereich: Sie können einen Typnamen nicht als Zeichenfolge bezeichnen oder ein Typliteral außerhalb des Skripts oder Moduls verwenden, in dem die Klasse definiert ist. In diesem Fall können Funktionen Klasseninstanzen (Objekte) zurückgeben, auf die außerhalb des Moduls oder Skripts zugegriffen werden kann.
Geben Sie nach dem Erstellen des Objekts seine Eigenschaften ein:
$object.Name = 'Ivan Danko'
$object.City = 'Moscow'
$object.Country = 'Russia'
$object
Beachten Sie, dass die Klassenbeschreibung nicht nur die Eigenschaftstypen, sondern auch deren Standardwerte angibt:
class Example
{
[string]$Name = 'John Doe'
}
Die Beschreibung einer Klassenmethode ähnelt der Beschreibung einer Funktion, jedoch ohne die Verwendung des Funktionsworts. Wie bei einer Funktion werden bei Bedarf Parameter an Methoden übergeben:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
#описание метода
Smile([bool]$param1)
{
If($param1) {
Write-Host ':)'
}
}
}
Jetzt kann der Vertreter unserer Klasse lächeln:
$object = [MyClass]::new()
$object.Smile($true)
Methoden können überladen sein; außerdem ist eine Klasse überladen
class MyClass2 : MyClass
{
#тело нового класса, базовым для которого является MyClass
}
[MyClass2]::new().Smile($true)
Unsere Beschreibung der Arbeit mit Objekten in PowerShell ist kaum erschöpfend. In den folgenden Veröffentlichungen werden wir versuchen, es anhand praktischer Beispiele zu vertiefen: Der fünfte Artikel der Reihe widmet sich den Fragen der Integration von PowerShell mit Softwarekomponenten von Drittanbietern. Frühere Teile finden Sie unter den folgenden Links.
Source: habr.com