WhatIf und Confirm
WhatIf und Confirm sind Standard-Parameter, die oft bei Cmdlets, die Änderungen an Daten durchführen (Set-*, Remove-*), verfügbar sind. Rufen Sie ein Cmdlet mit -Whatif auf, wird statt der eigentlichen Funktion nur eine "Was wäre wenn"-Meldung ausgegeben:
PS C:\Windows> Get-ChildItem -File | Remove-Item -WhatIf
> WhatIf: Ausführen des Vorgangs "Datei entfernen" für das Ziel "C:\Windows\bfsvc.e-xe".
> WhatIf: Ausführen des Vorgangs "Datei entfernen" für das Ziel "C:\Windows\bootstat. dat".
> WhatIf: Ausführen des Vorgangs "Datei entfernen" für das Ziel "C:\Windows\comsetup. log".
> WhatIf: Ausführen des Vorgangs "Datei entfernen" für das Ziel "C:\Windows\ctfile. rfc".
> WhatIf: Ausführen des Vorgangs "Datei entfernen" für das Ziel "C:\Windows\diagerr. xml".
> WhatIf: Ausführen des Vorgangs "Datei entfernen" für das Ziel "C:\Windows\diagwrn. xml".
> WhatIf: Ausführen des Vorgangs "Datei entfernen" für das Ziel "C:\Windows\DirectX. log".
> WhatIf: Ausführen des Vorgangs "Datei entfernen" für das Ziel "C:\Windows\DPINST. LOG".
> WhatIf: Ausführen des Vorgangs "Datei entfernen" für das Ziel "C:\Windows\DtcIn-stall.log".
> WhatIf: Ausführen des Vorgangs "Datei entfernen" für das Ziel "C:\Windows\Educatio-n.xml".
> WhatIf: Ausführen des Vorgangs "Datei entfernen" für das Ziel "C:\Windows\Enterpri-se.xml".
> WhatIf: Ausführen des Vorgangs "Datei entfernen" für das Ziel "C:\Windows\explorer. exe".
> WhatIf: Ausführen des Vorgangs "Datei entfernen" für das Ziel "C:\Windows\gdrv. sys".
> WhatIf: Ausführen des Vorgangs "Datei entfernen" für das Ziel "C:\Windows\gdrv2. sys".
Geben Sie -Confirm beim Aufruf eines Kommandos an, wird das Kommando ganz normal ausgeführt, Powershell fordert aber vor der Ausführung eine Bestätigung an.
Get-ChildItem -File | Remove-Item -Confirm
> Bestätigung
> Möchten Sie diese Aktion wirklich ausführen?
> Ausführen des Vorgangs "Datei entfernen" für das Ziel "C:\Windows\system32\0".
> [J] Ja [A] Ja, alle [N] Nein [K] Nein, keine [H] Anhalten [?] Hilfe (Standard ist "J"):
Sie können -whatif und -confirm für Ihre eigenen Funktionen verwenden. Binden Sie dazu zuerst das [CmdletBinding]-Attribut mit dem Argument SupportsShouldProcess=$true ein. Das [CmdletBinding]-Attribut muss direkt vor dem Parameter-Block stehen.
function Remove-Windows
{
[CmdletBinding(SupportsShouldProcess=$true)]
param()
remove-item -Path F:\Windows\*.*
}
Wenn Sie SupportsShouldprocess aktivieren, erlaubt Ihre Funktion sofort den Einsatz von -whatif und -confirm:

