Freigeben über


Kapitel 4 – One-Liners und die Pipeline

Als ich mit dem Erlernen von PowerShell begonnen habe, vertraute ich zunächst auf die grafische Benutzeroberfläche (GUI) für Aufgaben, die für einfache PowerShell-Befehle zu komplex schien. Da ich jedoch weiter gelernt habe, habe ich meine Fähigkeiten verbessert und von einfachen Einzeilen zum Erstellen von Skripts, Funktionen und Modulen gewechselt. Es ist wichtig, daran zu denken, dass es normal ist, sich von ausführlichen Online-Beispielen überwältigt zu fühlen. Niemand beginnt als Experte in PowerShell; Wir beginnen alle als Anfänger.

Installieren Sie die Verwaltungstools auf Ihrer Administrationsarbeitsstation, wenn Sie in erster Linie die GUI für administrative Aufgaben verwenden, um Ihre Server remote zu verwalten. Unabhängig davon, ob Ihr Server eine GUI oder die Server Core OS-Installation verwendet, ist dieser Ansatz von Vorteil. Es ist eine praktische Möglichkeit, sich mit der Remoteserververwaltung in Vorbereitung auf die Durchführung administrativer Aufgaben mit PowerShell vertraut zu machen.

Wie in den vorherigen Kapiteln probieren Sie diese Konzepte in Ihrer Laborumgebung aus.

Einzeiler

Ein PowerShell-Einzeiler ist eine durchgehende Pipeline. Es ist ein allgemeiner Irrglaube, dass ein Befehl in einer Zeile ein PowerShell Einzeiler ist. Das stimmt nicht immer.

Betrachten Sie zum Beispiel das folgende Beispiel: Der Befehl erstreckt sich über mehrere Zeilen, ist aber dennoch ein PowerShell-Einzeiler, da er eine durchgehende Pipeline bildet. Um die Lesbarkeit und Transparenz eines langen Einzeilers zu verbessern, empfiehlt sich ein Zeilenumbruch am Pipe-Symbol, einem natürlichen Unterbrechungspunkt in der PowerShell. Dieser strategische Einsatz von Zeilenumbrüchen verbessert die Lesbarkeit, ohne den Flow der Pipeline zu unterbrechen.

Get-Service |
    Where-Object CanPauseAndContinue -EQ $true |
    Select-Object -Property *
Name                : LanmanWorkstation
RequiredServices    : {NSI, MRxSmb20, Bowser}
CanPauseAndContinue : True
CanShutdown         : False
CanStop             : True
DisplayName         : Workstation
DependentServices   : {SessionEnv, Netlogon}
MachineName         : .
ServiceName         : LanmanWorkstation
ServicesDependedOn  : {NSI, MRxSmb20, Bowser}
ServiceHandle       :
Status              : Running
ServiceType         : Win32OwnProcess, Win32ShareProcess
StartType           : Automatic
Site                :
Container           :

Name                : Netlogon
RequiredServices    : {LanmanWorkstation}
CanPauseAndContinue : True
CanShutdown         : False
CanStop             : True
DisplayName         : Netlogon
DependentServices   : {}
MachineName         : .
ServiceName         : Netlogon
ServicesDependedOn  : {LanmanWorkstation}
ServiceHandle       :
Status              : Running
ServiceType         : Win32ShareProcess
StartType           : Automatic
Site                :
Container           :

Name                : vmicheartbeat
RequiredServices    : {}
CanPauseAndContinue : True
CanShutdown         : False
CanStop             : True
DisplayName         : Hyper-V Heartbeat Service
DependentServices   : {}
MachineName         : .
ServiceName         : vmicheartbeat
ServicesDependedOn  : {}
ServiceHandle       :
Status              : Running
ServiceType         : Win32OwnProcess, Win32ShareProcess
StartType           : Manual
Site                :
Container           :

Name                : vmickvpexchange
RequiredServices    : {}
CanPauseAndContinue : True
CanShutdown         : False
CanStop             : True
DisplayName         : Hyper-V Data Exchange Service
DependentServices   : {}
MachineName         : .
ServiceName         : vmickvpexchange
ServicesDependedOn  : {}
ServiceHandle       :
Status              : Running
ServiceType         : Win32OwnProcess, Win32ShareProcess
StartType           : Manual
Site                :
Container           :

