此示例演示如何使用 System.Management.Automation.ProxyCommand 类创建调用现有 cmdlet 但限制可用参数集的代理命令。 然后,将代理命令添加到用于创建受约束运行空间的初始会话状态。 这意味着用户只能通过代理命令访问 cmdlet 的功能。
要求
此示例需要 Windows PowerShell 2.0。
演示
此示例演示了以下内容。
创建描述现有 cmdlet 元数据的 System.Management.Automation.CommandMetadata 对象。
创建 System.Management.Automation.Runspaces.InitialSessionState 对象。
修改 cmdlet 元数据以删除 cmdlet 的参数。
将 cmdlet 添加到 System.Management.Automation.Runspaces.InitialSessionState 对象,并使 cmdlet 专用。
创建调用现有 cmdlet 的代理函数,但只公开一组受限的参数。
将代理函数添加到初始会话状态。
创建使用 System.Management.Automation.Runspaces.Runspace 对象的 System.Management.Automation.PowerShell 对象。
使用 System.Management.Automation.PowerShell 对象调用专用 cmdlet 和代理函数,以演示受约束的运行空间。
示例
这会为专用 cmdlet 创建一个代理命令来演示受约束的运行空间。
namespace Microsoft.Samples.PowerShell.Runspaces
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using PowerShell = System.Management.Automation.PowerShell;
#region GetProcCommand
/// <summary>
/// This class implements the Get-Proc cmdlet. It has been copied
/// verbatim from the GetProcessSample02.cs sample.
/// </summary>
[Cmdlet(VerbsCommon.Get, "Proc")]
public class GetProcCommand : Cmdlet
{
#region Parameters
/// <summary>
/// The names of the processes to act on.
/// </summary>
private string[] processNames;
/// <summary>
/// Gets or sets the list of process names on which
/// the Get-Proc cmdlet will work.
/// </summary>
[Parameter(Position = 0)]
[ValidateNotNullOrEmpty]
public string[] Name
{
get { return this.processNames; }
set { this.processNames = value; }
}
#endregion Parameters
#region Cmdlet Overrides
/// <summary>
/// The ProcessRecord method calls the Process.GetProcesses
/// method to retrieve the processes specified by the Name
/// parameter. Then, the WriteObject method writes the
/// associated processes to the pipeline.
/// </summary>
protected override void ProcessRecord()
{
// If no process names are passed to the cmdlet, get all
// processes.
if (this.processNames == null)
{
WriteObject(Process.GetProcesses(), true);
}
else
{
// If process names are passed to cmdlet, get and write
// the associated processes.
foreach (string name in this.processNames)
{
WriteObject(Process.GetProcessesByName(name), true);
}
} // if (processNames...
} // ProcessRecord
#endregion Cmdlet Overrides
} // GetProcCommand
#endregion GetProcCommand
/// <summary>
/// This class contains the Main entry point for this host application.
/// </summary>
internal class Runspace11
{
/// <summary>
/// This shows how to use the ProxyCommand class to create a proxy
/// command that calls an existing cmdlet, but restricts the set of
/// available parameters. The proxy command is then added to an initial
/// session state that is used to create a constrained runspace. This
/// means that the user can access the cmdlet only through the proxy
/// command.
/// </summary>
/// <remarks>
/// This sample demonstrates the following:
/// 1. Creating a CommandMetadata object that describes the metadata of an
/// existing cmdlet.
/// 2. Modifying the cmdlet metadata to remove a parameter of the cmdlet.
/// 3. Adding the cmdlet to an initial session state and making it private.
/// 4. Creating a proxy function that calls the existing cmdlet, but exposes
/// only a restricted set of parameters.
/// 6. Adding the proxy function to the initial session state.
/// 7. Calling the private cmdlet and the proxy function to demonstrate the
/// constrained runspace.
/// </remarks>
private static void Main()
{
// Create a default initial session state. The default initial session state
// includes all the elements that are provided by Windows PowerShell.
InitialSessionState iss = InitialSessionState.CreateDefault();
// Add the Get-Proc cmdlet to the initial session state.
SessionStateCmdletEntry cmdletEntry = new SessionStateCmdletEntry("Get-Proc", typeof(GetProcCommand), null);
iss.Commands.Add(cmdletEntry);
// Make the cmdlet private so that it is not accessible.
cmdletEntry.Visibility = SessionStateEntryVisibility.Private;
// Set the language mode of the initial session state to NoLanguage to
//prevent users from using language features. Only the invocation of
// public commands is allowed.
iss.LanguageMode = PSLanguageMode.NoLanguage;
// Create the proxy command using cmdlet metadata to expose the
// Get-Proc cmdlet.
CommandMetadata cmdletMetadata = new CommandMetadata(typeof(GetProcCommand));
// Remove one of the parameters from the command metadata.
cmdletMetadata.Parameters.Remove("Name");
// Generate the body of a proxy function that calls the original cmdlet,
// but does not have the removed parameter.
string bodyOfProxyFunction = ProxyCommand.Create(cmdletMetadata);
// Add the proxy function to the initial session state. The name of the proxy
// function can be the same as the name of the cmdlet, but to clearly
// demonstrate that the original cmdlet is not available a different name is
// used for the proxy function.
iss.Commands.Add(new SessionStateFunctionEntry("Get-ProcProxy", bodyOfProxyFunction));
// Create the constrained runspace using the initial session state.
using (Runspace myRunspace = RunspaceFactory.CreateRunspace(iss))
{
myRunspace.Open();
// Call the private cmdlet to demonstrate that it is not available.
try
{
using (PowerShell powershell = PowerShell.Create())
{
powershell.Runspace = myRunspace;
powershell.AddCommand("Get-Proc").AddParameter("Name", "*explore*");
powershell.Invoke();
}
}
catch (CommandNotFoundException e)
{
System.Console.WriteLine(
"Invoking 'Get-Proc' failed as expected: {0}: {1}",
e.GetType().FullName,
e.Message);
}
// Call the proxy function to demonstrate that the -Name parameter is
// not available.
try
{
using (PowerShell powershell = PowerShell.Create())
{
powershell.Runspace = myRunspace;
powershell.AddCommand("Get-ProcProxy").AddParameter("Name", "idle");
powershell.Invoke();
}
}
catch (ParameterBindingException e)
{
System.Console.WriteLine(
"\nInvoking 'Get-ProcProxy -Name idle' failed as expected: {0}: {1}",
e.GetType().FullName,
e.Message);
}
// Call the proxy function to demonstrate that it calls into the
// private cmdlet to retrieve the processes.
using (PowerShell powershell = PowerShell.Create())
{
powershell.Runspace = myRunspace;
powershell.AddCommand("Get-ProcProxy");
List<Process> processes = new List<Process>(powershell.Invoke<Process>());
System.Console.WriteLine(
"\nInvoking the Get-ProcProxy function called into the Get-Proc cmdlet and returned {0} processes",
processes.Count);
}
// Close the runspace to release resources.
myRunspace.Close();
}
System.Console.WriteLine("Hit any key to exit...");
System.Console.ReadKey();
}
}
}