Allerdings setzen Sie mit diesem Parameter nur für den Ablauf der Funktion die Standardvariable $WhatIfPreference bzw. $Confirmpreference auf $true, was dazu führt, dass alle Kommandos in Ihrer Funktion so ausgeführt werden, als hätten Sie die Parameter beim Aufruf explizit angegeben. Sie können über die Methode ShouldProcess(), die über $PSCmdlet verfügbar gemacht wird, aber Ihre eigene Prüfung implementieren. Die Methode Shouldprocess() arbeitet im Prinzip wie die vielen Test-Cmdlets. Sie prüft, ob -WhatIf oder -Confirm gesetzt wurden, und gibt $true zurück, wenn sie NICHT gesetzt sind, und $false, wenn sie gesetzt sind. Schauen Sie sich dazu folgendes Skript an:
function Set-VMDefault
{
[CmdletBinding(SupportsShouldProcess=$true)]
param(
[Parameter(ValueFromPipeline)]
$VmName
)
process {
If ( $PSCmdlet.ShouldProcess($VmName.VMName) ) {
Set-VM -VMName $VmName -CheckpointType Production - ProcessorCount 2
}
}
}
Die Funktion Set-VMDefault setzt für eine oder mehrere virtuelle Hyper-V Maschinen den Typ des Snapshots und die Anzahl der virtuellen CPUs. Da die Funktion Pipeline-Eingaben akzeptiert, sollte sie auch Whatif und -confirm unterstützen. Der Befehl zum Ändern der virtuellen Maschine wird daher in ein if-Statement eingepackt:
If ( $PSCmdlet.ShouldProcess( $VmName.VMName ))
{
Set-VM -VMName $VmName -CheckpointType Production -ProcessorCount 2
}
Der Skriptblock des if wird nur ausgeführt, wenn $PSCmdlet.Shouldprocess() wahr zurückgibt, wenn also -Whatif und -Confirm NICHT gesetzt sind. Ansonsten gibt Shouldprocess() $false zurück und schreibt eine Ausgabe direkt in den Host zurück:
"DC1","DC2" | Set-VMDefault -WhatIf
> WhatIf: Ausführen des Vorgangs "Set-VMDefault" für das Ziel "DC1".
> WhatIf: Ausführen des Vorgangs "Set-VMDefault" für das Ziel "DC2".
Die Textausgabe besteht aus dem Standardtext "WhatIf: Ausführen des Vorgangs {0} für das Ziel {1}". In Position {0} wird der Name der Funktion eingefügt, der ausgeführt wird, und in {1} der Wert, der ShouldProcess() als Parameter in runden Klammern übergeben wurde – in diesem Fall also der Name der virtuellen Maschine. Die gleiche Ausgabe wird bei -Confirm angezeigt, allerdings mit einer Abfrage, ob die Aktion wirklich ausgeführt werden soll.
Die Methode Shouldprocess() verfügt noch über eine Reihe von Parametern, um die Ausgabe anzupassen. Die Überladungen (=Parameter, die übergeben werden können) sehen so aus:
OverloadDefinitions
-------------------
bool ShouldProcess(string target)
bool ShouldProcess(string target, string action)
bool ShouldProcess(string verboseDescription, string verboseWarning, string caption)
bool ShouldProcess(string verboseDescription, string verboseWarning, string caption,
[ref] System.Management.Automation.ShouldProcessReason shouldProcessReason)
Die erste Überladung wurde im Beispiel bereits angewendet. Der Target-String definiert, was in der Ausgabe für das Ziel angegeben werden soll:
( $PSCmdlet.ShouldProcess( $VmName ))
Sie können den Namen der Funktion aber auch durch eine eigene Aktion ersetzen:
( $PSCmdlet.ShouldProcess($VmName,'Mache kaputt'))
Die Ausgabe lautet dann:
"DC1","DC2" | Set-VMDefault -WhatIf
> WhatIf: Ausführen des Vorgangs "Mache kaputt" für das Ziel "DC1".
> WhatIf: Ausführen des Vorgangs "Mache kaputt" für das Ziel "DC2".
Die dritte Überladung erlaubt es Ihnen, eine komplett eigene Meldung auszugeben. Sie wird im Parameter VerboseDescription übergeben. Der Parameter VerboseWarning wird verwendet, wenn Sie die Funktion statt mit -WhatIf mit -Confirm aufrufen. Der dritte Parameter Caption gibt einfach nur den Namen des Confirm-Fensters an:
function Set-VMDefault
{
[CmdletBinding(SupportsShouldProcess=$true)]
param(
[Parameter(ValueFromPipeline)]
$VmName
)
process {
If ( $PSCmdlet.ShouldProcess("Mache kaputt","Bitte bestätigen","Don´t do it!" )
{
Set-VM -VMName $VmName -CheckpointType Production -ProcessorCount 2
}
}
}
-Confirm fordert jetzt eine Bestätigung mit Ihrem individuellen Text.

-WhatIf verwendet den Text, der im ersten Parameter VerboseDescription übergeben wurde.
"DC1","DC2" | Set-VMDefault -WhatIf
> WhatIf: Etwas Schlimmes passiert WhatIf: Etwas Schlimmes passiert
Die letzte Überladung erlaubt Ihnen, den Grund für das Ausführen von Shouldprocess() zurückzugeben. Die Rückgabe erfolgt byReference (erkennbar am [ref] vor dem Parametertyp in der Überladung), was bedeutet, dass die Daten nur einer bestehenden Variablen zugewiesen werden können ("referenziert").
$Reason = New-Object -TypeName System.Management.Automation.ShouldProcessReason
If ( $PSCmdlet.ShouldProcess($VmName,"Mache kaputt",'bla',[ref]$Reason) )
{
Set-VM -VMName $VmName -CheckpointType Production -ProcessorCount 2
}
$Reason
In der ersten Zeile wird eine neue Enumeration vom Typ [System.Management.Automation.ShouldProcessReason] erzeugt. Enumerationen sind im Prinzip vordefinierte Arrays, die eine Liste von festgelegten Werten erhalten. Die Enumeration ShouldProcessReason kennt tatsächlich zwei Werte: None und WhatIf. Dies sind auch die beiden möglichen Rückgabewerte, die Sie aus dem Parameter shouldpro-cessreason entnehmen können.
In der Shouldprocess()-Methode übergeben Sie die Variable $Reason referentiell (erkennbar an der [ref]-Anweisung). Referentiell bedeutet, dass Shouldprocess() kein neues Objekt für die Rückgabe erzeugt, sondern das von Ihnen übergebene Objekt verwendet, um den Rückgabegrund zu speichern. Wenn Sie nach Ausführung von Shouldprocess() die Variable $Reason abfragen, gibt sie "WhatIf" zurück, wenn die Funktion mit dem Parameter -Whatif aufgerufen wurde, und sonst None.
Eine noch ausführlichere Beschreibung von Whatif und Confirm finden Sie im Artikel Powershell: Everything you wanted to know about ShouldProcess.