Sdílet prostřednictvím


Vytvoření rutiny, která upravuje systém

Někdy musí rutina změnit spuštěný stav systému, nejen stav modulu runtime Windows PowerShellu. V těchto případech by rutina měla uživateli umožnit ověřit, jestli se má tato změna provést nebo ne.

Pokud chcete potvrdit, že rutina musí dělat dvě věci.

Díky potvrzení zveřejňuje rutina parametry Confirm a WhatIf, které poskytuje Prostředí Windows PowerShell, a také splňuje pokyny pro vývoj pro rutiny (Další informace o pokynech pro vývoj rutin najdete v tématu Pokyny pro vývoj rutin.).

Změna systému

Akce "změna systému" odkazuje na libovolnou rutinu, která potenciálně změní stav systému mimo Windows PowerShell. Například zastavení procesu, povolení nebo zakázání uživatelského účtu nebo přidání řádku do databázové tabulky jsou všechny změny systému, které by se měly potvrdit. Naproti tomu operace, které čtou data nebo navazují přechodná připojení, nemění systém a obecně nevyžadují potvrzení. Potvrzení také není nutné pro akce, jejichž účinek je omezen na modul runtime Prostředí Windows PowerShell, například Set-Variable. Rutiny, které můžou nebo nemusí provést trvalou změnu, by měly deklarovat SupportsShouldProcess a volat System.Management.Automation.Cmdlet.ShouldProcess pouze v případě, že se chystá provést trvalou změnu.

Poznámka:

Potvrzení funkce ShouldProcess platí jenom pro rutiny. Pokud příkaz nebo skript upraví stav systému přímým voláním metod nebo vlastností rozhraní .NET nebo voláním aplikací mimo Windows PowerShell, nebude tato forma potvrzení k dispozici.

Rutina StopProc

Toto téma popisuje Stop-Proc rutinu, která se pokouší zastavit procesy načtené pomocí rutiny Get-Proc (popsané v Vytvoření první rutiny).

Definování rutiny

Prvním krokem při vytváření rutin je vždy pojmenování rutiny a deklarování třídy .NET, která tuto rutinu implementuje. Protože píšete rutinu pro změnu systému, měla by být odpovídajícím způsobem pojmenována. Tato rutina zastaví systémové procesy, takže název slovesa zvolené zde je Stop, definovaný System.Management.Automation.VerbsLifecycle třídy, s podstatným jménem "Proc" označující, že rutina zastaví procesy. Další informace o schválených rutinách naleznete v tématu Názvy příkazů rutin.

Následuje definice třídy pro tuto rutinu Stop-Proc.

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

Mějte na paměti, že v deklaraci system.Management.Automation.CmdletAttribute je klíčové slovo atributu SupportsShouldProcess nastaveno na true, aby se rutina mohla volat System.Management.Automation.Cmdlet.ShouldProcess a System.Management.Automation.Cmdlet.ShouldContinue. Bez této sady klíčových slov nebudou pro uživatele k dispozici parametry Confirm a WhatIf.

Extrémně destruktivní akce

Některé operace jsou extrémně destruktivní, například přeformátování aktivního oddílu pevného disku. V těchto případech by rutina měla nastavit ConfirmImpact = ConfirmImpact.High při deklarování atributu System.Management.Automation.CmdletAttribute. Toto nastavení vynutí, aby rutina požadovala potvrzení uživatele, i když uživatel nezadá parametr Confirm. Vývojáři rutin by se ale měli vyhnout nadměrnému využití ConfirmImpact pro operace, které jsou jen potenciálně destruktivní, například odstranění uživatelského účtu. Mějte na paměti, že pokud je ConfirmImpact nastavena na System.Management.Automation.ConfirmImpactHigh.

Podobně některé operace pravděpodobně nejsou destruktivní, i když teoreticky upravují stav spuštění systému mimo Windows PowerShell. Takové rutiny mohou nastavit ConfirmImpact na System.Management.Automation.ConfirmImpact.Low. Tím se nepoužijí žádosti o potvrzení, u kterých uživatel požádal o potvrzení pouze středně ovlivněných operací a operací s vysokým dopadem.

Definování parametrů pro úpravu systému

Tato část popisuje, jak definovat parametry rutiny, včetně parametrů potřebných k podpoře úprav systému. Pokud potřebujete obecné informace o definování parametrů, přečtěte si přidání parametrů, které zpracovávají vstup příkazového řádku.

Rutina Stop-Proc definuje tři parametry: Name, Forcea PassThru.

Parametr Name odpovídá vlastnosti Name vstupního objektu procesu. Mějte na paměti, že parametr Name v této ukázce je povinný, protože rutina selže, pokud nemá pojmenovaný proces, který se má zastavit.

Parametr Force umožňuje uživateli přepsat volání System.Management.Automation.Cmdlet.ShouldContinue. Každá rutina, která volá System.Management.Automation.Cmdlet.ShouldContinue, by měla mít parametr Force, aby při zadání Force rutina přeskočí volání System.Management.Automation.Cmdlet.ShouldContinue a pokračuje s operací. Mějte na paměti, že to nemá vliv na volání System.Management.Automation.Cmdlet.ShouldProcess.

Parametr PassThru uživateli umožňuje indikovat, jestli rutina předává výstupní objekt kanálem, v tomto případě po zastavení procesu. Mějte na paměti, že tento parametr je vázán na samotnou rutinu místo na vlastnost vstupního objektu.

Tady je deklarace parametru pro rutinu 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;

Přepsání metody zpracování vstupu

