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

V některých případech musí rutina změnit stav spuštění systému, nejen stav Windows PowerShell runtime. V těchto případech by rutina měla uživateli umožnit, aby potvrdil, jestli má nebo nemá provést změnu.

Pro potvrzení musí rutina provést dvě věci.

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

Změna systému

"Změnou systému" se rozumí jakákoli rutina, 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 navázání přechodných připojení, nemění systém a obecně nevyžadují potvrzení. Potvrzení také není potřeba u akcí, jejichž účinek je omezený na uvnitř modulu runtime Windows PowerShell, například set-variable . Rutiny, které mohou nebo nemusí provést trvalou změnu, by měly deklarovat a volat SupportsShouldProcess System.Management.Automation.Cmdlet.ShouldProcess pouze v případě, že se mají provést trvalou změnu.

Poznámka

Potvrzení ShouldProcess se vztahuje jenom na rutiny. Pokud příkaz nebo skript upraví stav spuštění systému přímo 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 rutinu Stop-Proc, která se pokusí zastavit procesy, které se načítá pomocí rutiny Get-Proc (popsané v tématu Vytvoření první rutiny).

Definování rutiny

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

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

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

Uvědomte si, že v deklaraci System.Management.Automation.CmdletAttribute je klíčové slovo atributu nastavené na , aby rutině umožnilo volání SupportsShouldProcess true metody System.Management.Automation.Cmdlet.ShouldProcess a System.Management.Automation.Cmdlet.ShouldContinue. Bez této sady klíčových slov nebudou parametry a dostupné Confirm WhatIf pro uživatele.

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 měla rutina nastavit ConfirmImpact = ConfirmImpact.High při deklaraci atributu System.Management.Automation.CmdletAttribute. Toto nastavení vynutí rutinu, aby si vyžádal potvrzení uživatele i v případě, že uživatel nezadá Confirm parametr . Vývojáři rutin by se ale měli vyhnout přeučení pro operace, které jsou potenciálně destruktivní, například ConfirmImpact pro odstranění uživatelského účtu. Pamatujte, ConfirmImpact že pokud je nastavená na System.Management.Automation.ConfirmImpact High.

Podobně některé operace pravděpodobně nebudou destruktivní, i když teoreticky upravovat stav systému mimo Windows PowerShell. Tyto rutiny lze nastavit ConfirmImpact na System.Management.Automation.Confirmimpact.Low. Tím se obchází žádosti o potvrzení, kdy uživatel požádal o potvrzení pouze operací se středním dopadem a s vysokým dopadem.

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

Tato část popisuje, jak definovat parametry rutiny, včetně těch, které jsou potřeba pro podporu úprav systému. Pokud potřebujete obecné informace o definování parametrů, podívejte se na přidání parametrů, které zpracovávají vstup z příkazového řádku.

Rutina Stop-Proc tři parametry: Name Force , a PassThru .

Parametr Name odpovídá vlastnosti Name vstupního objektu procesu. Uvědomte si, že parametr v této ukázce je povinný, protože rutina selže, pokud nemá pojmenovaný proces Name k zastavení.

Parametr Force umožňuje uživateli přepsat volání metody System.Management.Automation.Cmdlet.ShouldContinue. Ve skutečnosti by každá rutina, která volá System.Management.Automation.Cmdlet.ShouldContinue, měla mít parametr , takže pokud je zadaný parametr , rutina přeskočí volání Force Force metody System.Management.Automation.Cmdlet.ShouldContinue a pokračuje v operaci. Uvědomte si, že to nemá vliv na volání metody System.Management.Automation.Cmdlet.ShouldProcess.

Parametr umožňuje uživateli určit, jestli rutina předá výstupní objekt prostřednictvím kanálu, v tomto případě PassThru po zastavení procesu. Uvědomte si, že tento parametr je svázán se samotnou rutinou místo s vlastností vstupního objektu.

Tady je deklarace parametru pro Stop-Proc rutinu.

[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 vstupního zpracování

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

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 vaší rutiny by měla zavolat metodu System.Management.Automation.Cmdlet.ShouldProcess, aby se potvrdilo provedení operace před provedením změny (například odstranění souborů) do spuštěného stavu systému. To modulu runtime Windows PowerShell zadat správné chování WhatIf a Confirm v prostředí.

Poznámka

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

Volání Metody System.Management.Automation.Cmdlet.ShouldProcess odešle název prostředku, který se má změnit uživateli, přičemž modul runtime Windows PowerShell bere v úvahu 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í Metody System.Management.Automation.Cmdlet.ShouldProcess z přepsání metody System.Management.Automation.Cmdlet.ProcessRecord v ukázkové Stop-Proc rutině.

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 provádí po volání metody System.Management.Automation.Cmdlet.ShouldProcess a v případě, že parametr nebyl true nastaven na hodnotu Force true . Uživatel pak může poskytnout zpětnou vazbu a říct, jestli by operace měla pokračovat. Vaše rutina volá System.Management.Automation.Cmdlet.ShouldContinue jako další kontrolu potenciálně nebezpečných úprav systému nebo pokud chcete uživateli poskytnout možnosti yes-to-all a no-to-all.

Následující příklad ukazuje volání Metody 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í poskytovat způsob, jak zastavit zpracování vstupu. V případě této rutiny Stop-Proc volání metody System.Management.Automation.Cmdlet.ProcessRecord do metody System.Diagnostics.Process.Kill*. Vzhledem k tomu, že parametr je nastavený na PassThru true , System.Management.Automation.Cmdlet.ProcessRecord volá také System.Management.Automation.Cmdlet.WriteObject pro odeslání objektu procesu do kanálu.

Vzorek kódu

Kompletní vzorový kód C# najdete v ukázce StopProcessSample01.

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

Windows PowerShell předá informace mezi rutinami pomocí objektů .NET. V důsledku toho může rutina potřebovat definovat vlastní typ nebo rutina může potřebovat rozšířit existující typ poskytovaný jinou rutinou. Další informace o definování nových typů nebo rozšíření existujících typů najdete v tématu Rozšíření typů objektůa formátování .

Sestavení rutiny

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

Testování rutiny

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

  • Spusťte Windows PowerShell a pomocí rutiny Stop-Proc zastavte zpracování, jak je znázorněno níže. Vzhledem k tomu, že Name rutina určuje parametr jako povinný, rutina dotazuje 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 upozornění o provedení této akce, protože to 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 bez upozornění. Uvědomte si, že tato položka příkazu používá Force parametr 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í Command-Line vstupu

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

Registrace rutin, poskytovatelů a hostitelských aplikací

Sada SDK Windows PowerShellu

Ukázky rutin