Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Manchmal muss ein Cmdlet den Zustand des Systems ändern, nicht nur den Zustand der Windows PowerShell-Laufzeit. In diesen Fällen sollte das Cmdlet dem Benutzer die Möglichkeit geben, zu bestätigen, ob die Änderung vorgenommen werden soll.
Um die Bestätigung zu unterstützen, muss ein Cmdlet zwei Schritte ausführen.
Deklarieren Sie, dass das Cmdlet die Bestätigung unterstützt, wenn Sie das Attribut System.Management.Automation.CmdletAttribute angeben, indem Sie das Schlüsselwort SupportsShouldProcess auf
truefestlegen.Rufen Sie System.Management.Automation.Cmdlet.ShouldProcess während der Ausführung des Cmdlets auf (siehe das folgende Beispiel).
Durch die Unterstützung der Bestätigung macht ein Cmdlet die parameter Confirm und WhatIf verfügbar, die von Windows PowerShell bereitgestellt werden, und erfüllt außerdem die Entwicklungsrichtlinien für Cmdlets (Weitere Informationen zu Cmdlet-Entwicklungsrichtlinien finden Sie unter Cmdlet Development Guidelines.).
Ändern des Systems
Der Akt der "Änderung des Systems" bezieht sich auf jedes Cmdlet, das den Zustand des Systems außerhalb von Windows PowerShell potenziell ändert. Das Beenden eines Prozesses, das Aktivieren oder Deaktivieren eines Benutzerkontos oder das Hinzufügen einer Zeile zu einer Datenbanktabelle sind alle Änderungen am System, die bestätigt werden sollen.
Im Gegensatz dazu ändern Vorgänge, die Daten lesen oder vorübergehende Verbindungen herstellen, das System nicht und erfordern in der Regel keine Bestätigung. Die Bestätigung ist auch für Aktionen nicht erforderlich, deren Wirkung auf die Windows PowerShell-Laufzeit beschränkt ist, z. B. Set-Variable. Cmdlets, die möglicherweise eine dauerhafte Änderung vornehmen, sollten SupportsShouldProcess deklarieren und System.Management.Automation.Cmdlet.ShouldProcess nur aufrufen, wenn sie eine dauerhafte Änderung vornehmen möchten.
Hinweis
Die Bestätigung von "ShouldProcess" gilt nur für Cmdlets. Wenn ein Befehl oder ein Skript den Ausführungsstatus eines Systems durch direktes Aufrufen von .NET-Methoden oder -Eigenschaften oder durch Aufrufen von Anwendungen außerhalb von Windows PowerShell ändert, ist diese Form der Bestätigung nicht verfügbar.
Das StopProc-Cmdlet
In diesem Thema wird ein Stop-Proc-Cmdlet beschrieben, das versucht, Prozesse zu beenden, die mithilfe des cmdlets Get-Proc abgerufen werden (beschrieben in Creating Your First Cmdlet).
Definieren des Cmdlets
Der erste Schritt beim Erstellen von Cmdlets ist immer das Benennen des Cmdlets und das Deklarieren der .NET-Klasse, die das Cmdlet implementiert. Da Sie ein Cmdlet zum Ändern des Systems schreiben, sollte es entsprechend benannt werden. Dieses Cmdlet stoppt Systemprozesse, sodass der hier ausgewählte Verbname "Stop" ist, definiert durch die System.Management.Automation.VerbsLifecycle Klasse, mit dem Substantiv "Proc", um anzugeben, dass das Cmdlet die Prozesse stoppt. Weitere Informationen zu genehmigten Cmdlet-Verben finden Sie unter Cmdlet Verb Names.
Es folgt die Klassendefinition für dieses Stop-Proc-Cmdlet.
[Cmdlet(VerbsLifecycle.Stop, "Proc",
SupportsShouldProcess = true)]
public class StopProcCommand : Cmdlet
Beachten Sie, dass im System.Management.Automation.CmdletAttribute--Deklaration das Schlüsselwort SupportsShouldProcess Attribut auf true festgelegt ist, damit das Cmdlet Aufrufe an System.Management.Automation.Cmdlet.ShouldProcess und System.Management.Automation.Cmdlet.ShouldContinue.
Ohne diesen Schlüsselwortsatz stehen dem Benutzer die Parameter Confirm und WhatIf nicht zur Verfügung.
Extrem destruktive Aktionen
Einige Vorgänge sind äußerst destruktiv, z. B. das Neuformatieren einer aktiven Festplattenpartition. In diesen Fällen sollte das Cmdlet ConfirmImpact = ConfirmImpact.High beim Deklarieren des attributs System.Management.Automation.CmdletAttribute festlegen. Diese Einstellung erzwingt das Cmdlet, die Benutzerbestätigung anzufordern, auch wenn der Benutzer den parameter Confirm nicht angegeben hat. Cmdlet-Entwickler sollten jedoch vermeiden, ConfirmImpact für Vorgänge zu verwenden, die einfach destruktiv sind, z. B. das Löschen eines Benutzerkontos. Denken Sie daran, dass ConfirmImpact auf System.Management.Automation.ConfirmImpactHighfestgelegt ist.
Ebenso sind einige Vorgänge unwahrscheinlich, dass sie destruktiv sind, obwohl sie theoretisch den Ausführungszustand eines Systems außerhalb von Windows PowerShell ändern. Solche Cmdlets können ConfirmImpact auf System.Management.Automation.ConfirmImpact.Lowfestlegen.
Dadurch werden Bestätigungsanforderungen umgangen, bei denen der Benutzer aufgefordert wurde, nur mittlere Auswirkungen und Vorgänge mit hohen Auswirkungen zu bestätigen.
Definieren von Parametern für die Systemänderung
In diesem Abschnitt wird beschrieben, wie Sie die Cmdlet-Parameter definieren, einschließlich der Parameter, die zur Unterstützung der Systemänderung erforderlich sind. Informationen zum Definieren von Parametern finden Sie unter Hinzufügen von Parametern, die die Befehlszeileneingabe verarbeiten.
Das Cmdlet Stop-Proc definiert drei Parameter: Name, Forceund PassThru.
Der Name-Parameter entspricht der Name Eigenschaft des Prozesseingabeobjekts. Beachten Sie, dass der parameter Name in diesem Beispiel obligatorisch ist, da das Cmdlet fehlschlägt, wenn kein benannter Prozess zum Beenden vorhanden ist.
Der Force-Parameter ermöglicht es dem Benutzer, Aufrufe von System.Management.Automation.Cmdlet.ShouldContinueaußer Kraft zu setzen.
Tatsächlich sollte jedes Cmdlet, das System.Management.Automation.Cmdlet.ShouldContinue aufruft, über einen Force Parameter verfügen, sodass das Cmdlet, wenn Force angegeben wird, den Aufruf von System.Management.Automation.Cmdlet.ShouldContinue überspringt und mit dem Vorgang fortfährt. Beachten Sie, dass sich dies nicht auf Aufrufe von System.Management.Automation.Cmdlet.ShouldProcessauswirkt.
Mit dem parameter PassThru kann der Benutzer angeben, ob das Cmdlet ein Ausgabeobjekt über die Pipeline übergibt, in diesem Fall, nachdem ein Prozess beendet wurde. Beachten Sie, dass dieser Parameter anstelle einer Eigenschaft des Eingabeobjekts an das Cmdlet selbst gebunden ist.
Dies ist die Parameterdeklaration für das Cmdlet Stop-Proc.
[Parameter(
Position = 0,
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true
)]
public string[] Name
{
get { return processNames; }
set { processNames = value; }
}
private string[] processNames;
/// <summary>
/// Specify the Force parameter that allows the user to override
/// the ShouldContinue call to force the stop operation. This
/// parameter should always be used with caution.
/// </summary>
[Parameter]
public SwitchParameter Force
{
get { return force; }
set { force = value; }
}
private bool force;
/// <summary>
/// Specify the PassThru parameter that allows the user to specify
/// that the cmdlet should pass the process object down the pipeline
/// after the process has been stopped.
/// </summary>
[Parameter]
public SwitchParameter PassThru
{
get { return passThru; }
set { passThru = value; }
}
private bool passThru;
Überschreiben einer Eingabeverarbeitungsmethode
Das Cmdlet muss eine Eingabeverarbeitungsmethode überschreiben. Der folgende Code veranschaulicht die System.Management.Automation.Cmdlet.ProcessRecord Außerkraftsetzung, die im Beispiel-Stop-Proc-Cmdlet verwendet wird. Für jeden angeforderten Prozessnamen stellt diese Methode sicher, dass der Prozess kein spezieller Prozess ist, versucht, den Prozess zu beenden, und sendet dann ein Ausgabeobjekt, wenn der parameter PassThru angegeben ist.
protected override void ProcessRecord()
{
foreach (string name in processNames)
{
// For every process name passed to the cmdlet, get the associated
// process(es). For failures, write a non-terminating error
Process[] processes;
try
{
processes = Process.GetProcessesByName(name);
}
catch (InvalidOperationException ioe)
{
WriteError(new ErrorRecord(ioe,"Unable to access the target process by name",
ErrorCategory.InvalidOperation, name));
continue;
}
// Try to stop the process(es) that have been retrieved for a name
foreach (Process process in processes)
{
string processName;
try
{
processName = process.ProcessName;
}
catch (Win32Exception e)
{
WriteError(new ErrorRecord(e, "ProcessNameNotFound",
ErrorCategory.ReadError, process));
continue;
}
// Call Should Process to confirm the operation first.
// This is always false if WhatIf is set.
if (!ShouldProcess(string.Format("{0} ({1})", processName,
process.Id)))
{
continue;
}
// Call ShouldContinue to make sure the user really does want
// to stop a critical process that could possibly stop the computer.
bool criticalProcess =
criticalProcessNames.Contains(processName.ToLower());
if (criticalProcess &&!force)
{
string message = String.Format
("The process \"{0}\" is a critical process and should not be stopped. Are you sure you wish to stop the process?",
processName);
// It is possible that ProcessRecord is called multiple times
// when the Name parameter receives objects as input from the
// pipeline. So to retain YesToAll and NoToAll input that the
// user may enter across multiple calls to ProcessRecord, this
// information is stored as private members of the cmdlet.
if (!ShouldContinue(message, "Warning!",
ref yesToAll,
ref noToAll))
{
continue;
}
} // if (criticalProcess...
// Stop the named process.
try
{
process.Kill();
}
catch (Exception e)
{
if ((e is Win32Exception) || (e is SystemException) ||
(e is InvalidOperationException))
{
// This process could not be stopped so write
// a non-terminating error.
string message = String.Format("{0} {1} {2}",
"Could not stop process \"", processName,
"\".");
WriteError(new ErrorRecord(e, message,
ErrorCategory.CloseError, process));
continue;
} // if ((e is...
else throw;
} // catch
// If the PassThru parameter argument is
// True, pass the terminated process on.
if (passThru)
{
WriteObject(process);
}
} // foreach (Process...
} // foreach (string...
} // ProcessRecord
Aufrufen der ShouldProcess-Methode
Die Eingabeverarbeitungsmethode des Cmdlets sollte die System.Management.Automation.Cmdlet.ShouldProcess Methode aufrufen, um die Ausführung eines Vorgangs zu bestätigen, bevor eine Änderung (z. B. das Löschen von Dateien) an den Ausführungszustand des Systems vorgenommen wird. Auf diese Weise kann die Windows PowerShell-Laufzeit das richtige Verhalten "WhatIf" und "Confirm" innerhalb der Shell bereitstellen.
Hinweis
Wenn ein Cmdlet angibt, dass es unterstützt wird, das Verfahren verarbeiten soll und das System.Management.Automation.Cmdlet.ShouldProcess Aufruf nicht ausführen kann, kann der Benutzer das System unerwartet ändern.
Der Aufruf von System.Management.Automation.Cmdlet.ShouldProcess sendet den Namen der Ressource, die an den Benutzer geändert werden soll, wobei die Windows PowerShell-Laufzeit alle Befehlszeileneinstellungen oder Einstellungsvariablen berücksichtigt, um zu bestimmen, was dem Benutzer angezeigt werden soll.
Das folgende Beispiel zeigt den Aufruf von System.Management.Automation.Cmdlet.ShouldProcess aus der Außerkraftsetzung der System.Management.Automation.Cmdlet.ProcessRecord-Methode im Beispiel-Stop-Proc Cmdlet.
if (!ShouldProcess(string.Format("{0} ({1})", processName,
process.Id)))
{
continue;
}
Aufrufen der ShouldContinue-Methode
Der Aufruf der System.Management.Automation.Cmdlet.ShouldContinue Methode sendet eine sekundäre Nachricht an den Benutzer. Dieser Aufruf erfolgt nach dem Aufruf von System.Management.Automation.Cmdlet.ShouldProcess gibt true zurück und wenn der parameter Force nicht auf truefestgelegt wurde. Der Benutzer kann dann Feedback geben, um zu sagen, ob der Vorgang fortgesetzt werden soll. Ihr Cmdlet ruft System.Management.Automation.Cmdlet.ShouldContinue als zusätzliche Überprüfung auf potenziell gefährliche Systemänderungen auf, oder wenn Sie dem Benutzer ja-to-all und no-to-alle Optionen bereitstellen möchten.
Das folgende Beispiel zeigt den Aufruf System.Management.Automation.Cmdlet.ShouldContinue aus der Außerkraftsetzung der System.Management.Automation.Cmdlet.ProcessRecord-Methode im Beispiel-Stop-Proc-Cmdlet.
if (criticalProcess &&!force)
{
string message = String.Format
("The process \"{0}\" is a critical process and should not be stopped. Are you sure you wish to stop the process?",
processName);
// It is possible that ProcessRecord is called multiple times
// when the Name parameter receives objects as input from the
// pipeline. So to retain YesToAll and NoToAll input that the
// user may enter across multiple calls to ProcessRecord, this
// information is stored as private members of the cmdlet.
if (!ShouldContinue(message, "Warning!",
ref yesToAll,
ref noToAll))
{
continue;
}
} // if (criticalProcess...
Beenden der Eingabeverarbeitung
Die Eingabeverarbeitungsmethode eines Cmdlets, das Systemänderungen vorgibt, muss eine Möglichkeit zum Beenden der Eingabeverarbeitung bieten. Im Falle dieses Stop-Proc Cmdlets wird ein Aufruf von der System.Management.Automation.Cmdlet.ProcessRecord-Methode an die System.Diagnostics.Process.Kill* Methode ausgeführt. Da der parameter PassThru auf truefestgelegt ist, ruft System.Management.Automation.Cmdlet.ProcessRecord auch System.Management.Automation.Cmdlet.WriteObject auf, um das Prozessobjekt an die Pipeline zu senden.
Codebeispiel
Den vollständigen C#-Beispielcode finden Sie unter StopProcessSample01 Sample.
Definieren von Objekttypen und Formatierungen
Windows PowerShell übergibt Informationen zwischen Cmdlets mithilfe von .NET-Objekten. Daher muss ein Cmdlet möglicherweise einen eigenen Typ definieren, oder das Cmdlet muss einen vorhandenen Typ erweitern, der von einem anderen Cmdlet bereitgestellt wird. Weitere Informationen zum Definieren neuer Typen oder zum Erweitern vorhandener Typen finden Sie unter Erweitern von Objekttypen und Formatierungen.
Erstellen des Cmdlets
Nach der Implementierung eines Cmdlets muss es über ein Windows PowerShell-Snap-In bei Windows PowerShell registriert werden. Weitere Informationen zum Registrieren von Cmdlets finden Sie unter Registrieren von Cmdlets, Anbietern und Hostanwendungen.
Testen des Cmdlets
Wenn Ihr Cmdlet bei Windows PowerShell registriert wurde, können Sie es testen, indem Sie es in der Befehlszeile ausführen. Hier sind mehrere Tests, die das cmdlet Stop-Proc testen. Weitere Informationen zur Verwendung von Cmdlets über die Befehlszeile finden Sie in der Erste Schritte mit Windows PowerShell.
Starten Sie Windows PowerShell, und verwenden Sie das cmdlet Stop-Proc, um die Verarbeitung wie unten dargestellt zu beenden. Da das Cmdlet den parameter
Nameals obligatorisch angibt, fragt das Cmdlet den Parameter ab.PS> Stop-ProcDie folgende Ausgabe wird angezeigt.
Cmdlet Stop-Proc at command pipeline position 1 Supply values for the following parameters: Name[0]:Lassen Sie uns nun das Cmdlet verwenden, um den Prozess mit dem Namen "NOTEPAD" zu beenden. Das Cmdlet fordert Sie auf, die Aktion zu bestätigen.
PS> Stop-Proc -Name notepadDie folgende Ausgabe wird angezeigt.
Confirm Are you sure you want to perform this action? Performing operation "Stop-Proc" on Target "notepad (4996)". [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): YVerwenden Sie Stop-Proc, wie gezeigt, um den kritischen Prozess mit dem Namen "WINLOGON" zu beenden. Sie werden aufgefordert, diese Aktion auszuführen, da das Betriebssystem neu gestartet wird.
PS> Stop-Proc -Name WinlogonDie folgende Ausgabe wird angezeigt.
Confirm Are you sure you want to perform this action? Performing operation "Stop-Proc" on Target "winlogon (656)". [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): Y Warning! The process " winlogon " is a critical process and should not be stopped. Are you sure you wish to stop the process? [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): NVersuchen wir nun, den WINLOGON-Prozess zu beenden, ohne eine Warnung zu erhalten. Beachten Sie, dass dieser Befehlseintrag den parameter
Forceverwendet, um die Warnung außer Kraft zu setzen.PS> Stop-Proc -Name winlogon -ForceDie folgende Ausgabe wird angezeigt.
Confirm Are you sure you want to perform this action? Performing operation "Stop-Proc" on Target "winlogon (656)". [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): N
Siehe auch
Hinzufügen von Parametern, die Command-Line Eingabeeingaben
Erweitern von Objekttypen und Formatierungen