Rutina musí přepsat metodu zpracování vstupu. Následující kód znázorňuje System.Management.Automation.Cmdlet.ProcessRecord přepsání použité v ukázkové rutině Stop-Proc. Pro každý požadovaný název procesu tato metoda zajišťuje, že proces není speciální proces, pokusí se proces zastavit a poté odešle výstupní objekt, pokud je zadán parametr PassThru.

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

Volání metody ShouldProcess

Metoda zpracování vstupu rutiny by měla volat metodu System.Management.Automation.Cmdlet.ShouldProcess metodu pro potvrzení provedení operace před provedením změny (například odstranění souborů) ve spuštěném stavu systému. To umožňuje modulu runtime Windows PowerShellu zadat správné chování WhatIf a Confirm v prostředí.

Poznámka:

Pokud rutina uvádí, že by měla zpracovat proces a nepodaří se provést System.Management.Automation.Cmdlet.ShouldProcess volání, uživatel může systém neočekávaně upravit.

Volání System.Management.Automation.Cmdlet.ShouldProcess odešle uživateli název prostředku, který se má změnit, s modulem runtime Windows PowerShellu s ohledem na všechna nastavení příkazového řádku nebo proměnné předvoleb při určování toho, co se má uživateli zobrazit.

Následující příklad ukazuje volání System.Management.Automation.Cmdlet.ShouldProcess z přepsání metody System.Management.Automation.Cmdlet.ProcessRecord v ukázkové rutině Stop-Proc.

if (!ShouldProcess(string.Format("{0} ({1})", processName,
                   process.Id)))
{
  continue;
}

Volání Metody ShouldContinue

Volání metody System.Management.Automation.Cmdlet.ShouldContinue odešle uživateli sekundární zprávu. Toto volání se provede po volání System.Management.Automation.Cmdlet.ShouldProcess vrátí true a pokud parametr Force nebyl nastaven na true. Uživatel pak může poskytnout zpětnou vazbu s informacemi o tom, jestli má operace pokračovat. Rutina volá System.Management.Automation.Cmdlet.ShouldContinue jako další kontrolu potenciálně nebezpečných úprav systému nebo když chcete uživateli poskytnout možnosti ano-to-all a no-to-all.

Následující příklad ukazuje volání System.Management.Automation.Cmdlet.ShouldContinue z přepsání metody System.Management.Automation.Cmdlet.ProcessRecord v ukázkové rutině 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...

Zastavení zpracování vstupu

Metoda zpracování vstupu rutiny, která provádí úpravy systému, musí poskytnout způsob zastavení zpracování vstupu. V případě této rutiny Stop-Proc je volání provedeno z metody System.Management.Automation.ProcessRecord metody System.Diagnostics.Process.Kill*. Protože PassThru parametr je nastaven na true, System.Management.Automation.ProcessRecord volá také System.Management.Automation.Cmdlet.WriteObject odeslat objekt procesu do kanálu.

Ukázka kódu

Úplný vzorový kód jazyka C# najdete v tématu StopProcessSample01 Sample.

Definování typů objektů a formátování

Windows PowerShell předává informace mezi rutinami pomocí objektů .NET. Proto může být potřeba, aby rutina definovala vlastní typ, nebo může být potřeba rozšířit existující typ poskytovaný jinou rutinou. Další informace o definování nových typů nebo rozšíření existujících typů naleznete v tématu Rozšíření typů objektů a formátování.

Sestavení rutiny

Po implementaci rutiny musí být zaregistrovaný ve Windows PowerShellu prostřednictvím modulu snap-in Prostředí Windows PowerShell. Další informace o registraci rutin naleznete v tématu Postup registrace rutin, poskytovatelů a hostitelských aplikací.

Testování rutiny

Když je vaše rutina zaregistrovaná ve Windows PowerShellu, můžete ji otestovat spuštěním na příkazovém řádku. Tady je několik testů, které testují rutinu Stop-Proc. Další informace o používání rutin z příkazového řádku najdete v tématu Začínáme s prostředím Windows PowerShell.

  • Spusťte Windows PowerShell a pomocí rutiny Stop-Proc zastavte zpracování, jak je znázorněno níže. Protože rutina určuje parametr Name jako povinný, rutina se dotazuje na parametr.

    PS> Stop-Proc
    

    Zobrazí se následující výstup.

    Cmdlet Stop-Proc at command pipeline position 1
    Supply values for the following parameters:
    Name[0]:
    
  • Teď pomocí rutiny zastavte proces s názvem POZNÁMKOVÝ BLOK. Rutina vás vyzve k potvrzení akce.

    PS> Stop-Proc -Name notepad
    

    Zobrazí se následující výstup.

    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
    
  • Pomocí Stop-Proc, jak je znázorněno, zastavte kritický proces s názvem WINLOGON. Zobrazí se výzva a zobrazí se upozornění na provedení této akce, protože způsobí restartování operačního systému.

    PS> Stop-Proc -Name Winlogon
    

    Zobrazí se následující výstup.

    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
    
  • Teď se pokusíme zastavit proces WINLOGON, aniž by se zobrazilo upozornění. Mějte na paměti, že tato položka příkazu používá parametr Force k přepsání upozornění.

    PS> Stop-Proc -Name winlogon -Force
    

    Zobrazí se následující výstup.

    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
    

Viz také

přidání parametrů, které zpracovávají vstupní Command-Line

rozšíření typů objektů a formátování

registrace rutin, poskytovatelů a hostitelských aplikací

windows PowerShell SDK

ukázky rutin