Création d’une applet de commande qui modifie le système

parfois, une applet de commande doit modifier l’état d’exécution du système, et pas seulement l’état de l’exécution du Windows PowerShell. Dans ce cas, l’applet de commande doit permettre à l’utilisateur de confirmer si la modification doit être apportée ou non.

Pour prendre en charge la confirmation, une applet de commande doit faire deux choses.

en prenant en charge la confirmation, une applet de commande expose les Confirm WhatIf paramètres et fournis par Windows PowerShell, ainsi que les 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 appletsde commande.).

Modification du système

L’acte de « modification du système » fait référence à toute applet de commande qui modifie éventuellement 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 des modifications apportées au système qui doivent être confirmées. En revanche, les opérations qui lisent les 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é à dans le runtime Windows PowerShell, tel que set-variable . Les applets de commande qui peuvent ou ne peuvent pas effectuer de modification permanente doivent déclarer SupportsShouldProcess et appeler System. Management. Automation. cmdlet. ShouldProcess uniquement si elles sont sur le lieu d’effectuer une modification permanente.

Notes

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 des processus qui sont récupérés à l’aide de l’applet de commande Get-Proc (décrite dans création de votre première appletde commande).

Définition de l’applet de commande

La première étape de la création des applets 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. par conséquent, 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 des verbes d’appletde commande.

Voici la définition de classe pour cette applet de commande Stop-Proc.

[Cmdlet(VerbsLifecycle.Stop, "Proc",
        SupportsShouldProcess = true)]
public class StopProcCommand : Cmdlet

Sachez que dans la Déclaration System. Management. Automation. CmdletAttribute , le SupportsShouldProcess mot clé d’attribut a la valeur true pour permettre à l’applet de commande d’effectuer des appels à System. Management. Automation. cmdlet. ShouldProcess et System. Management. Automation. cmdlet. ShouldContinue. Si ce mot clé n’est pas défini, les Confirm WhatIf paramètres et ne sont pas disponibles pour l’utilisateur.

Actions extrêmement destructrices

Certaines opérations sont extrêmement destructrices, telles que le reformatage d’une partition de disque dur active. Dans ce cas, l’applet de commande doit être définie 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 si l’utilisateur n’a pas spécifié le Confirm paramètre. Toutefois, les développeurs d’applets de commande doivent éviter de les utiliser ConfirmImpact pour les opérations qui sont simplement potentiellement destructrices, telles que la suppression d’un compte d’utilisateur. N’oubliez pas que si ConfirmImpact a la valeur System. Management. Automation. ConfirmImpact High.

De même, certaines opérations ont peu de chances 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 ConfirmImpact être définies sur System. Management. Automation. ConfirmImpact. Low. Cela permet de contourner les demandes de confirmation lorsque l’utilisateur a demandé à confirmer uniquement les opérations à impact moyen et à impact élevé.

Définition des paramètres pour la modification du système

Cette section décrit comment définir les paramètres de l’applet de commande, y compris ceux qui sont nécessaires pour prendre en charge la modification du système. Consultez Ajout de paramètres qui traitent l’entrée de la ligne de commande 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 , Force et PassThru .

Le Name paramètre correspond à la Name propriété de l’objet de traitement d’entrée. Sachez que le Name paramètre de cet exemple est obligatoire, car l’applet de commande échouera s’il n’a pas de processus nommé à arrêter.

Le Force paramètre permet à l’utilisateur de substituer des appels à System. Management. Automation. appletde commande. ShouldContinue. En fait, toute applet de commande qui appelle System. Management. Automation. applet de commande. ShouldContinue doit avoir un Force paramètre de sorte que lorsque Force est spécifié, l’applet de commande ignore l’appel à System. Management. Automation. cmdlet. ShouldContinue et poursuit l’opération. N’oubliez pas que cela n’affecte pas les appels à System. Management. Automation. appletde commande. ShouldProcess.

Le PassThru paramètre permet à l’utilisateur d’indiquer si l’applet de commande passe 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 et non à une propriété de l’objet d’entrée.

Voici la déclaration du paramètre pour 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 PassThru paramètre 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 d’exécution du système. cela permet au runtime Windows PowerShell de fournir les comportements « WhatIf » et « Confirm » corrects dans l’interpréteur de commandes.

Notes

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. applet de commande. ShouldProcess envoie le nom de la ressource à modifier à l’utilisateur, avec le runtime Windows PowerShell en tenant compte des paramètres de ligne de commande ou des 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’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. applet de commande. ShouldContinue envoie un message secondaire à l’utilisateur. Cet appel est effectué après l’appel à System. Management. Automation. applet de commande. ShouldProcess retourne true et si le Force paramètre n’a pas la valeur 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. applet de commande. ShouldContinue en guise de vérification supplémentaire des modifications système potentiellement dangereuses ou lorsque vous souhaitez fournir des options Oui-à-tout et non-tout à l’utilisateur.

L’exemple suivant illustre l’appel à System. Management. Automation. applet de commande. ShouldContinue à partir de la substitution de la méthode System. Management. Automation. cmdlet. ProcessRecord dans l’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 des entrées

La méthode de traitement d’entrée d’une applet de commande qui effectue des modifications du système doit permettre d’arrêter le traitement des entrées. Dans le cas de cette applet de commande Stop-Proc, un appel est effectué à partir de la méthode System. Management. Automation. cmdlet. ProcessRecord vers la méthode System. Diagnostics. Process. Kill * . Étant donné que le PassThru paramètre a la valeur true , System. Management. Automation. cmdlet. ProcessRecord appelle également System. Management. Automation. cmdlet. WriteObject pour envoyer l’objet 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 l’implémentation d’une applet de commande, celle-ci doit être inscrite auprès de Windows PowerShell via un composant logiciel enfichable Windows PowerShell. Pour plus d’informations sur l’enregistrement des applets de commande, consultez comment 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 des applets de commande à partir de la ligne de commande, consultez le prise en main avec 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 Name paramètre comme obligatoire, l’applet de commande interroge le paramètre.

    PS> stop-proc
    

    La sortie suivante apparaît.

    Cmdlet stop-proc at command pipeline position 1
    Supply values for the following parameters:
    Name[0]:
    
  • Nous allons maintenant utiliser 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 notepad
    

    La sortie suivante apparaît.

    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
    
  • Utilisez Stop-Proc comme indiqué pour arrêter le processus critique nommé « WINLOGON ». Vous êtes invité à effectuer cette action, qui entraîne le redémarrage du système d’exploitation.

    PS> stop-proc -Name Winlogon
    

    La sortie suivante apparaît.

    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
    
  • Essayons maintenant d’arrêter le processus WINLOGON sans recevoir d’avertissement. N’oubliez pas que cette entrée de commande utilise le Force paramètre pour remplacer l’avertissement.

    PS> stop-proc -Name winlogon -Force
    

    La sortie suivante apparaît.

    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 entrée

Extension des types d’objets et de la mise en forme

Comment inscrire des applets de commande, des fournisseurs et des applications hôtes

Windows PowerShell SDK

Exemples d’applets de commande