Skapa en cmdlet som ändrar systemet
Ibland måste en cmdlet ändra systemets körningstillstånd, inte bara tillståndet för den Windows PowerShell körningen. I dessa fall bör cmdleten ge användaren möjlighet att bekräfta om ändringen ska göras eller inte.
För att stödja bekräftelse måste en cmdlet göra två saker.
Deklarera att cmdleten stöder bekräftelse när du anger attributet System.Management.Automation.CmdletAttribute genom att ange nyckelordet SupportsShouldProcess till
true
.Anropa System.Management.Automation.Cmdlet.ShouldProcess under körningen av cmdleten (se följande exempel).
En cmdlet visar parametrarna och som tillhandahålls av Windows PowerShell och uppfyller även utvecklingsriktlinjerna för cmdlet:ar (Mer information om riktlinjer för cmdlet-utveckling finns i Confirm
WhatIf
Cmdlet Development Guidelines.).
Ändra systemet
Att "ändra systemet" syftar på alla cmdlet:ar som potentiellt ändrar systemets tillstånd utanför Windows PowerShell. Om du till exempel stoppar en process, aktiverar eller inaktiverar ett användarkonto eller lägger till en rad i en databastabell ändras alla ändringar i systemet som ska bekräftas.
Åtgärder som läser data eller upprättar tillfälliga anslutningar ändrar däremot inte systemet och kräver vanligtvis ingen bekräftelse. Bekräftelse krävs inte heller för åtgärder vars effekt är begränsad till inuti Windows PowerShell körning, till exempel set-variable
. Cmdlets som kanske eller kanske inte gör en beständig ändring bör deklarera och anropa SupportsShouldProcess
System.Management.Automation.Cmdlet.ShouldProcess endast om de är på väg att göra en beständig ändring.
Anteckning
ShouldProcess-bekräftelse gäller endast för cmdlets. Om ett kommando eller skript ändrar körningstillståndet för ett system genom att direkt anropa .NET-metoder eller -egenskaper, eller genom att anropa program utanför Windows PowerShell, är den här formen av bekräftelse inte tillgänglig.
StopProc-cmdleten
Det här avsnittet beskriver Stop-Proc cmdlet som försöker stoppa processer som hämtas med hjälp av Get-Proc-cmdleten (beskrivs i Skapa din första cmdlet).
Definiera cmdleten
Det första steget i att skapa cmdleten är att alltid namnge cmdleten och deklarera den .NET-klass som implementerar cmdleten. Eftersom du skriver en cmdlet för att ändra systemet bör den namnges i enlighet med detta. Den här cmdleten stoppar systemprocesser, så verbnamnet som väljs här är "Stop", som definieras av klassen System.Management.Automation.Verbslifecycle, med substantivet "Proc" för att indikera att cmdleten stoppar processer. Mer information om godkända cmdlet-verb finns i Cmdlet-verbnamn.
Följande är klassdefinitionen för den här Stop-Proc cmdleten.
[Cmdlet(VerbsLifecycle.Stop, "Proc",
SupportsShouldProcess = true)]
public class StopProcCommand : Cmdlet
Tänk på att attributet i deklarationen System.Management.Automation.CmdletAttribute är inställt på att aktivera cmdleten för att göra anrop till SupportsShouldProcess
true
System.Management.Automation.Cmdlet.ShouldProcess och System.Management.Automation.Cmdlet.ShouldContinue.
Utan den här nyckelordsuppsättningen är parametrarna och Confirm
inte tillgängliga för WhatIf
användaren.
Extremt destruktiva åtgärder
Vissa åtgärder är mycket destruktiva, till exempel att formatera om en aktiv hårddiskpartition. I dessa fall ska cmdleten anges när ConfirmImpact
= ConfirmImpact.High
attributet System.Management.Automation.CmdletAttribute deklareras. Den här inställningen tvingar cmdleten att begära användarbekräftelse även om användaren inte har angett Confirm
parametern. Cmdlet-utvecklare bör dock undvika att överanvända åtgärder som kan vara ConfirmImpact
skadliga, till exempel att ta bort ett användarkonto. Kom ihåg att ConfirmImpact
om är inställt på System.Management.Automation.ConfirmImpact
High.
På samma sätt är det inte troligt att vissa åtgärder är destruktiva, även om de i teorin ändrar körningstillståndet för ett system utanför Windows PowerShell. Sådana cmdlets kan anges ConfirmImpact
till System.Management.Automation.Confirmimpact.Low.
Detta kringgår bekräftelsebegäranden där användaren har bett att endast bekräfta åtgärder med medelhög och hög påverkan.
Definiera parametrar för systemändring
I det här avsnittet beskrivs hur du definierar cmdlet-parametrarna, inklusive de som behövs för att stödja systemändring. Se Lägga till parametrar som bearbetar kommandoradsindata om du behöver allmän information om hur du definierar parametrar.
Cmdleten Stop-Proc definierar tre parametrar: Name
Force
, och PassThru
.
Parametern Name
motsvarar egenskapen Name
för processindataobjektet. Tänk på att parametern i det här exemplet är obligatorisk eftersom cmdleten misslyckas om den inte Name
har en namngiven process att stoppa.
Parametern Force
gör att användaren kan åsidosätta anrop till System.Management.Automation.Cmdlet.ShouldContinue.
I själva verket bör alla cmdlet:ar som anropar System.Management.Automation.Cmdlet.ShouldContinue ha en parameter så att när anges hoppar cmdleten över anropet till Force
Force
System.Management.Automation.Cmdlet.ShouldContinue och fortsätter med åtgärden. Tänk på att detta inte påverkar anrop till System.Management.Automation.Cmdlet.ShouldProcess.
Parametern gör att användaren kan ange om cmdleten skickar ett utdataobjekt via pipelinen, i det PassThru
här fallet efter att en process har stoppats. Tänk på att den här parametern är knuten till själva cmdleten i stället för till en egenskap för indataobjektet.
Här är parameterdeklarationen för Stop-Proc cmdlet.
[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;
Åsidosätta en metod för indatabearbetning
Cmdleten måste åsidosätta en indatabearbetningsmetod. Följande kod illustrerar åsidosättningen System.Management.Automation.Cmdlet.ProcessRecord som används i Stop-Proc cmdlet. För varje begärt processnamn säkerställer den här metoden att processen inte är en särskild process, försöker stoppa processen och skickar sedan ett utdataobjekt om PassThru
parametern har angetts.
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
Anropa Metoden ShouldProcess
Metoden för bearbetning av indata för din cmdlet bör anropa metoden System.Management.Automation.Cmdlet.ShouldProcess för att bekräfta körningen av en åtgärd innan en ändring (till exempel borttagning av filer) görs till systemets körningstillstånd. Detta gör att Windows PowerShell-körningen kan ange rätt "WhatIf"- och "Confirm"-beteende i gränssnittet.
Anteckning
Om en cmdlet säger att den stöder ska bearbeta och misslyckas med att göra anropet System.Management.Automation.Cmdlet.ShouldProcess kan användaren ändra systemet oväntat.
Anropet till System.Management.Automation.Cmdlet.ShouldProcess skickar namnet på resursen som ska ändras till användaren, där Windows PowerShell-körningen tar hänsyn till alla kommandoradsinställningar eller inställningsvariabler för att fastställa vad som ska visas för användaren.
I följande exempel visas anropet till System.Management.Automation.Cmdlet.ShouldProcess från åsidosättningen av metoden System.Management.Automation.Cmdlet.ProcessRecord i Stop-Proc cmdlet.
if (!ShouldProcess(string.Format("{0} ({1})", processName,
process.Id)))
{
continue;
}
Anropa ShouldContinue-metoden
Anropet till metoden System.Management.Automation.Cmdlet.ShouldContinue skickar ett sekundärt meddelande till användaren. Det här anropet görs efter anropet till System.Management.Automation.Cmdlet.ShouldProcess returnerar och true
om Force
parametern inte har angetts till true
. Användaren kan sedan ge feedback för att säga om åtgärden ska fortsätta. Din cmdlet anropar System.Management.Automation.Cmdlet.ShouldContinue som en ytterligare kontroll för potentiellt farliga systemändringar eller när du vill ge användaren alternativ som är ja-till-alla och inte-till-alla.
I följande exempel visas anropet till System.Management.Automation.Cmdlet.ShouldContinue från åsidosättningen av metoden System.Management.Automation.Cmdlet.ProcessRecord i 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...
Stoppa indatabearbetning
Metoden för bearbetning av indata för en cmdlet som gör systemändringar måste ge ett sätt att stoppa bearbetningen av indata. När det gäller den här Stop-Proc-cmdleten görs ett anrop från metoden System.Management.Automation.Cmdlet.ProcessRecord till metoden System.Diagnostics.Process.Kill*. Eftersom PassThru
parametern är inställd på true
anropar System.Management.Automation.Cmdlet.ProcessRecord även System.Management.Automation.Cmdlet.WriteObject för att skicka processobjektet till pipelinen.
Kodexempel
Den fullständiga C#-exempelkoden finns i StopProcessSample01 Sample.
Definiera objekttyper och formatering
Windows PowerShell skickar information mellan cmdlets med hjälp av .Net-objekt. Därför kan en cmdlet behöva definiera sin egen typ, eller så kan cmdleten behöva utöka en befintlig typ som tillhandahålls av en annan cmdlet. Mer information om hur du definierar nya typer eller utökar befintliga typer finns i Utöka objekttyper och formatering.
Skapa cmdleten
När du har implementerat en cmdlet måste den registreras Windows PowerShell via en Windows PowerShell snapin-modulen. Mer information om hur du registrerar cmdlets finns i Registrera cmdlets, providers och värdprogram.
Testa cmdleten
När din cmdlet har registrerats med Windows PowerShell kan du testa den genom att köra den på kommandoraden. Här är flera tester som testar Stop-Proc cmdlet. Mer information om hur du använder cmdlets från kommandoraden finns i Komma igång med Windows PowerShell.
Börja Windows PowerShell och använd cmdleten Stop-Proc för att stoppa bearbetningen enligt nedan. Eftersom cmdleten anger
Name
parametern som obligatorisk frågar cmdleten efter parametern.PS> stop-proc
Följande utdata visas.
Cmdlet stop-proc at command pipeline position 1 Supply values for the following parameters: Name[0]:
Nu ska vi använda cmdleten för att stoppa processen med namnet "ANTECKNINGAR". Cmdleten ber dig att bekräfta åtgärden.
PS> stop-proc -Name notepad
Följande utdata visas.
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
Använd Stop-Proc som visas för att stoppa den kritiska processen med namnet "WINLOGON". Du uppmanas och varnas om att utföra den här åtgärden eftersom det gör att operativsystemet startas om.
PS> stop-proc -Name Winlogon
Följande utdata visas.
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
Nu ska vi försöka stoppa WINLOGON-processen utan att få en varning. Tänk på att den här kommandoposten använder
Force
parametern för att åsidosätta varningen.PS> stop-proc -Name winlogon -Force
Följande utdata visas.
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
Se även
Lägga till parametrar som bearbetar Command-Line indata
Utöka objekttyper och formatering
Feedback
https://aka.ms/ContentUserFeedback.
Kommer snart: Under hela 2024 kommer vi att fasa ut GitHub-problem som feedbackmekanism för innehåll och ersätta det med ett nytt feedbacksystem. Mer information finns i:Skicka och visa feedback för