PowerShell PSDefaultParameterValues

Inhaltsverzeichnis

Post Featured Image

PSDefaultParameterValues ist eine Hashtabelle, mit der wir die Standardwerte eines beliebigen Parameters für ein beliebiges Cmdlet mit den von uns gewünschten Standardwerten überschreiben können.

Das Cmdlets verwendet dann den benutzerdefinierten Standardwert, sofern im Befehl kein anderer Wert angeben wird.

Das klingt vielleicht nicht nach der wichtigsten Funktion, aber glauben Sie mir, nach diesem Beitrag werden Sie sich fragen, wie Sie jemals ohne sie gearbeitet haben.

 

So verwenden Sie PowerShell PSDefaultParameterValues

 Parameter

Schauen wir uns genauer an, wie man einen Standardwert festlegt.

$PSDefaulParameterValues.Add("Command:Parameter","Value")

Wie Sie sehen können, fügen wir einfach einen neuen Schlüssel zur Hashtabelle hinzu und geben das Cmdlet und den Parameter an, für den ein Standardwert festgelegt werden soll, getrennt durch ein : .

Der Wert muss natürlich von einem Typ sein, der vom Parameter akzeptiert wird, sonst erhalten Sie Fehler bei der Verwendung des Cmdlets.
Ein konkretes Beispiel wäre die Angabe eines benutzerdefinierten Trennzeichens für Write-Host.

# Default
PS> Write-Host "Hello","World"
Hello World
# Adding the custom default
PS> $PSDefaultParameterValues.Add("Write-Host:Separator", "`n")
# Changed output
PS> Write-Host "Hello","World"
Hello
World


Switches

Für Switch-Parameter gilt fast dasselbe, wir verwenden nur einen Booleschen Wert, um anzugeben, ob der Schalter vorhanden $true oder nicht vorhanden $false sein soll.

Wir könnten ihn z. B. verwenden, um das Debugging für alle Invoke-WebRequest-Aufrufe in einem Skript auf einmal zu aktivieren.

# Default, no verbosity
PS> (Invoke-WebRequest "https://ps1.guru").StatusCode 
200
# Adding the custom default
PS> $PSDefaultParameterValues.Add("Invoke-WebRequest:Verbose", $true)
# Changed output, with verbosity
PS> (Invoke-WebRequest "https://ps1.guru").StatusCode
VERBOSE: GET https://ps1.guru/ with 0-byte payload
VERBOSE: received 4801-byte response of content type text/html
200


Wildcards

Wir bleiben beim Verbose-Parameter aus dem vorherigen Beispiel und können ihn mit Platzhaltern für alle Cmdlets festlegen. Dies ist ein nützlicher Trick, den ich häufig zum Debuggen meiner Scripts verwende.

PS> $PSDefaultParameterValues.Add("*:Verbose", $true)


Erweiterte Werte

Anstelle eines statischen Werts ist es möglich, einen Scriptblock als Vorgabe für einen Parameter zu verwenden. Dies ermöglicht ein extremes Maß an Anpassung in Abhängigkeit von Systemzuständen wie dem Host, auf dem Sie sich befinden, dem aktuellen Verzeichnis und vielem mehr.

Um bei unserem Verbosität-Beispiel von vorhin zu bleiben, könnten wir das Verhalten von einer Variable $verbose abhängig machen.

PS> $PSDefaultParameterValues.Add("*:Verbose", {$verbose -eq $true})

Jetzt können wir die standardmäßige Verbosität unserer Sitzung durch Setzen und Entfernen einer Variable steuern. Denken Sie daran, dass dieser Scriptblock jedes Mal ausgeführt wird, wenn Sie das Cmdlet verwenden, also halten Sie ihn schnell.

Sie können ihn wie folgt messen:

PS> Measure-Command {$verbose -eq $true} | ft
Days	Hours	Minutes Seconds Milliseconds
---- 	----- 	------- ------- ------------
0       0       0       0       0


Beständigkeit

Alles, was wir bis jetzt gemacht haben, bleibt nicht zwischen Sitzungen bestehen. Damit die Standardwerte dies tun, müssen Sie sie zu Ihrem Profil hinzufügen. Um alle Vorgaben zu finden, die Sie in der aktuellen Sitzung hinzugefügt haben, fragen Sie einfach die Historie wie folgt ab.

Get-History | Where-Object CommandLine -like "`$PSDEfaultParameterValues*"

 

Praxisbeispiel: so setzen Sie PSDefaultParameterValues ein

Sie fragen sich vielleicht, warum das nützlich sein soll, lassen Sie es mich an einem kurzen Beispiel zeigen.

Angenommen, Sie exportieren immer Daten in CSV-Dateien, die jemand in Excel öffnen soll. Wenn er einfach auf Ihre CSV-Datei doppelklickt, wird das Ergebnis nicht besonders gut sein.

download-2

Abb. 1: Importierte Daten in Excel, bei denen die Trennzeichen anzeigt werden

Die meisten von uns würden dann einfach eine neue Excel-Datei öffnen und die Daten mit „Daten > Aus Text“ importieren, sich durch die Fülle von Bildschirmfenstern klicken und Excel so konfigurieren, dass es das Trennzeichen tatsächlich erkennt.

Screenshot of an Excel data sheet. You can see several rows of data for which the import settings were manually edited so that delimiters were recognized and correctly interpreted

Abb. 2: Manuell editierter Daten-Import

Es gibt aber einen besseren Weg! Anstatt nur CSV zu exportieren:

Get-Process -Name Microsoft* | Export-Csv msproc.csv

können Sie ein benutzerdefiniertes Trennzeichen angeben und dabei Typinformationen und Klammern entfernen:

Get-Process -Name Microsoft* | Export-Csv bettermsproc.csv -Delimiter ";"
-NoTypeInformation -NoClobber

Jetzt wird beim Importieren, Exportieren, Konvertieren von und Konvertieren nach CSV das Trennzeichen ; verwendet und keine Typinformationen oder Klammern sind enthalten.

Wenn Sie die resultierende CSV-Datei direkt mit Excel öffnen, sehen Sie ein Ergebnis, das dem des Datenimport-Tanzes ähnelt, den wir vorher gemacht haben.

Screenshot of an Excel data sheet. You can see several rows with data that are clearly structured, similar to the example in Figure 2

Abb. 3: Daten-Import nach Konfiguration mit PowerShell

Aber immer diese Parameter abzutippen ist umständlich und hat eine hohe Fehlertoleranz.
An dieser Stelle kommen die Standardwerte ins Spiel

$PSDefaultParams.Add("Export-Csv:Delimiter", ";")
$PSDefaultParams.Add("Export-Csv:NoTypeInformation", $true)
$PSDefaultParams.Add("Export-Csv:NoClobber", $true)

Damit können wir zurückgehen und einfach Export-Csv verwenden und die resultierende Datei wird in Excel genau wie erwartet geöffnet.
Wir könnten sogar noch einen Schritt weiter gehen und diese Parameter für alle Cmdlets in der CSV-Familie mithilfe von Platzhaltern ändern.

$PSDefaultParams.Add("*-Csv:Delimiter", ";")
$PSDefaultParams.Add("*-Csv:NoTypeInformation", $true)
$PSDefaultParams.Add("*-Csv:NoClobber", $true)


 

PSDefaultParameterValues in Scripten

Nachdem Sie nun etwas über $PSDefaulParameterValues erfahren haben, möchte ich Sie warnen –  verwenden Sie sie bitte nicht in Ihren Scripts.

Dafür gibt es einige gute Gründe:

  • Andere Anwender haben möglicherweise nicht dieselben Standardwerte wie Sie und deshalb wird das Script für sie nicht funktionieren
  • Sie könnten Ihre Voreinstellungen im Laufe der Zeit ändern und das Script wird für Sie nicht mehr funktionieren

Um dies zu vermeiden, empfehle ich Ihnen PSDefaultParameterValues zuerst in allen Scripten zu deaktivieren:

# Disable PSDefaultParameterValues
$PSDefaultParameterValues.Add("Disabled", $true)

Und sie am Ende wieder zu aktivieren:

# Re-Enable PSDefaultParameterValues
$PSDefaultParameterValues.Remove("Disabled")

Zusammenhängende Posts

Über den Autor: