Tworzenie polecenia cmdlet, które modyfikuje system
Czasami polecenie cmdlet musi zmodyfikować stan działania systemu, a nie tylko stan Windows PowerShell uruchomieniowego. W takich przypadkach polecenie cmdlet powinno umożliwić użytkownikowi potwierdzenie, czy wprowadzić zmianę.
Aby zapewnić obsługę potwierdzenia, polecenie cmdlet musi wykonać dwie czynności.
Zadeklaruj, że polecenie cmdlet obsługuje potwierdzenie podczas określania atrybutu System.Management.Automation.CmdletAttribute przez ustawienie słowa kluczowego SupportsShouldProcess na
true
wartość .Wywołaj polecenie System.Management.Automation.Cmdlet.ShouldProcess podczas wykonywania polecenia cmdlet (jak pokazano w poniższym przykładzie).
Obsługując potwierdzenie, polecenie cmdlet uwidacznia parametry i , które są dostarczane przez program Windows PowerShell, a także spełnia wytyczne programowe dotyczące polecenia cmdlet (aby uzyskać więcej informacji na temat wytycznych dotyczących tworzenia polecenia Confirm
WhatIf
cmdlet, zobacz Cmdlet Development Guidelines.).
Zmienianie systemu
Działanie "zmiany systemu" odnosi się do dowolnego polecenia cmdlet, które potencjalnie zmienia stan systemu poza Windows PowerShell. Na przykład zatrzymanie procesu, włączenie lub wyłączenie konta użytkownika albo dodanie wiersza do tabeli bazy danych to wszystkie zmiany w systemie, które należy potwierdzić.
Z kolei operacje odczytu danych lub nawiązywania przejściowych połączeń nie zmieniają systemu i zazwyczaj nie wymagają potwierdzenia. Potwierdzenie nie jest również wymagane w przypadku akcji, których efekt jest ograniczony do wewnątrz Windows PowerShell uruchomieniowego, takich jak set-variable
. Polecenia cmdlet, które mogą lub nie mogą wprowadzić trwałej zmiany, powinny deklarować i wywołać polecenie SupportsShouldProcess
System.Management.Automation.Cmdlet.ShouldProcess tylko wtedy, gdy mają wprowadzić trwałą zmianę.
Uwaga
Potwierdzenie shouldProcess dotyczy tylko polecenia cmdlet. Jeśli polecenie lub skrypt modyfikuje stan działania systemu przez bezpośrednie wywołanie metod lub właściwości .NET lub przez wywołanie aplikacji spoza Windows PowerShell, ta forma potwierdzenia nie będzie dostępna.
Polecenie cmdlet StopProc
W tym temacie opisano Stop-Proc cmdlet, które próbuje zatrzymać procesy pobierane przy użyciu polecenia cmdlet Get-Proc (opisanego w temacie Creating Your First Cmdlet).
Definiowanie polecenia cmdlet
Pierwszym krokiem podczas tworzenia polecenia cmdlet jest zawsze nazewnictwo polecenia cmdlet i deklarowanie klasy .NET, która implementuje polecenie cmdlet. Ponieważ piszesz polecenie cmdlet w celu zmiany systemu, powinno ono mieć odpowiednie nazwy. To polecenie cmdlet zatrzymuje procesy systemowe, więc wybrana tutaj nazwa czasownika to "Stop", zdefiniowana przez klasę System.Management.Automation.Verbslifecycle, z rzeczownikiem "Proc", aby wskazać, że polecenie cmdlet zatrzymuje procesy. Aby uzyskać więcej informacji na temat zatwierdzonych czasowników cmdlet, zobacz Nazwy czasowników polecenia cmdlet.
Poniżej przedstawiono definicję klasy dla tego Stop-Proc cmdlet.
[Cmdlet(VerbsLifecycle.Stop, "Proc",
SupportsShouldProcess = true)]
public class StopProcCommand : Cmdlet
Należy pamiętać, że w deklaracji System.Management.Automation.CmdletAttribute słowo kluczowe atrybutu jest ustawione na wartość , aby umożliwić poleceniem cmdlet w celu wywołania do SupportsShouldProcess
true
system.Management.Automation.Cmdlet.ShouldProcess i System.Management.Automation.Cmdlet.ShouldContinue.
Bez tego słowa kluczowego ustawione Confirm
parametry i nie będą dostępne dla WhatIf
użytkownika.
Niezwykle destrukcyjne akcje
Niektóre operacje są niezwykle destrukcyjne, takie jak ponownie sformatowanie aktywnej partycji dysku twardego. W takich przypadkach polecenie cmdlet powinno zostać ustawione ConfirmImpact
= ConfirmImpact.High
podczas deklarowania atrybutu System.Management.Automation.CmdletAttribute. To ustawienie wymusza żądanie potwierdzenia przez polecenie cmdlet nawet wtedy, gdy użytkownik nie poda Confirm
parametru . Jednak deweloperzy polecenia cmdlet powinni unikać nadwyżek dla operacji, które są po prostu potencjalnie destrukcyjne, takich jak ConfirmImpact
usunięcie konta użytkownika. Pamiętaj, że jeśli ConfirmImpact
jest ustawiona wartość System.Management.Automation.ConfirmImpact
High.
Podobnie niektóre operacje są mało prawdopodobne do destrukcyjnych, chociaż teoretycznie modyfikują stan działania systemu poza Windows PowerShell. Takie polecenia cmdlet można ustawić ConfirmImpact
na System.Management.Automation.Confirmimpact.Low.
Spowoduje to obejście żądań potwierdzenia, w przypadku których użytkownik poprosił o potwierdzenie tylko operacji o średnim i dużym wpływie.
Definiowanie parametrów modyfikacji systemu
W tej sekcji opisano sposób definiowania parametrów polecenia cmdlet, w tym tych, które są potrzebne do obsługi modyfikacji systemu. Aby uzyskać ogólne informacje na temat definiowania parametrów, zobacz Adding Parameters that Process CommandLine Input (Dodawanie parametrów przetwarzających dane wejściowe wiersza polecenia).
Polecenie cmdlet Stop-Proc definiuje trzy parametry: Name
Force
, i PassThru
.
Parametr Name
odpowiada właściwości obiektu Name
wejściowego procesu. Należy pamiętać, że parametr w tym przykładzie jest obowiązkowy, ponieważ polecenie cmdlet zakończy się niepowodzeniem, jeśli nie ma nazwanego procesu do Name
zatrzymania.
Parametr Force
umożliwia użytkownikowi przesłonięcie wywołań metody System.Management.Automation.Cmdlet.ShouldContinue.
W rzeczywistości każde polecenie cmdlet, które wywołuje system.Management.Automation.Cmdlet.ShouldContinue, powinno mieć parametr , dzięki czemu po jego podaniem polecenie cmdlet pomija wywołanie funkcji Force
Force
System.Management.Automation.Cmdlet.ShouldContinue i kontynuuje operację. Należy pamiętać, że nie ma to wpływu na wywołania interfejsu System.Management.Automation.Cmdlet.ShouldProcess.
Parametr umożliwia użytkownikowi wskazanie, czy polecenie cmdlet przekazuje obiekt wyjściowy przez potok, w tym przypadku PassThru
po zatrzymaniu procesu. Należy pamiętać, że ten parametr jest powiązany z samym poleceniem cmdlet, a nie z właściwością obiektu wejściowego.
Oto deklaracja parametru dla polecenia 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;
Zastępowanie metody przetwarzania danych wejściowych
Polecenie cmdlet musi zastąpić metodę przetwarzania danych wejściowych. Poniższy kod ilustruje przesłonięcie System.Management.Automation.Cmdlet.ProcessRecord używane w przykładowym Stop-Proc cmdlet. Dla każdej nazwy żądanego procesu ta metoda zapewnia, że proces nie jest procesem specjalnym, próbuje zatrzymać proces, a następnie wysyła obiekt wyjściowy, jeśli PassThru
określono parametr.
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
Wywoływanie metody ShouldProcess
Metoda przetwarzania danych wejściowych polecenia cmdlet powinna wywołać metodę System.Management.Automation.Cmdlet.ShouldProcess, aby potwierdzić wykonanie operacji przed wprowadzeniem zmiany (na przykład usunięcia plików) do stanu uruchomienia systemu. Dzięki temu Windows PowerShell uruchomieniowe może podać poprawne zachowanie "WhatIf" i "Confirm" w obrębie powłoki.
Uwaga
Jeśli polecenie cmdlet, które obsługuje, powinno przetworzyć i nie może wykonać wywołania System.Management.Automation.Cmdlet.ShouldProcess, użytkownik może nieoczekiwanie zmodyfikować system.
Wywołanie elementu System.Management.Automation.Cmdlet.ShouldProcess wysyła nazwę zasobu, który ma zostać zmieniony, do użytkownika, przy czym środowisko uruchomieniowe programu Windows PowerShell uwzględnia wszystkie ustawienia wiersza polecenia lub zmienne preferencji podczas określania tego, co powinno być wyświetlane użytkownikowi.
W poniższym przykładzie pokazano wywołanie metody System.Management.Automation.Cmdlet.ShouldProcess z zastąpienia metody System.Management.Automation.Cmdlet.ProcessRecord w przykładowym Stop-Proc cmdlet.
if (!ShouldProcess(string.Format("{0} ({1})", processName,
process.Id)))
{
continue;
}
Wywoływanie metody ShouldContinue
Wywołanie metody System.Management.Automation.Cmdlet.ShouldContinue wysyła komunikat pomocniczy do użytkownika. To wywołanie jest wykonane po wywołaniu metody System.Management.Automation.Cmdlet.ShouldProcess zwraca wartość , a jeśli parametr nie true
został ustawiony na Force
true
. Użytkownik może następnie przekazać opinię, aby powiedzieć, czy operacja powinna być kontynuowana. Polecenie cmdlet wywołuje element System.Management.Automation.Cmdlet.ShouldContinue jako dodatkowe sprawdzenie potencjalnie niebezpiecznych modyfikacji systemu lub gdy użytkownik chce udostępnić użytkownikowi opcje "tak do wszystkich" i "nie do wszystkich".
W poniższym przykładzie pokazano wywołanie metody System.Management.Automation.Cmdlet.ShouldContinue z zastąpienia metody System.Management.Automation.Cmdlet.ProcessRecord w przykładowym 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...
Zatrzymywanie przetwarzania danych wejściowych
Metoda przetwarzania danych wejściowych polecenia cmdlet, która wprowadza modyfikacje systemu, musi umożliwiać zatrzymanie przetwarzania danych wejściowych. W przypadku tego polecenia cmdlet Stop-Proc wywołanie metody System.Management.Automation.Cmdlet.ProcessRecord do metody System.Diagnostics.Process.Kill*. Ponieważ parametr jest ustawiony na PassThru
true
wartość , system.Management.Automation.Cmdlet.ProcessRecord wywołuje również polecenie System.Management.Automation.Cmdlet.WriteObject w celu wysłania obiektu procesu do potoku.
Przykład kodu
Aby uzyskać kompletny przykładowy kod w języku C#, zobacz StopProcessSample01 Sample (Przykład StopProcessSample01).
Definiowanie typów obiektów i formatowania
Windows PowerShell przekazuje informacje między poleceniami cmdlet przy użyciu obiektów .Net. W związku z tym polecenie cmdlet może wymagać zdefiniowania własnego typu lub może być konieczne rozszerzenie istniejącego typu udostępnianego przez inne polecenie cmdlet. Aby uzyskać więcej informacji na temat definiowania nowych typów lub rozszerzania istniejących typów, zobacz Rozszerzanie typów obiektów i formatowanie.
Budowania polecenia cmdlet
Po zaimplementowaniu polecenia cmdlet należy je zarejestrować w Windows PowerShell za pośrednictwem Windows PowerShell przystawki. Aby uzyskać więcej informacji na temat rejestrowania cmdlet, zobacz How to Register Cmdlets, Providers, and Host Applications(Jak rejestrować polecenia cmdlet, dostawców i aplikacje hosta).
Testowanie polecenia cmdlet
Po zarejestrowaniu polecenia cmdlet za pomocą Windows PowerShell można je przetestować, uruchamiając je w wierszu polecenia. Oto kilka testów, które testują Stop-Proc cmdlet. Aby uzyskać więcej informacji na temat używania poleceń cmdlet z wiersza polecenia, zobacz Wprowadzenie z Windows PowerShell.
Uruchom Windows PowerShell i użyj polecenia cmdlet Stop-Proc, aby zatrzymać przetwarzanie, jak pokazano poniżej. Ponieważ polecenie cmdlet określa
Name
parametr jako obowiązkowy, polecenie cmdlet wykonuje zapytanie dotyczące parametru.PS> stop-proc
Wyświetlone są następujące dane wyjściowe.
Cmdlet stop-proc at command pipeline position 1 Supply values for the following parameters: Name[0]:
Teraz użyjemy polecenia cmdlet , aby zatrzymać proces o nazwie "NOTEPAD". Polecenie cmdlet prosi o potwierdzenie akcji.
PS> stop-proc -Name notepad
Wyświetlone są następujące dane wyjściowe.
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"): Y
Użyj Stop-Proc jak pokazano, aby zatrzymać krytyczny proces o nazwie "WINLOGON". Zostanie wyświetlony monit z ostrzeżeniem o wykonaniu tej akcji, ponieważ spowoduje to ponowne uruchomienie systemu operacyjnego.
PS> stop-proc -Name Winlogon
Wyświetlone są następujące dane wyjściowe.
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"): N
Spróbujmy teraz zatrzymać proces WINLOGON bez otrzymywania ostrzeżenia. Należy pamiętać, że ten wpis polecenia używa
Force
parametru w celu zastąpienia ostrzeżenia.PS> stop-proc -Name winlogon -Force
Wyświetlone są następujące dane wyjściowe.
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
Zobacz też
Dodawanie parametrów, które przetwarzają Command-Line danych wejściowych
Rozszerzanie typów obiektów i formatowanie
Jak rejestrować polecenia cmdlet, dostawców i aplikacje hosta
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla