Bagikan melalui


Membuat Cmdlet yang Memodifikasi Sistem

Terkadang cmdlet harus memodifikasi status sistem yang sedang berjalan, bukan hanya status runtime Windows PowerShell. Dalam kasus ini, cmdlet harus memungkinkan pengguna untuk mengonfirmasi apakah akan melakukan perubahan atau tidak.

Untuk mendukung konfirmasi, cmdlet harus melakukan dua hal.

Dengan mendukung konfirmasi, cmdlet mengekspos parameter Confirm dan WhatIf yang disediakan oleh Windows PowerShell, dan juga memenuhi panduan pengembangan untuk cmdlet (Untuk informasi selengkapnya tentang panduan pengembangan cmdlet, lihat Panduan Pengembangan Cmdlet.).

Mengubah Sistem

Tindakan "mengubah sistem" mengacu pada cmdlet apa pun yang berpotensi mengubah status sistem di luar Windows PowerShell. Misalnya, menghentikan proses, mengaktifkan atau menonaktifkan akun pengguna, atau menambahkan baris ke tabel database adalah semua perubahan pada sistem yang harus dikonfirmasi. Sebaliknya, operasi yang membaca data atau membuat koneksi sementara tidak mengubah sistem dan umumnya tidak memerlukan konfirmasi. Konfirmasi juga tidak diperlukan untuk tindakan yang efeknya terbatas pada di dalam runtime Windows PowerShell, seperti Set-Variable. Cmdlet yang mungkin atau mungkin tidak membuat perubahan persisten harus mendeklarasikan SupportsShouldProcess dan memanggil System.Management.Automation.Cmdlet.ShouldProcess hanya jika mereka akan membuat perubahan persisten.

Nota

Konfirmasi ShouldProcess hanya berlaku untuk cmdlet. Jika perintah atau skrip memodifikasi status sistem yang sedang berjalan dengan langsung memanggil metode atau properti .NET, atau dengan memanggil aplikasi di luar Windows PowerShell, bentuk konfirmasi ini tidak akan tersedia.

The StopProc Cmdlet

Topik ini menjelaskan cmdlet Stop-Proc yang mencoba menghentikan proses yang diambil menggunakan cmdlet Get-Proc (dijelaskan dalam Membuat Cmdlet Pertama Anda).

Menentukan Cmdlet

Langkah pertama dalam pembuatan cmdlet adalah selalu menamai cmdlet dan mendeklarasikan kelas .NET yang mengimplementasikan cmdlet. Karena Anda menulis cmdlet untuk mengubah sistem, cmdlet harus diberi nama yang sesuai. Cmdlet ini menghentikan proses sistem, sehingga nama kata kerja yang dipilih di sini adalah "Stop", yang ditentukan oleh kelas System.Management.Automation.VerbsLifecycle, dengan kata benda "Proc" untuk menunjukkan bahwa cmdlet menghentikan proses. Untuk informasi selengkapnya tentang kata kerja cmdlet yang disetujui, lihat Nama Kata Kerja Cmdlet.

Berikut ini adalah definisi kelas untuk cmdlet Stop-Proc ini.

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

Ketahuilah bahwa dalam deklarasi System.Management.Automation.CmdletAttribute, kata kunci atribut SupportsShouldProcess diatur ke true untuk mengaktifkan cmdlet untuk melakukan panggilan ke System.Management.Automation.Cmdlet.ShouldProcess dan System.Management.Automation.Cmdlet.ShouldContinue. Tanpa kumpulan kata kunci ini, parameter Confirm dan WhatIf tidak akan tersedia untuk pengguna.

Tindakan yang Sangat Merusak

Beberapa operasi sangat merusak, seperti memformat ulang partisi hard disk aktif. Dalam kasus ini, cmdlet harus mengatur ConfirmImpact = ConfirmImpact.High saat mendeklarasikan atribut System.Management.Automation.CmdletAttribute. Pengaturan ini memaksa cmdlet untuk meminta konfirmasi pengguna bahkan ketika pengguna belum menentukan parameter Confirm. Namun, pengembang cmdlet harus menghindari penggunaan ConfirmImpact berlebihan untuk operasi yang berpotensi merusak, seperti menghapus akun pengguna. Ingatlah bahwa jika ConfirmImpact diatur ke System.Management.Automation.ConfirmImpactHigh.