Name                : vmicrdv
RequiredServices    : {}
CanPauseAndContinue : True
CanShutdown         : False
CanStop             : True
DisplayName         : Hyper-V Remote Desktop Virtualization Service
DependentServices   : {}
MachineName         : .
ServiceName         : vmicrdv
ServicesDependedOn  : {}
ServiceHandle       :
Status              : Running
ServiceType         : Win32OwnProcess, Win32ShareProcess
StartType           : Manual
Site                :
Container           :

Name                : vmicshutdown
RequiredServices    : {}
CanPauseAndContinue : True
CanShutdown         : False
CanStop             : True
DisplayName         : Hyper-V Guest Shutdown Service
DependentServices   : {}
MachineName         : .
ServiceName         : vmicshutdown
ServicesDependedOn  : {}
ServiceHandle       :
Status              : Running
ServiceType         : Win32OwnProcess, Win32ShareProcess
StartType           : Manual
Site                :
Container           :

Name                : vmicvss
RequiredServices    : {}
CanPauseAndContinue : True
CanShutdown         : False
CanStop             : True
DisplayName         : Hyper-V Volume Shadow Copy Requestor
DependentServices   : {}
MachineName         : .
ServiceName         : vmicvss
ServicesDependedOn  : {}
ServiceHandle       :
Status              : Running
ServiceType         : Win32OwnProcess, Win32ShareProcess
StartType           : Manual
Site                :
Container           :

Name                : webthreatdefsvc
RequiredServices    : {RpcSs, wtd}
CanPauseAndContinue : True
CanShutdown         : True
CanStop             : True
DisplayName         : Web Threat Defense Service
DependentServices   : {}
MachineName         : .
ServiceName         : webthreatdefsvc
ServicesDependedOn  : {RpcSs, wtd}
ServiceHandle       :
Status              : Running
ServiceType         : Win32OwnProcess, Win32ShareProcess
StartType           : Manual
Site                :
Container           :

Name                : webthreatdefusersvc_644de
RequiredServices    : {}
CanPauseAndContinue : True
CanShutdown         : True
CanStop             : True
DisplayName         : Web Threat Defense User Service_644de
DependentServices   : {}
MachineName         : .
ServiceName         : webthreatdefusersvc_644de
ServicesDependedOn  : {}
ServiceHandle       :
Status              : Running
ServiceType         : 240
StartType           : Automatic
Site                :
Container           :

Name                : Winmgmt
RequiredServices    : {RPCSS}
CanPauseAndContinue : True
CanShutdown         : True
CanStop             : True
DisplayName         : Windows Management Instrumentation
DependentServices   : {}
MachineName         : .
ServiceName         : Winmgmt
ServicesDependedOn  : {RPCSS}
ServiceHandle       :
Status              : Running
ServiceType         : Win32OwnProcess, Win32ShareProcess
StartType           : Automatic
Site                :
Container           :

