Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier les répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer de répertoire.
Parfois, une applet de commande doit modifier l’état d’exécution du système, pas seulement l’état du runtime Windows PowerShell. Dans ce cas, l’applet de commande doit permettre à l’utilisateur de confirmer s’il faut ou non apporter la modification.
Pour prendre en charge la confirmation d’une applet de commande, vous devez effectuer deux opérations.
Déclarez que l’applet de commande prend en charge la confirmation lorsque vous spécifiez l’attribut System.Management.Automation.CmdletAttribute en définissant le mot clé SupportsShouldProcess sur
true.Appelez System.Management.Automation.Cmdlet.ShouldProcess pendant l’exécution de l’applet de commande (comme illustré dans l’exemple suivant).
En prenant en charge la confirmation, une applet de commande expose les paramètres Confirm et WhatIf fournis par Windows PowerShell, et répond également aux instructions de développement pour les applets de commande (pour plus d’informations sur les instructions de développement des applets de commande, consultez Instructions de développement des applets de commande.).
Modification du système
L’acte de « modification du système » fait référence à toute applet de commande qui modifie potentiellement l’état du système en dehors de Windows PowerShell. Par exemple, l’arrêt d’un processus, l’activation ou la désactivation d’un compte d’utilisateur ou l’ajout d’une ligne à une table de base de données sont toutes les modifications apportées au système qui doivent être confirmées.
En revanche, les opérations qui lisent des données ou établissent des connexions temporaires ne modifient pas le système et ne nécessitent généralement pas de confirmation. La confirmation n’est pas non plus nécessaire pour les actions dont l’effet est limité à l’intérieur du runtime Windows PowerShell, tel que Set-Variable. Les applets de commande susceptibles ou non d’apporter une modification persistante doivent déclarer SupportsShouldProcess et appeler System.Management.Automation.Cmdlet.ShouldProcess uniquement s’ils sont sur le point d’apporter une modification persistante.
Remarque
La confirmation ShouldProcess s’applique uniquement aux applets de commande. Si une commande ou un script modifie l’état d’exécution d’un système en appelant directement des méthodes ou des propriétés .NET, ou en appelant des applications en dehors de Windows PowerShell, cette forme de confirmation n’est pas disponible.
Applet de commande StopProc
Cette rubrique décrit une applet de commande Stop-Proc qui tente d’arrêter les processus récupérés à l’aide de l’applet de commande Get-Proc (décrite dans Création de votre première applet de commande).
Définition de l’applet de commande
La première étape de la création de l’applet de commande consiste toujours à nommer l’applet de commande et à déclarer la classe .NET qui implémente l’applet de commande. Étant donné que vous écrivez une applet de commande pour modifier le système, elle doit être nommée en conséquence. Cette applet de commande arrête les processus système. Le nom du verbe choisi ici est « Stop », défini par la classe System.Management.Automation.VerbsLifecycle, avec le nom « Proc » pour indiquer que l’applet de commande arrête les processus. Pour plus d’informations sur les verbes d’applet de commande approuvés, consultez noms de verbes d’applet de commande.
Voici la définition de classe pour cette applet de commande Stop-Proc.
[Cmdlet(VerbsLifecycle.Stop, "Proc",
SupportsShouldProcess = true)]
public class StopProcCommand : Cmdlet
Notez que dans la déclaration System.Management.Automation.CmdletAttribute, le mot clé d’attribut SupportsShouldProcess est défini sur true pour permettre à l’applet de commande d’effectuer des appels à System.Management.Automation.Cmdlet.ShouldProcess et System.Management.Automation.Cmdlet.ShouldContinue.
Sans ce jeu de mots clés, les paramètres Confirm et WhatIf ne seront pas disponibles pour l’utilisateur.
Actions extrêmement destructrices
Certaines opérations sont extrêmement destructrices, telles que la reformatage d’une partition de disque dur active. Dans ce cas, l’applet de commande doit définir ConfirmImpact = ConfirmImpact.High lors de la déclaration de l’attribut System.Management.Automation.CmdletAttribute. Ce paramètre force l’applet de commande à demander la confirmation de l’utilisateur même lorsque l’utilisateur n’a pas spécifié le paramètre Confirm. Toutefois, les développeurs d’applets de commande doivent éviter de trop utiliser ConfirmImpact pour les opérations qui sont simplement destructrices, telles que la suppression d’un compte d’utilisateur. N’oubliez pas que si ConfirmImpact est défini sur System.Management.Automation.ConfirmImpactHigh.
De même, certaines opérations sont peu susceptibles d’être destructrices, bien qu’elles modifient en théorie l’état d’exécution d’un système en dehors de Windows PowerShell. Ces applets de commande peuvent définir ConfirmImpact sur System.Management.Automation.ConfirmImpact.Low.
Cela contournera les demandes de confirmation où l’utilisateur a demandé de confirmer uniquement les opérations à impact moyen et à impact élevé.
Définition de paramètres pour la modification du système
Cette section explique comment définir les paramètres d’applet de commande, y compris ceux nécessaires à la prise en charge de la modification du système. Consultez Ajout de paramètres qui traitent l’entrée CommandLine si vous avez besoin d’informations générales sur la définition des paramètres.
L’applet de commande Stop-Proc définit trois paramètres : Name, Forceet PassThru.
Le paramètre Name correspond à la propriété Name de l’objet d’entrée de processus. N’oubliez pas que le paramètre Name dans cet exemple est obligatoire, car l’applet de commande échoue si elle n’a pas de processus nommé à arrêter.
Le paramètre Force permet à l’utilisateur de remplacer les appels à System.Management.Automation.Cmdlet.ShouldContinue.
En fait, toutes les applets de commande qui appellent System.Management.Automation.Cmdlet.ShouldContinue doivent avoir un paramètre Force afin que lorsque Force soit spécifié, l’applet de commande ignore l’appel à System.Management.Automation.Cmdlet.ShouldContinue et passe à l’opération. N’oubliez pas que cela n’affecte pas les appels à System.Management.Automation.Cmdlet.ShouldProcess.
Le paramètre PassThru permet à l’utilisateur d’indiquer si l’applet de commande transmet un objet de sortie via le pipeline, dans ce cas, après l’arrêt d’un processus. N’oubliez pas que ce paramètre est lié à l’applet de commande elle-même au lieu d’une propriété de l’objet d’entrée.
Voici la déclaration de paramètre de l’applet de commande 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;
Substitution d’une méthode de traitement d’entrée
L’applet de commande doit remplacer une méthode de traitement d’entrée. Le code suivant illustre la substitution System.Management.Automation.Cmdlet.ProcessRecord utilisée dans l’exemple d’applet de commande Stop-Proc. Pour chaque nom de processus demandé, cette méthode garantit que le processus n’est pas un processus spécial, tente d’arrêter le processus, puis envoie un objet de sortie si le paramètre PassThru est spécifié.
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
Appel de la méthode ShouldProcess
La méthode de traitement d’entrée de votre applet de commande doit appeler la méthode System.Management.Automation.Cmdlet.ShouldProcess pour confirmer l’exécution d’une opération avant qu’une modification (par exemple, la suppression de fichiers) soit apportée à l’état en cours d’exécution du système. Cela permet au runtime Windows PowerShell de fournir le comportement correct « WhatIf » et « Confirm » dans l’interpréteur de commandes.
Remarque
Si une applet de commande indique qu’elle prend en charge doit traiter et ne parvient pas à effectuer l’appel System.Management.Automation.Cmdlet.ShouldProcess, l’utilisateur peut modifier le système de manière inattendue.
L’appel à System.Management.Automation.Cmdlet.ShouldProcess envoie le nom de la ressource à modifier à l’utilisateur, avec le runtime Windows PowerShell prenant en compte les paramètres de ligne de commande ou les variables de préférence pour déterminer ce qui doit être affiché à l’utilisateur.
L’exemple suivant montre l’appel à System.Management.Automation.Cmdlet.ShouldProcess à partir de la substitution de la méthode System.Management.Automation.Cmdlet.ProcessRecord dans l’exemple d’applet de commande Stop-Proc.
if (!ShouldProcess(string.Format("{0} ({1})", processName,
process.Id)))
{
continue;
}
Appel de la méthode ShouldContinue
L’appel à la méthode System.Management.Automation.Cmdlet.ShouldContinue envoie un message secondaire à l’utilisateur. Cet appel est effectué après l’appel à System.Management.Automation.Cmdlet.ShouldProcess retourne true et si le paramètre Force n’a pas été défini sur true. L’utilisateur peut ensuite fournir des commentaires pour indiquer si l’opération doit être poursuivie. Votre applet de commande appelle System.Management.Automation.Cmdlet.ShouldContinue comme vérification supplémentaire des modifications système potentiellement dangereuses ou lorsque vous souhaitez fournir oui à tout et no-to-toutes les options à l’utilisateur.
L’exemple suivant montre l’appel à System.Management.Automation.Cmdlet.ShouldContinue à partir du remplacement de la méthode System.Management.Automation.Cmdlet.ProcessRecord dans l’exemple d’applet de commande Stop-Proc.
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...
Arrêt du traitement d’entrée
La méthode de traitement d’entrée d’une applet de commande qui apporte des modifications système doit fournir un moyen d’arrêter le traitement de l’entrée. Dans le cas de cette applet de commande Stop-Proc, un appel est effectué à partir de la méthode System.Management.Automation.Cmdlet.ProcessRecord à la méthode System.Diagnostics.Process.Kill*. Étant donné que le paramètre PassThru est défini sur true, System.Management.Automation.Cmdlet.ProcessRecord appelle également System.Management.Automation.Cmdlet.WriteObject pour envoyer l’objet de processus au pipeline.
Exemple de code
Pour obtenir l’exemple de code C# complet, consultez 'exemple stopProcessSample01.
Définition des types d’objets et de la mise en forme
Windows PowerShell transmet des informations entre les applets de commande à l’aide d’objets .NET. Par conséquent, une applet de commande peut avoir besoin de définir son propre type, ou l’applet de commande peut avoir besoin d’étendre un type existant fourni par une autre applet de commande. Pour plus d’informations sur la définition de nouveaux types ou l’extension de types existants, consultez Extension des types d’objets et de la mise en forme.
Génération de l’applet de commande
Après avoir implémenté une applet de commande, elle doit être inscrite auprès de Windows PowerShell via un composant logiciel enfichable Windows PowerShell. Pour plus d’informations sur l’inscription d’applets de commande, consultez Guide pratique pour inscrire des applets de commande, des fournisseurs et des applications hôtes.
Test de l’applet de commande
Lorsque votre applet de commande a été inscrite auprès de Windows PowerShell, vous pouvez la tester en l’exécutant sur la ligne de commande. Voici plusieurs tests qui testent l’applet de commande Stop-Proc. Pour plus d’informations sur l’utilisation d’applets de commande à partir de la ligne de commande, consultez la Prise en main de Windows PowerShell.
Démarrez Windows PowerShell et utilisez l’applet de commande Stop-Proc pour arrêter le traitement, comme indiqué ci-dessous. Étant donné que l’applet de commande spécifie le paramètre
Namecomme obligatoire, l’applet de commande interroge le paramètre.PS> Stop-ProcLa sortie suivante s’affiche.
Cmdlet Stop-Proc at command pipeline position 1 Supply values for the following parameters: Name[0]:À présent, utilisons l’applet de commande pour arrêter le processus nommé « NOTEPAD ». L’applet de commande vous demande de confirmer l’action.
PS> Stop-Proc -Name notepadLa sortie suivante s’affiche.
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"): YUtilisez Stop-Proc comme indiqué pour arrêter le processus critique nommé « WINLOGON ». Vous êtes invité et averti de l’exécution de cette action, car il entraîne le redémarrage du système d’exploitation.
PS> Stop-Proc -Name WinlogonLa sortie suivante s’affiche.
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"): NEssayons maintenant d’arrêter le processus WINLOGON sans recevoir d’avertissement. N’oubliez pas que cette entrée de commande utilise le paramètre
Forcepour remplacer l’avertissement.PS> Stop-Proc -Name winlogon -ForceLa sortie suivante s’affiche.
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
Voir aussi
Ajout de paramètres qui traitent Command-Line d’entrée
extension des types d’objets et de mise en forme
Comment inscrire des applets de commande, des fournisseurs et des applications hôtes