Demikian pula, beberapa operasi tidak mungkin merusak, meskipun mereka melakukan secara teori memodifikasi status berjalan sistem di luar Windows PowerShell. Cmdlet tersebut dapat mengatur ConfirmImpact ke System.Management.Automation.ConfirmImpact.Low. Ini akan melewati permintaan konfirmasi di mana pengguna telah meminta untuk mengonfirmasi hanya operasi berdampak sedang dan berdampak tinggi.

Menentukan Parameter untuk Modifikasi Sistem

Bagian ini menjelaskan cara menentukan parameter cmdlet, termasuk yang diperlukan untuk mendukung modifikasi sistem. Lihat Menambahkan Parameter yang memproses Input CommandLine jika Anda memerlukan informasi umum tentang menentukan parameter.

Cmdlet Stop-Proc mendefinisikan tiga parameter: Name, Force, dan PassThru.

Parameter Name sesuai dengan properti Name dari objek input proses. Ketahuilah bahwa parameter Name dalam sampel ini wajib, karena cmdlet akan gagal jika tidak memiliki proses bernama untuk dihentikan.

Parameter Force memungkinkan pengguna untuk mengambil alih panggilan ke System.Management.Automation.Cmdlet.ShouldContinue. Bahkan, cmdlet apa pun yang memanggil System.Management.Automation.Cmdlet.ShouldContinue harus memiliki parameter Force sehingga ketika Force ditentukan, cmdlet melewati panggilan ke System.Management.Automation.Cmdlet.ShouldContinue dan melanjutkan operasi. Ketahuilah bahwa ini tidak memengaruhi panggilan ke System.Management.Automation.Cmdlet.ShouldProcess.

Parameter PassThru memungkinkan pengguna untuk menunjukkan apakah cmdlet melewati objek output melalui alur, dalam hal ini, setelah proses dihentikan. Ketahuilah bahwa parameter ini terkait dengan cmdlet itu sendiri alih-alih ke properti objek input.

Berikut adalah deklarasi parameter untuk cmdlet 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;

Mengesampingkan Metode Pemrosesan Input

Cmdlet harus mengambil alih metode pemrosesan input. Kode berikut mengilustrasikan System.Management.Automation.Cmdlet.ProcessRecord mengambil alih yang digunakan dalam cmdlet Stop-Proc sampel. Untuk setiap nama proses yang diminta, metode ini memastikan bahwa prosesnya bukan proses khusus, mencoba menghentikan proses, lalu mengirim objek output jika parameter PassThru ditentukan.

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

Memanggil Metode ShouldProcess

Metode pemrosesan input cmdlet Anda harus memanggil metode System.Management.Automation.Cmdlet.ShouldProcess untuk mengonfirmasi eksekusi operasi sebelum perubahan (misalnya, menghapus file) dibuat ke status sistem yang sedang berjalan. Ini memungkinkan runtime Windows PowerShell untuk menyediakan perilaku "WhatIf" dan "Konfirmasi" yang benar dalam shell.

Nota

Jika cmdlet menyatakan bahwa dukungannya harus diproses dan gagal melakukan panggilan System.Management.Automation.Cmdlet.ShouldProcess, pengguna mungkin mengubah sistem secara tiba-tiba.

Panggilan ke System.Management.Automation.Cmdlet.ShouldProcess mengirim nama sumber daya untuk diubah ke pengguna, dengan runtime Windows PowerShell dengan mempertimbangkan pengaturan baris perintah atau variabel preferensi dalam menentukan apa yang harus ditampilkan kepada pengguna.

Contoh berikut menunjukkan panggilan ke System.Management.Automation.Cmdlet.ShouldProcess dari penggantian metode System.Management.Automation.Cmdlet.ProcessRecord dalam cmdlet Stop-Proc sampel.

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

Memanggil Metode ShouldContinue