Natürliche Zeilenumbrüche können an häufig verwendeten Zeichen auftreten, einschließlich Komma (,) und öffnenden Klammern ([), geschweiften Klammern ({) und Klammern ((). Andere Zeichen, die nicht so häufig vorkommen, umfassen das Semikolon (;), das Gleichheitszeichen (=) sowie öffnende einfache als auch doppelte Anführungszeichen (', ").

Die Verwendung des Backticks (`) oder des Gravis-Akzentzeichens als Zeilenfortsetzung ist umstritten. Es ist am besten, es nach Möglichkeit zu vermeiden. Die Verwendung eines Backticks nach einem natürlichen Zeilenumbruch ist ein häufiger Fehler. Diese Redundanz ist unnötig und kann den Code überladen.

Die Befehle im folgenden Beispiel werden ordnungsgemäß über die PowerShell-Konsole ausgeführt. Der Versuch, sie im Konsolenbereich der integrierten Skriptumgebung (ISE) von PowerShell auszuführen, führt jedoch zu einem Fehler. Dieser Unterschied tritt auf, weil der Konsolenbereich der ISE im Gegensatz zur PowerShell-Konsole die Fortsetzung eines Befehls in der nächsten Zeile nicht automatisch vorwegnimmt. Um dieses Problem zu vermeiden, drücken Sie UMSCHALT+EINGABE im Konsolenbereich der ISE anstelle von EINGABE, wenn Sie einen Befehl über mehrere Zeilen hinweg verlängern müssen. Diese Tastenkombination signalisiert dem ISE, dass der Befehl in der folgenden Zeile fortgesetzt wird und verhindert die Ausführung, die zu Fehlern führt.

Get-Service -Name w32time |
    Select-Object -Property *
Name                : w32time
RequiredServices    : {}
CanPauseAndContinue : False
CanShutdown         : True
CanStop             : True
DisplayName         : Windows Time
DependentServices   : {}
MachineName         : .
ServiceName         : w32time
ServicesDependedOn  : {}
ServiceHandle       :
Status              : Running
ServiceType         : Win32OwnProcess, Win32ShareProcess
StartType           : Manual
Site                :
Container           :

Das folgende Beispiel ist kein PowerShell-Einzeiler, da es sich nicht um eine durchgehende Pipeline handelt. Stattdessen sind zwei separate Befehle in einer einzelnen Zeile angeordnet, die durch ein Semikolon getrennt sind. Dieses Semikolon gibt das Ende eines Befehls und den Anfang eines anderen an.

$Service = 'w32time'; Get-Service -Name $Service
Status   Name               DisplayName
------   ----               -----------
Running  w32time            Windows Time

Viele Programmier- und Skriptsprachen erfordern ein Semikolon am Ende jeder Zeile. In PowerShell sind Semikolons am Ende der Zeilen jedoch nicht erforderlich und nicht empfohlen. Sie sollten sie vermeiden, um übersichtlicheren und besser lesbaren Code zu erhalten.

Links filtern

In diesem Kapitel wird das Filtern der Ergebnisse verschiedener Befehle veranschaulicht.

Es ist eine bewährte Methode in PowerShell, die Ergebnisse so früh wie möglich in der Pipeline zu filtern. Um dies zu erreichen, müssen Sie Filter mit Hilfe von Parametern auf den ersten Befehl anwenden, in der Regel am Anfang der Pipeline. Dies wird allgemein als links filtern bezeichnet.

Um dieses Konzept zu veranschaulichen, betrachten Sie das folgende Beispiel: Verwenden Sie den Parameter Name von Get-Service, um die Ergebnisse am Anfang der Pipeline zu filtern und nur die Details für den Windows Time-Dienst zurückzugeben. Diese Methode veranschaulicht einen effizienten Datenabruf und stellt sicher, dass nur die erforderlichen und relevanten Informationen zurückgegeben werden.

Get-Service -Name w32time
Status   Name               DisplayName
------   ----               -----------
Running  w32time            Windows Time

Im Internet finden Sie häufig Beispiele dafür, dass ein PowerShell-Befehl an das Cmdlet Where-Object weitergeleitet wird, um seine Ergebnisse zu filtern. Diese Technik ist ineffizient, wenn ein früherer Befehl in der Pipeline über einen Parameter zum Ausführen der Filterung verfügt.

Get-Service | Where-Object Name -EQ w32time
Status   Name               DisplayName
------   ----               -----------
Running  W32Time            Windows Time

Im ersten Beispiel wird das Filtern direkt an der Quelle veranschaulicht, wobei Ergebnisse speziell für den Windows-Zeitdienst zurückgegeben werden. Im gegensatz dazu ruft das zweite Beispiel alle Dienste ab und verwendet dann einen anderen Befehl, um die Ergebnisse zu filtern. Dies mag in kleinen Szenarien unbedeutend erscheinen, aber berücksichtigen Sie eine Situation, die ein großes Dataset wie Active Directory umfasst. Es ist ineffizient, Details für Tausende von Benutzerkonten abzurufen, um sie nur auf eine kleine Teilmenge einzugrenzen. Üben Sie links filtern – wenden Sie Filter so früh wie möglich in der Befehlssequenz an – selbst in scheinbar trivialen Fällen. Diese Gewohnheit sorgt für Effizienz in komplexeren Szenarien, in denen sie wichtiger wird.

Befehlssequenzierung für effektive Filterung

Es gibt eine Fehleinschätzung, dass die Reihenfolge von Befehlen in PowerShell inkonsequent ist, aber dies ist ein Missverständnis. Die Reihenfolge, in der Sie Befehle anordnen, insbesondere beim Filtern, ist wichtig. Angenommen, Sie verwenden Select-Object, um bestimmte Eigenschaften auszuwählen, und Where-Object zum Filtern. In diesem Fall ist es wichtig, zuerst die Filterung anzuwenden. Andernfalls sind die erforderlichen Eigenschaften möglicherweise nicht in der Pipeline für die Filterung verfügbar, was zu unwirksamen oder fehlerhaften Ergebnissen führt.

Das folgende Beispiel liefert keine Ergebnisse, weil die Eigenschaft CanPauseAndContinue nicht vorhanden ist, wenn Select-Object über die Pipeline an Where-Object übergeben wird. Das liegt daran, dass die Eigenschaft CanPauseAndContinue nicht in die Auswahl von Select-Object aufgenommen wurde. Sie wird also ausgeschlossen oder herausgefiltert.

Get-Service |
    Select-Object -Property DisplayName, Running, Status |
    Where-Object CanPauseAndContinue

Das Umkehren der Reihenfolge von Select-Object und Where-Object erzeugt die gewünschten Ergebnisse.

Get-Service |
    Where-Object CanPauseAndContinue |
    Select-Object -Property DisplayName, Status
DisplayName                                    Status
-----------                                    ------
Workstation                                   Running
Netlogon                                      Running
Hyper-V Heartbeat Service                     Running
Hyper-V Data Exchange Service                 Running
Hyper-V Remote Desktop Virtualization Service Running
Hyper-V Guest Shutdown Service                Running
Hyper-V Volume Shadow Copy Requestor          Running
Web Threat Defense Service                    Running
Web Threat Defense User Service_644de         Running
Windows Management Instrumentation            Running

Die Pipeline

Wie in vielen Beispielen in diesem Buch gezeigt, können Sie häufig die Ausgabe eines Befehls als Eingabe für einen anderen Befehl verwenden. In Kapitel 3 wurde Get-Member verwendet, um zu bestimmen, welchen Objekttyp ein Befehl erzeugt.

In Kapitel 3 wurde auch gezeigt, wie man den Parameter ParameterType von Get-Command verwendet, um zu bestimmen, welche Befehle diesen Eingabetyp akzeptieren. Je nachdem, wie ausführlich die Hilfe zu einem Befehl ist, kann sie einen INPUTS- und OUTPUTS-Abschnitt enthalten.

Der Abschnitt INPUTS zeigt an, dass Sie ein ServiceController oder ein Zeichenfolge-Objekt über die Pipeline an das Cmdlet Stop-Service übergeben können.

help Stop-Service -Full

Die folgende Ausgabe ist abgekürzt, um den relevanten Teil der Hilfe anzuzeigen.

...
INPUTS
    System.ServiceProcess.ServiceController
        You can pipe a service object to this cmdlet.

    System.String
        You can pipe a string that contains the name of a service to this
        cmdlet.


OUTPUTS
    None
        By default, this cmdlet returns no output.

    System.ServiceProcess.ServiceController
        When you use the PassThru parameter, this cmdlet returns a
        ServiceController object representing the service.
...

Es gibt jedoch nicht an, welche Parameter diese Art von Eingabe akzeptieren. Sie können diese Informationen ermitteln, indem Sie die verschiedenen Parameter in der Vollversion der Hilfe für das Cmdlet Stop-Service überprüfen.

help Stop-Service -Full

Erneut wird nur die relevante Hilfe in den folgenden Ergebnissen angezeigt. Beachten Sie, dass der Parameter DisplayName keine Pipeline-Eingabe akzeptiert. Der Parameter InputObject akzeptiert Pipeline-Eingaben als Wert für ServiceController-Objekte. Der Parameter Name akzeptiert Pipeline-Eingaben als Wert für Zeichenfolge-Objekte und Pipeline-Eingaben nach Eigenschaftsname.

...
-DisplayName <System.String[]>
    Specifies the display names of the services to stop. Wildcard
    characters are permitted.

    Required?                    true
    Position?                    named
    Default value                None
    Accept pipeline input?       False
    Accept wildcard characters?  true

-InputObject <System.ServiceProcess.ServiceController[]>
    Specifies ServiceController objects that represent the services to
    stop. Enter a variable that contains the objects, or type a command
    or expression that gets the objects.

    Required?                    true
    Position?                    0
    Default value                None
    Accept pipeline input?       True (ByValue)
    Accept wildcard characters?  false

-Name <System.String[]>
    Specifies the service names of the services to stop. Wildcard
    characters are permitted.

    Required?                    true
    Position?                    0
    Default value                None
    Accept pipeline input?       True (ByPropertyName, ByValue)
    Accept wildcard characters?  true
...

Bei der Verarbeitung von Pipeline-Eingaben wird bei einem Parameter, der Pipeline-Eingaben sowohl nach Eigenschaftsname als auch nach Wert akzeptiert, die Bindung nach Wert zuerst priorisiert. Wenn diese Methode fehlschlägt, wird versucht, die Pipeline-Eingabe nach Eigenschaftsname zu verarbeiten. Der Begriff nach Wert kann jedoch irreführend sein. Eine korrektere Beschreibung ist nach Typ.

Wenn Sie z. B. die Ausgabe eines Befehls, der ein ServiceController-objekt generiert, an Stop-Serviceübergeben, wird diese Ausgabe an den InputObject--Parameter gebunden. Wenn der Weitergeleitete Befehl ein String-Objekt erzeugt, wird die Ausgabe dem parameter Name zugeordnet. Wenn Sie die Ausgabe eines Befehls über die Pipeline leiten, der kein ServiceController- oder Zeichenfolge-Objekt erzeugt, aber eine Eigenschaft namens Name enthält, bindet Stop-Service den Wert der Eigenschaft Name an seinen Parameter Name.

Bestimmen Sie, welcher Ausgabetyp der befehl Get-Service erzeugt.

Get-Service -Name w32time | Get-Member

Get-Service erzeugt einen ServiceController-Objekttyp.

   TypeName: System.ServiceProcess.ServiceController

Wie in der Hilfe zu Cmdlet Stop-Service gezeigt, akzeptiert der Parameter InputObjectServiceController-Objekte durch die Pipeline nach Wert. Das bedeutet, dass, wenn Sie die Ausgabe des Cmdlets Get-Service über die Pipeline an Stop-Service übergeben, die von erzeugten Get-Service-Objekte an den Parameter InputObject von Stop-Service gebunden werden.

Get-Service -Name w32time | Stop-Service

Probieren Sie nun die Zeichenfolgeneingabe aus. Übergeben Sie w32time an Get-Member, um zu bestätigen, dass es sich um eine Zeichenfolge handelt.

'w32time' | Get-Member
   TypeName: System.String

Die PowerShell-Hilfedokumentation veranschaulicht, dass, wenn Sie eine Zeichenfolge über die Pipeline an Stop-Service übergeben, diese an den Parameter Namenach Wert gebunden wird. Führen Sie einen praktischen Test durch, um dies in Aktion zu sehen: leiten Sie die Zeichenfolge w32time nach Stop-Service. In diesem Beispiel wird veranschaulicht, wie Stop-Service die Zeichenfolge w32time als Namen des Diensts verarbeitet, der beendet werden soll. Führen Sie den folgenden Befehl aus, um diese Bindung und Befehlsausführung in Aktion zu beobachten.

Beachten Sie, dass w32time in einfache Anführungszeichen eingeschlossen ist. In PowerShell empfiehlt es sich, einzelne Anführungszeichen für statische Zeichenfolgen zu verwenden, um doppelte Anführungszeichen für Situationen zu reservieren, in denen die Zeichenfolge Variablen enthält, die eine Erweiterung erfordern. Einfache Anführungszeichen weisen PowerShell an, den Inhalt wörtlich zu behandeln, ohne nach Variablen zu analysieren. Dieser Ansatz gewährleistet nicht nur die Genauigkeit der Interpretation der Zeichenfolge durch Ihr Skript, sondern verbessert auch die Leistung, da PowerShell weniger Verarbeitungsaufwand für Zeichenfolgen innerhalb einzelner Anführungszeichen aufwendet.

'w32time' | Stop-Service

Erstellen Sie ein benutzerdefiniertes Objekt, um die Pipelineeingabe als Eigenschaftsname für den Parameter Name von Stop-Service zu testen.

$customObject = [pscustomobject]@{
    Name = 'w32time'
}

Der Inhalt der Variablen CustomObject ist ein PSCustomObject-Objekttyp, der eine Eigenschaft namens Name enthält.

$customObject | Get-Member
   TypeName: System.Management.Automation.PSCustomObject

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
Name        NoteProperty string Name=w32time

Beim Arbeiten mit Variablen in PowerShell, z. B. $customObject in diesem Beispiel, ist es wichtig, doppelte Anführungszeichen zu verwenden, wenn Sie die Variable in Anführungszeichen setzen müssen. Doppelte Anführungszeichen ermöglichen die Variableerweiterung – PowerShell wertet die Variable aus und verwendet ihren Wert. Wenn Sie zum Beispiel $customObject in doppelte Anführungszeichen einschließen und über die Pipeline nach Get-Member leiten, verarbeitet PowerShell den Wert von $customObject. Im Gegensatz dazu würde die Verwendung von einfachen Anführungszeichen dazu führen, dass die wörtliche Zeichenfolge $customObject nach Get-Member geleitet wird und nicht der Wert der Variable. Diese Unterscheidung ist für Szenarien wichtig, in denen Sie den Wert von Variablen auswerten müssen.

Wenn Sie den Inhalt der Variablen $customObject über die Pipeline an das Cmdlet Stop-Service übergeben, erfolgt die Bindung an den Parameter Name über Eigenschaftsname und nicht über Wert. Dies liegt daran, dass $customObject ein Objekt ist, das eine Eigenschaft mit dem Namen Nameenthält. In diesem Szenario identifiziert PowerShell die Eigenschaft Name in $customObject und verwendet ihren Wert für den Parameter Name von Stop-Service.

Erstellen Sie ein weiteres angepasstes Objekt mit einem anderen Eigenschaftsnamen, wie z. B. Service.

$customObject = [pscustomobject]@{
    Service = 'w32time'
}

Bei dem Versuch, Service w32time über die Pipelinebindung von $customObject nach Stop-Service zu beenden, tritt ein Fehler auf. Die Pipeline-Bindung schlägt fehl, weil $customObject kein ServiceController- oder Zeichenfolgen-Objekt erzeugt und keine Eigenschaft Name enthält.

$customObject | Stop-Service
Stop-Service : Cannot find any service with service name
'@{Service=w32time}'.
At line:1 char:17
+ $customObject | Stop-Service
+                 ~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (@{Service=w32time}:String) [
   Stop-Service], ServiceCommandException
    + FullyQualifiedErrorId : NoServiceFoundForGivenName,Microsoft.PowerShe
   ll.Commands.StopServiceCommand

Wenn die Namen der Ausgabeeigenschaften eines Befehls nicht den Anforderungen an die Pipeline-Eingabe eines anderen Befehls entsprechen, können Sie Select-Object verwenden, um die Eigenschaftsnamen umzubenennen, sodass sie korrekt übereinstimmen.

Im folgenden Beispiel verwenden Sie Select-Object, um die Eigenschaft Service in eine Eigenschaft namens Name umzubenennen.

Auf den ersten Blick kann die Syntax dieses Beispiels komplex sein. Es ist jedoch wichtig zu verstehen, dass mehr als Kopieren und Einfügen von Code erforderlich ist, um die Syntax zu erlernen. Nehmen Sie sich stattdessen zeit, den Code manuell einzugeben. Diese praktische Übung hilft Ihnen, sich an die Syntax zu erinnern, und sie wird mit wiederholter Anstrengung intuitiver. Die Verwendung mehrerer Monitore oder geteilter Bildschirme kann auch beim Lernprozess helfen. Zeigen Sie den Beispielcode auf einem Bildschirm an, während Sie auf einem anderen Bildschirm aktiv daran arbeiten und experimentieren. Diese Einrichtung erleichtert das Nachvollziehen und verbessert Ihr Verständnis und das Merken der Syntax.

$customObject |
    Select-Object -Property @{Name='Name';Expression={$_.Service}} |
    Stop-Service

Es gibt Fälle, in denen Sie möglicherweise einen Parameter verwenden müssen, der keine Pipelineeingabe akzeptiert. In solchen Fällen können Sie die Ausgabe eines Befehls weiterhin als Eingabe für einen anderen verwenden. Erfassen und speichern Sie zunächst die Anzeigenamen einiger bestimmter Windows-Dienste in einer Textdatei. In diesem Schritt können Sie die gespeicherten Daten als Eingabe für einen anderen Befehl verwenden.

'Background Intelligent Transfer Service', 'Windows Time' |
    Out-File -FilePath $env:TEMP\services.txt

Sie können Klammern verwenden, um die Ausgabe eines Befehls als Eingabe für einen Parameter an einen anderen Befehl zu übergeben.

Stop-Service -DisplayName (Get-Content -Path $env:TEMP\services.txt)

Dieses Konzept ähnelt der Reihenfolge der Operationen in Algebra. Ebenso wie mathematische Vorgänge innerhalb von Klammern zuerst berechnet werden, wird der in Klammern eingeschlossene Befehl vor dem äußeren Befehl ausgeführt.

PowerShellGet

PowerShellGet, ein Modul, das in PowerShell Version 5.0 und höher enthalten ist, bietet Befehle zum Ermitteln, Installieren, Aktualisieren und Veröffentlichen von PowerShell-Modulen und anderen Elementen in einem NuGet-Repository. Für Personen, die PowerShell Version 3.0 und höher verwenden, ist PowerShellGet auch als separater Download verfügbar.

Die PowerShell Gallery ist ein von Microsoft gehostetes Online-Repository, das als zentraler Hub für die gemeinsame Nutzung von PowerShell-Modulen, Skripten und anderen Ressourcen konzipiert ist. Während Microsoft die PowerShell Gallery hostet, steuert die PowerShell-Community die meisten der verfügbaren Module und Skripts bei. Gehen Sie aufgrund der Quelle dieser Module und Skripte vorsichtig vor, bevor Sie Code aus der PowerShell Gallery in Ihre Umgebung integrieren. Überprüfen und testen Sie Downloads aus der PowerShell Gallery in einer isolierten Testumgebung. Dieser Prozess stellt sicher, dass der Code sicher und zuverlässig ist, wie erwartet funktioniert, und schützt Ihre Umgebung vor potenziellen Problemen oder Schwachstellen, die sich aus nicht überprüftem Code ergeben.

Viele Organisationen entscheiden sich dafür, ihr eigenes internes, privates NuGet-Repository einzurichten. Dieses Repository dient einem dualen Zweck. Erstens fungiert sie als sicherer Ort zum Speichern von Modulen, die intern entwickelt wurden und ausschließlich für den internen Gebrauch vorgesehen sind. Zweitens stellt sie eine überprüfte Sammlung von Modulen bereit, die extern stammen, einschließlich derjenigen aus öffentlichen Repositorys. Unternehmen nehmen in der Regel einen gründlichen Validierungsprozess vor dem Hinzufügen dieser externen Module zum internen Repository vor. Dieser Prozess ist wichtig, um sicherzustellen, dass die Module frei von böswilligen Inhalten sind und den Sicherheits- und Betriebsstandards des Unternehmens entsprechen.

Verwenden Sie das Cmdlet Find-Module, das Teil des Moduls PowerShellGet ist, um im PowerShell-Katalog ein von mir geschriebenes Modul namens MrToolkitzu finden.

Find-Module -Name MrToolkit
NuGet provider is required to continue
PowerShellGet requires NuGet provider version '2.8.5.201' or newer to
interact with NuGet-based repositories. The NuGet provider must be available
 in 'C:\Program Files\PackageManagement\ProviderAssemblies' or
'C:\Users\mikefrobbins\AppData\Local\PackageManagement\ProviderAssemblies'.
You can also install the NuGet provider by running 'Install-PackageProvider
-Name NuGet -MinimumVersion 2.8.5.201 -Force'. Do you want PowerShellGet to
install and import the NuGet provider now?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"):

Version    Name                      Repository        Description
-------    ----                      ----------        -----------
1.3        MrToolkit                 PSGallery         Misc PowerShell Tools

Wenn Sie zum ersten Mal einen der Befehle aus dem PowerShellGet Modul verwenden, werden Sie aufgefordert, den NuGet-Anbieter zu installieren.

Um das MrToolkit Modul zu installieren, leiten Sie den vorherigen Befehl an Install-Moduleweiter.

Find-Module -Name MrToolkit | Install-Module -Scope CurrentUser
Untrusted repository
You are installing the modules from an untrusted repository. If you trust
this repository, change its InstallationPolicy value by running the
Set-PSRepository cmdlet. Are you sure you want to install the modules from
'https://www.powershellgallery.com/api/v2'?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help
(default is "N"):y

Da es sich beim PowerShell-Katalog um ein nicht vertrauenswürdiges Repository handelt, werden Sie aufgefordert, die Installation des Moduls zu genehmigen.

Pipelineeingaben suchen leicht gemacht

Das MrToolkit Modul enthält eine Funktion mit dem Namen Get-MrPipelineInput. Dieses Cmdlet wurde entwickelt, um Benutzern eine bequeme Methode zum Identifizieren der Parameter eines Befehls bereitzustellen, der die Pipelineeingabe akzeptiert. Insbesondere werden drei wichtige Aspekte offenbart:

  • Welche Parameter eines Befehls Pipeline-Eingaben empfangen können
  • Der Typ des Objekts, das jeder Parameter akzeptiert
  • Ob sie Pipeline-Eingaben akzeptieren nach Wert oder nach Eigenschaftsname

Diese Funktion vereinfacht den Prozess des Verständnisses und der Nutzung der Pipelinefunktionen von PowerShell-Befehlen erheblich.

Die zuvor durch die Analyse der Hilfedokumentation erhaltenen Informationen können mithilfe dieser Funktion bestimmt werden.

Get-MrPipelineInput -Name Stop-Service | Format-List
ParameterName                   : InputObject
ParameterType                   : System.ServiceProcess.ServiceController[]
ValueFromPipeline               : True
ValueFromPipelineByPropertyName : False

ParameterName                   : Name
ParameterType                   : System.String[]
ValueFromPipeline               : True
ValueFromPipelineByPropertyName : True

Zusammenfassung

In diesem Kapitel haben Sie die Feinheiten von PowerShell Einzeilern kennengelernt. Außerdem haben Sie gelernt, dass die Anzahl der physischen Zeilen eines Befehls für die Klassifizierung als PowerShell-Einzeiler irrelevant ist. Außerdem haben Sie wichtige Konzepte wie z. B. das Linksfiltern, die Pipeline und PowerShellGet kennengelernt.

Rezension

  1. Was ist ein PowerShell-Einzeiler?
  2. Welches sind einige Zeichen, bei denen in der PowerShell natürliche Zeilenumbrüche auftreten können?
  3. Warum sollten Sie links filtern?
  4. Welche zwei Möglichkeiten gibt es, wie ein PowerShell-Befehl Pipelineeingaben akzeptieren kann?
  5. Warum sollten Sie die im PowerShell-Katalog gefundenen Befehlen nicht als vertrauenswürdig einstufen?

Referenzen

Nächste Schritte

Im nächsten Kapitel erfahren Sie mehr über Formatierung, Aliase, Anbieter und Vergleichsoperatoren.