이 샘플에서는 매개 변수에 별칭이 있고 매개 변수가 와일드카드 문자를 지원하는 cmdlet을 작성하는 방법을 보여 줍니다. 이 cmdlet은 Windows PowerShell 2.0에서 제공하는 Stop-Process
cmdlet과 유사합니다.
Visual Studio를 사용하여 샘플을 빌드하는 방법
Windows PowerShell 2.0 SDK가 설치된 상태에서 StopProcessSample03 폴더로 이동합니다. 기본 위치는
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0\Samples\sysmgmt\WindowsPowerShell\csharp\StopProcessSample03
입니다.솔루션(.sln) 파일의 아이콘을 두 번 클릭합니다. 그러면 Microsoft Visual Studio에서 샘플 프로젝트가 열립니다.
빌드 메뉴에서 빌드 솔루션 선택하여 기본
\bin
또는\bin\debug
폴더에서 샘플에 대한 라이브러리를 빌드합니다.
샘플을 실행하는 방법
다음 모듈 폴더를 만듭니다.
[user]\Documents\WindowsPowerShell\Modules\StopProcessSample03
샘플 어셈블리를 모듈 폴더에 복사합니다.
Windows PowerShell을 시작합니다.
다음 명령을 실행하여 Windows PowerShell에 어셈블리를 로드합니다.
Import-Module stopprossessample03
다음 명령을 실행하여 cmdlet을 실행합니다.
Stop-Proc
요구 사항
이 샘플에는 Windows PowerShell 2.0이 필요합니다.
입증합니다
이 샘플에서는 다음을 보여 줍니다.
Cmdlet 특성을 사용하여 cmdlet 클래스를 선언합니다.
매개 변수 특성을 사용하여 cmdlet 매개 변수 선언
매개 변수 선언에 별칭을 추가합니다.
매개 변수에 와일드카드 지원 추가
예시
이 샘플에서는 매개 변수 별칭을 선언하고 와일드카드를 지원하는 방법을 보여 줍니다.
using System;
using System.Diagnostics;
using System.Collections;
using Win32Exception = System.ComponentModel.Win32Exception;
using System.Management.Automation; //Windows PowerShell namespace
using System.Globalization;
namespace Microsoft.Samples.PowerShell.Commands
{
#region StopProcCommand
/// <summary>
/// This class implements the Stop-Proc cmdlet.
/// </summary>
[Cmdlet(VerbsLifecycle.Stop, "Proc",
SupportsShouldProcess = true)]
public class StopProcCommand : Cmdlet
{
#region Parameters
/// <summary>
/// This parameter provides the list of process names on
/// which the Stop-Proc cmdlet will work.
/// </summary>
[Parameter(
Position = 0,
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
HelpMessage = "The name of one or more processes to stop. Wildcards are permitted."
)]
[Alias("ProcessName")]
public string[] Name
{
get { return processNames; }
set { processNames = value; }
}
private string[] processNames;
/// <summary>
/// This parameter overrides the ShouldContinue call to force
/// the cmdlet to stop its operation. This parameter should always
/// be used with caution.
/// </summary>
[Parameter]
public SwitchParameter Force
{
get { return force; }
set { force = value; }
}
private bool force;
/// <summary>
/// This parameter indicates that the cmdlet should return
/// an object to the pipeline after the processing has been
/// completed.
/// </summary>
[Parameter(
ValueFromPipelineByPropertyName = true,
HelpMessage = "If set, the process(es) will be passed to the pipeline after stopped."
)]
public SwitchParameter PassThru
{
get { return passThru; }
set { passThru = value; }
}
private bool passThru;
#endregion Parameters
#region Cmdlet Overrides
/// <summary>
/// The ProcessRecord method does the following for each of the
/// requested process names:
/// 1) Check that the process is not a critical process.
/// 2) Attempt to stop that process.
/// If no process is requested then nothing occurs.
/// </summary>
protected override void ProcessRecord()
{
Process[] processes = null;
try
{
processes = Process.GetProcesses();
}
catch (InvalidOperationException ioe)
{
base.ThrowTerminatingError(new ErrorRecord(ioe,
"UnableToAccessProcessList",
ErrorCategory.InvalidOperation,
null));
}
// For every process name passed to the cmdlet, get the associated
// processes.
// Write a non-terminating error for failure to retrieve
// a process.
foreach (string name in processNames)
{
// Write a user-friendly verbose message to the pipeline. These
// messages are intended to give the user detailed information
// on the operations performed by the cmdlet. These messages will
// appear with the -Verbose option.
string message = String.Format(CultureInfo.CurrentCulture,
"Attempting to stop process \"{0}\".", name);
WriteVerbose(message);
// Validate the process name against a wildcard pattern.
// If the name does not contain any wildcard patterns, it
// will be treated as an exact match.
WildcardOptions options = WildcardOptions.IgnoreCase |
WildcardOptions.Compiled;
WildcardPattern wildcard = new WildcardPattern(name,options);
foreach (Process process in processes)
{
string processName;
try
{
processName = process.ProcessName;
}
catch (Win32Exception e)
{
WriteError(new ErrorRecord(
e, "ProcessNameNotFound",
ErrorCategory.ObjectNotFound,
process)
);
continue;
}
// Write a debug message to the host that can be used when
// troubleshooting a problem. All debug messages will appear
// with the -Debug option.
message = String.Format(CultureInfo.CurrentCulture,
"Acquired name for pid {0} : \"{1}\"",
process.Id, processName);
WriteDebug(message);
// Check to see if this process matches the current process
// name pattern. Skip this process if it does not.
if (!wildcard.IsMatch(processName))
{
continue;
}
// Stop the process.
SafeStopProcess(process);
} // foreach (Process...
} // foreach (string...
} // ProcessRecord
#endregion Cmdlet Overrides
#region Helper Methods
/// <summary>
/// Safely stops a named process. Used as standalone function
/// to declutter the ProcessRecord method.
/// </summary>
/// <param name="process">The process to stop.</param>
private void SafeStopProcess(Process process)
{
string processName = null;
try
{
processName = process.ProcessName;
}
catch (Win32Exception e)
{
WriteError(new ErrorRecord(e, "ProcessNameNotFound",
ErrorCategory.ObjectNotFound, process));
return;
}
string message = null;
// Confirm the operation first.
// This is always false if the WhatIf parameter is specified.
if (!ShouldProcess(string.Format(CultureInfo.CurrentCulture,
"{0} ({1})", processName, process.Id)))
{
return;
}
// Make sure that the user really wants to stop a critical
// process that could possibly stop the computer.
bool criticalProcess = criticalProcessNames.Contains(processName.ToLower(CultureInfo.CurrentCulture));
if (criticalProcess && !force)
{
message = String.Format(CultureInfo.CurrentCulture,
"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
// when objects are received as inputs from a pipeline.
// So, to retain YesToAll and NoToAll input that the
// user may enter across multiple calls to this
// function, they are stored as private members of the
// Cmdlet.
if (!ShouldContinue(message, "Warning!",
ref yesToAll, ref noToAll))
{
return;
}
} // if (criticalProcess...
// Display a warning message if stopping a critical
// process.
if (criticalProcess)
{
message = String.Format(CultureInfo.CurrentCulture,
"Stopping the critical process \"{0}\".",
processName);
WriteWarning(message);
} // if (criticalProcess...
try
{
// Stop the process.
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.
WriteError(new ErrorRecord(e, "CouldNotStopProcess",
ErrorCategory.CloseError,
process)
);
return;
} // if ((e is...
else throw;
} // catch
message = String.Format(CultureInfo.CurrentCulture,
"Stopped process \"{0}\", pid {1}.",
processName, process.Id);
WriteVerbose(message);
// If the PassThru parameter is specified,
// return the terminated process to the pipeline.
if (passThru)
{
message = String.Format(CultureInfo.CurrentCulture,
"Writing process \"{0}\" to pipeline",
processName);
WriteDebug(message);
WriteObject(process);
} // if (passThru...
} // SafeStopProcess
#endregion Helper Methods
#region Private Data
private bool yesToAll, noToAll;
/// <summary>
/// Partial list of the critical processes that should not be
/// stopped. Lower case is used for case insensitive matching.
/// </summary>
private ArrayList criticalProcessNames = new ArrayList(
new string[] { "system", "winlogon", "spoolsv" }
);
#endregion Private Data
} // StopProcCommand
#endregion StopProcCommand
} // namespace Microsoft.Samples.PowerShell.Commands
또한 참조하십시오
PowerShell