Panggilan ke metode System.Management.Automation.Cmdlet.ShouldContinue mengirimkan pesan sekunder kepada pengguna. Panggilan ini dilakukan setelah panggilan ke System.Management.Automation.Cmdlet.ShouldProcess mengembalikan true dan jika parameter Force tidak diatur ke true. Pengguna kemudian dapat memberikan umpan balik untuk mengatakan apakah operasi harus dilanjutkan. Cmdlet Anda memanggil System.Management.Automation.Cmdlet.ShouldContinue sebagai pemeriksaan tambahan untuk modifikasi sistem yang berpotensi berbahaya atau ketika Anda ingin memberikan opsi yes-to-all dan no-to-all kepada pengguna.

Contoh berikut menunjukkan panggilan ke System.Management.Automation.Cmdlet.ShouldContinue dari penggantian metode System.Management.Automation.Cmdlet.ProcessRecord dalam cmdlet Stop-Proc sampel.

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...

Menghentikan Pemrosesan Input

Metode pemrosesan input cmdlet yang membuat modifikasi sistem harus menyediakan cara menghentikan pemrosesan input. Dalam kasus cmdlet Stop-Proc ini, panggilan dilakukan dari metode System.Management.Automation.Cmdlet.ProcessRecord ke metode System.Diagnostics.Process.Kill*. Karena parameter PassThru diatur ke true, System.Management.Automation.Cmdlet.ProcessRecord juga memanggil System.Management.Automation.Cmdlet.WriteObject untuk mengirim objek proses ke alur.

Sampel Kode

Untuk kode sampel C# lengkap, lihat Sampel StopProcessSample01.

Menentukan Tipe objek dan Pemformatan

Windows PowerShell meneruskan informasi antar cmdlet menggunakan objek .NET. Akibatnya, cmdlet mungkin perlu menentukan jenisnya sendiri, atau cmdlet mungkin perlu memperluas jenis yang ada yang disediakan oleh cmdlet lain. Untuk informasi selengkapnya tentang menentukan jenis baru atau memperluas jenis yang sudah ada, lihat Memperluas Tipe Objek dan Pemformatan.

Membangun Cmdlet

Setelah menerapkan cmdlet, cmdlet harus didaftarkan ke Windows PowerShell melalui snap-in Windows PowerShell. Untuk informasi selengkapnya tentang mendaftarkan cmdlet, lihat Cara Mendaftarkan Cmdlet, Penyedia, dan Aplikasi Host.

Menguji Cmdlet

Ketika cmdlet Anda telah terdaftar di Windows PowerShell, Anda dapat mengujinya dengan menjalankannya di baris perintah. Berikut adalah beberapa pengujian yang menguji cmdlet Stop-Proc. Untuk informasi selengkapnya tentang menggunakan cmdlet dari baris perintah, lihat Memulai Windows PowerShell.

  • Mulai Windows PowerShell dan gunakan cmdlet Stop-Proc untuk menghentikan pemrosesan seperti yang ditunjukkan di bawah ini. Karena cmdlet menentukan parameter Name sebagai wajib, cmdlet meminta parameter .

    PS> Stop-Proc
    

    Output berikut muncul.

    Cmdlet Stop-Proc at command pipeline position 1
    Supply values for the following parameters:
    Name[0]:
    
  • Sekarang mari kita gunakan cmdlet untuk menghentikan proses bernama "NOTEPAD". Cmdlet meminta Anda untuk mengonfirmasi tindakan.

    PS> Stop-Proc -Name notepad
    

    Output berikut muncul.

    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
    
  • Gunakan Stop-Proc seperti yang ditunjukkan untuk menghentikan proses penting bernama "WINLOGON". Anda diminta dan diperingatkan tentang melakukan tindakan ini karena akan menyebabkan sistem operasi di-boot ulang.

    PS> Stop-Proc -Name Winlogon
    

    Output berikut muncul.

    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
    
  • Sekarang mari kita coba hentikan proses WINLOGON tanpa menerima peringatan. Ketahuilah bahwa entri perintah ini menggunakan parameter Force untuk mengambil alih peringatan.

    PS> Stop-Proc -Name winlogon -Force
    

    Output berikut muncul.

    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
    

Lihat Juga

Menambahkan Parameter yang Proses input Command-Line

Memperluas Tipe Objek dan Pemformatan

Cara Mendaftarkan Cmdlet, Penyedia, dan Aplikasi Host

Windows PowerShell SDK

Sampel Cmdlet