Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Soms moet een cmdlet de status van het systeem wijzigen, niet alleen de status van de Windows PowerShell-runtime. In deze gevallen moet de cmdlet de gebruiker de mogelijkheid geven om te bevestigen of de wijziging al dan niet moet worden aangebracht.
Ter ondersteuning van de bevestiging moet een cmdlet twee dingen doen.
Declareer dat de cmdlet bevestiging ondersteunt wanneer u het kenmerk System.Management.Automation.CmdletAttribute opgeeft door het trefwoord SupportsShouldProcess in te stellen op
true.Roep System.Management.Automation.Cmdlet.ShouldProcess aan tijdens de uitvoering van de cmdlet (zoals wordt weergegeven in het volgende voorbeeld).
Door bevestiging te ondersteunen, maakt een cmdlet de Confirm- en WhatIf parameters beschikbaar die worden geleverd door Windows PowerShell en voldoet ook aan de ontwikkelingsrichtlijnen voor cmdlets (zie richtlijnen voor het ontwikkelen van cmdlets.).
Het systeem wijzigen
De handeling 'het systeem wijzigen' verwijst naar een cmdlet die mogelijk de status van het systeem buiten Windows PowerShell wijzigt. Als u bijvoorbeeld een proces stopt, een gebruikersaccount inschakelt of uitschakelt, of een rij toevoegt aan een databasetabel, worden alle wijzigingen aangebracht in het systeem dat moet worden bevestigd.
Bewerkingen die gegevens lezen of tijdelijke verbindingen tot stand brengen, wijzigen daarentegen het systeem niet en vereisen in het algemeen geen bevestiging. Er is ook geen bevestiging nodig voor acties waarvan het effect is beperkt tot binnen de Windows PowerShell-runtime, zoals Set-Variable. Cmdlets die een permanente wijziging kunnen aanbrengen, moeten SupportsShouldProcess declareren en System.Management.Automation.Cmdlet.ShouldProcess alleen als ze op het punt staan om een permanente wijziging aan te brengen.
Notitie
ShouldProcess-bevestiging is alleen van toepassing op cmdlets. Als een opdracht of script de actieve status van een systeem wijzigt door rechtstreeks .NET-methoden of -eigenschappen aan te roepen, of door toepassingen buiten Windows PowerShell aan te roepen, is deze vorm van bevestiging niet beschikbaar.
De StopProc-cmdlet
In dit onderwerp wordt een Stop-Proc cmdlet beschreven waarmee wordt geprobeerd processen te stoppen die worden opgehaald met behulp van de Get-Proc-cmdlet (beschreven in Uw eerste cmdlet maken).
De cmdlet definiëren
De eerste stap bij het maken van de cmdlet is altijd de naamgeving van de cmdlet en het declareren van de .NET-klasse die de cmdlet implementeert. Omdat u een cmdlet schrijft om het systeem te wijzigen, moet deze dienovereenkomstig worden genoemd. Deze cmdlet stopt systeemprocessen, dus de werkwoordnaam die hier wordt gekozen, is 'Stop', gedefinieerd door de System.Management.Automation.VerbsLifecycle klasse, met het zelfstandig naamwoord Proc om aan te geven dat de cmdlet processen stopt. Zie Cmdlet Verb Namesvoor meer informatie over goedgekeurde cmdlet-werkwoorden.
Hier volgt de klassedefinitie voor deze Stop-Proc cmdlet.
[Cmdlet(VerbsLifecycle.Stop, "Proc",
SupportsShouldProcess = true)]
public class StopProcCommand : Cmdlet
Houd er rekening mee dat in de declaratie System.Management.Automation.CmdletAttribute het trefwoord SupportsShouldProcess kenmerk is ingesteld op true om de cmdlet in staat te stellen aanroepen naar System.Management.Automation.Cmdlet.ShouldProcess en System.Management.Automation.Cmdlet.ShouldContinue.
Zonder deze trefwoordenset zijn de parameters Confirm en WhatIf niet beschikbaar voor de gebruiker.
Extreem destructieve acties
Sommige bewerkingen zijn uiterst destructief, zoals het opnieuw formatteren van een actieve harde schijfpartitie. In deze gevallen moet de cmdlet ConfirmImpact = ConfirmImpact.High instellen bij het declareren van het kenmerk System.Management.Automation.CmdletAttribute. Met deze instelling wordt de cmdlet gedwongen om bevestiging van de gebruiker aan te vragen, zelfs wanneer de gebruiker de parameter Confirm niet heeft opgegeven. Cmdlet-ontwikkelaars moeten echter geen te veel ConfirmImpact gebruiken voor bewerkingen die mogelijk destructief zijn, zoals het verwijderen van een gebruikersaccount. Houd er rekening mee dat als ConfirmImpact is ingesteld op System.Management.Automation.ConfirmImpactHigh.
Op dezelfde manier zijn sommige bewerkingen waarschijnlijk destructief, hoewel ze in theorie de status van een systeem buiten Windows PowerShell wijzigen. Dergelijke cmdlets kunnen ConfirmImpact instellen op System.Management.Automation.ConfirmImpact.Low.
Hiermee worden bevestigingsaanvragen omzeild waarbij de gebruiker heeft gevraagd om alleen bewerkingen met gemiddelde impact en high-impact te bevestigen.
Parameters definiëren voor systeemwijziging
In deze sectie wordt beschreven hoe u de cmdlet-parameters definieert, inclusief parameters die nodig zijn om systeemaanpassing te ondersteunen. Zie Parameters toevoegen die opdrachtregelinvoer verwerken als u algemene informatie nodig hebt over het definiëren van parameters.
De cmdlet Stop-Proc definieert drie parameters: Name, Forceen PassThru.
De parameter Name komt overeen met de eigenschap Name van het invoerobject voor het proces. Houd er rekening mee dat de parameter Name in dit voorbeeld verplicht is, omdat de cmdlet mislukt als er geen benoemd proces is om te stoppen.
Met de parameter Force kan de gebruiker aanroepen naar System.Management.Automation.Cmdlet.ShouldContinueoverschrijven.
Elke cmdlet die System.Management.Automation.Cmdlet.ShouldContinue aanroept, moet een Force parameter hebben, zodat wanneer Force is opgegeven, de cmdlet de aanroep naar System.Management.Automation.Cmdlet.ShouldContinue overslaat en verdergaat met de bewerking. Houd er rekening mee dat dit geen invloed heeft op aanroepen naar System.Management.Automation.Cmdlet.ShouldProcess.
Met de parameter PassThru kan de gebruiker aangeven of de cmdlet een uitvoerobject doorgeeft via de pijplijn, in dit geval, nadat een proces is gestopt. Houd er rekening mee dat deze parameter is gekoppeld aan de cmdlet zelf in plaats van aan een eigenschap van het invoerobject.
Hier volgt de parameterdeclaratie voor de 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;
Een invoerverwerkingsmethode overschrijven
De cmdlet moet een invoerverwerkingsmethode overschrijven. De volgende code illustreert de System.Management.Automation.Cmdlet.ProcessRecord die wordt gebruikt in de voorbeeld-Stop-Proc cmdlet. Voor elke aangevraagde procesnaam zorgt deze methode ervoor dat het proces geen speciaal proces is, het proces probeert te stoppen en vervolgens een uitvoerobject verzendt als de parameter PassThru is opgegeven.
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
De Methode ShouldProcess aanroepen
De invoerverwerkingsmethode van uw cmdlet moet de System.Management.Automation.Cmdlet.ShouldProcess methode aanroepen om de uitvoering van een bewerking te bevestigen voordat een wijziging (bijvoorbeeld het verwijderen van bestanden) wordt aangebracht in de actieve status van het systeem. Hierdoor kan de Windows PowerShell-runtime het juiste 'WhatIf' en 'Confirm'-gedrag in de shell opgeven.
Notitie
Als een cmdlet aangeeft dat deze wordt ondersteund, moet worden verwerkt en de System.Management.Automation.Cmdlet.ShouldProcess aanroep, kan de gebruiker het systeem onverwacht wijzigen.
De aanroep van System.Management.Automation.Cmdlet.ShouldProcess verzendt de naam van de resource die moet worden gewijzigd in de gebruiker, waarbij de Windows PowerShell-runtime rekening houdt met eventuele opdrachtregelinstellingen of voorkeursvariabelen om te bepalen wat moet worden weergegeven aan de gebruiker.
In het volgende voorbeeld ziet u de aanroep van System.Management.Automation.Cmdlet.ShouldProcess uit de onderdrukking van de methode System.Management.Automation.Cmdlet.ProcessRecord in de voorbeeld-Stop-Proc-cmdlet.
if (!ShouldProcess(string.Format("{0} ({1})", processName,
process.Id)))
{
continue;
}
De methode ShouldContinue aanroepen
De aanroep van de methode System.Management.Automation.Cmdlet.ShouldContinue verzendt een secundair bericht naar de gebruiker. Deze aanroep wordt uitgevoerd nadat de aanroep naar System.Management.Automation.Cmdlet.ShouldProcesstrue retourneert en als de parameter Force niet is ingesteld op true. De gebruiker kan vervolgens feedback geven om te zeggen of de bewerking moet worden voortgezet. Uw cmdlet roept System.Management.Automation.Cmdlet.ShouldContinue- aan als extra controle op mogelijk gevaarlijke systeemwijzigingen of wanneer u ja-op-alles en no-to-alle opties aan de gebruiker wilt bieden.
In het volgende voorbeeld ziet u de aanroep van System.Management.Automation.Cmdlet.ShouldContinue uit de onderdrukking van de methode System.Management.Automation.Cmdlet.ProcessRecord in de Stop-Proc-voorbeeld-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...
Invoerverwerking stoppen
De invoerverwerkingsmethode van een cmdlet die systeemwijzigingen aanbrengt, moet een manier bieden om de verwerking van invoer te stoppen. In het geval van deze Stop-Proc cmdlet wordt een aanroep uitgevoerd vanuit de methode System.Management.Automation.Cmdlet.ProcessRecord naar de methode System.Diagnostics.Process.Kill* methode. Omdat de parameter PassThru is ingesteld op true, roept System.Management.Automation.Cmdlet.ProcessRecord ook System.Management.Automation.Cmdlet.WriteObject aan om het procesobject naar de pijplijn te verzenden.
Codevoorbeeld
Zie StopProcessSample01 Samplevoor de volledige C#-voorbeeldcode.
Objecttypen en -opmaak definiëren
Windows PowerShell geeft informatie door tussen cmdlets met behulp van .NET-objecten. Daarom moet een cmdlet mogelijk een eigen type definiëren of moet de cmdlet mogelijk een bestaand type uitbreiden dat wordt geleverd door een andere cmdlet. Zie Objecttypen en Opmaak uitbreidenvoor meer informatie over het definiëren van nieuwe typen of het uitbreiden van bestaande typen.
De cmdlet bouwen
Nadat u een cmdlet hebt geïmplementeerd, moet deze worden geregistreerd bij Windows PowerShell via een Windows PowerShell-module. Zie Cmdlets, providers en hosttoepassingen registrerenvoor meer informatie over het registreren van cmdlets.
De cmdlet testen
Wanneer uw cmdlet is geregistreerd bij Windows PowerShell, kunt u deze testen door deze uit te voeren op de opdrachtregel. Hier volgen verschillende tests waarmee de Stop-Proc cmdlet wordt getest. Zie de Aan de slag met Windows PowerShellvoor meer informatie over het gebruik van cmdlets vanaf de opdrachtregel.
Start Windows PowerShell en gebruik de Stop-Proc-cmdlet om de verwerking te stoppen, zoals hieronder wordt weergegeven. Omdat de cmdlet de parameter
Nameals verplicht opgeeft, voert de cmdlet query's uit voor de parameter.PS> Stop-ProcDe volgende uitvoer wordt weergegeven.
Cmdlet Stop-Proc at command pipeline position 1 Supply values for the following parameters: Name[0]:Nu gaan we de cmdlet gebruiken om het proces met de naam 'KLADBLOK' te stoppen. De cmdlet vraagt u om de actie te bevestigen.
PS> Stop-Proc -Name notepadDe volgende uitvoer wordt weergegeven.
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"): YGebruik Stop-Proc zoals wordt weergegeven om het kritieke proces met de naam WINLOGON te stoppen. U wordt gevraagd en gewaarschuwd voor het uitvoeren van deze actie, omdat het besturingssysteem hierdoor opnieuw wordt opgestart.
PS> Stop-Proc -Name WinlogonDe volgende uitvoer wordt weergegeven.
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"): NWe gaan nu proberen het WINLOGON-proces te stoppen zonder een waarschuwing te ontvangen. Houd er rekening mee dat deze opdrachtvermelding de parameter
Forcegebruikt om de waarschuwing te overschrijven.PS> Stop-Proc -Name winlogon -ForceDe volgende uitvoer wordt weergegeven.
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
Zie ook
Parameters toevoegen die Command-Line invoer verwerken
objecttypen en opmaak uitbreiden