/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
using System.Management.Automation.Runspaces;
using Dbg = System.Management.Automation.Diagnostics;
namespace System.Management.Automation
{
///
/// Defines a PowerShell command / script object which can be used with
/// object.
///
public sealed class PSCommand
{
#region Private Fields
private PowerShell _owner;
private CommandCollection _commands;
private Command _currentCommand;
#endregion
#region Constructor
///
/// Creates an empty PSCommand; a command or script must be added to this PSCommand before it can be executed.
///
public PSCommand()
{
Initialize(null, false, null);
}
///
/// Internal copy constructor
///
///
internal PSCommand(PSCommand commandToClone)
{
_commands = new CommandCollection();
foreach (Command command in commandToClone.Commands)
{
Command clone = command.Clone();
// Attach the cloned Command to this instance.
_commands.Add(clone);
_currentCommand = clone;
}
}
///
/// Creates a PSCommand from the specified command
///
/// Command object to use
internal PSCommand(Command command)
{
_currentCommand = command;
_commands = new CommandCollection();
_commands.Add(_currentCommand);
}
#endregion
#region Command / Parameter Construction
///
/// Add a command to construct a command pipeline.
/// For example, to construct a command string "get-process | sort-object",
///
/// PSCommand command = new PSCommand("get-process").AddCommand("sort-object");
///
///
///
/// A string representing the command.
///
///
/// Powershell instance cannot be changed in its
/// current state.
///
///
/// A PSCommand instance with added.
///
///
/// This method is not thread safe.
///
///
/// cmdlet is null.
///
public PSCommand AddCommand(string command)
{
if (null == command)
{
throw PSTraceSource.NewArgumentNullException("cmdlet");
}
if (_owner != null)
{
_owner.AssertChangesAreAccepted();
}
_currentCommand = new Command(command, false);
_commands.Add(_currentCommand);
return this;
}
///
/// Add a cmdlet to construct a command pipeline.
/// For example, to construct a command string "get-process | sort-object",
///
/// PSCommand command = new PSCommand("get-process").AddCommand("sort-object");
///
///
///
/// A string representing cmdlet.
///
///
/// if true local scope is used to run the script command.
///
///
/// Powershell instance cannot be changed in its
/// current state.
///
///
/// A PSCommand instance with added.
///
///
/// This method is not thread safe.
///
///
/// cmdlet is null.
///
public PSCommand AddCommand(string cmdlet, bool useLocalScope)
{
if (null == cmdlet)
{
throw PSTraceSource.NewArgumentNullException("cmdlet");
}
if (_owner != null)
{
_owner.AssertChangesAreAccepted();
}
_currentCommand = new Command(cmdlet, false, useLocalScope);
_commands.Add(_currentCommand);
return this;
}
///
/// Add a piece of script to construct a command pipeline.
/// For example, to construct a command string "get-process | foreach { $_.Name }"
///
/// PSCommand command = new PSCommand("get-process").
/// AddCommand("foreach { $_.Name }", true);
///
///
///
/// A string representing the script.
///
///
/// A PSCommand instance with added.
///
///
/// This method is not thread-safe.
///
///
/// command is null.
///
///
/// Powershell instance cannot be changed in its
/// current state.
///
public PSCommand AddScript(string script)
{
if (null == script)
{
throw PSTraceSource.NewArgumentNullException("script");
}
if (_owner != null)
{
_owner.AssertChangesAreAccepted();
}
_currentCommand = new Command(script, true);
_commands.Add(_currentCommand);
return this;
}
///
/// Add a piece of script to construct a command pipeline.
/// For example, to construct a command string "get-process | foreach { $_.Name }"
///
/// PSCommand command = new PSCommand("get-process").
/// AddCommand("foreach { $_.Name }", true);
///
///
///
/// A string representing the script.
///
///
/// if true local scope is used to run the script command.
///
///
/// A PSCommand instance with added.
///
///
/// This method is not thread-safe.
///
///
/// command is null.
///
///
/// Powershell instance cannot be changed in its
/// current state.
///
public PSCommand AddScript(string script, bool useLocalScope)
{
if (null == script)
{
throw PSTraceSource.NewArgumentNullException("script");
}
if (_owner != null)
{
_owner.AssertChangesAreAccepted();
}
_currentCommand = new Command(script, true, useLocalScope);
_commands.Add(_currentCommand);
return this;
}
///
/// Add a element to the current command
/// pipeline.
///
///
/// Command to add.
///
///
/// A PSCommand instance with added.
///
///
/// This method is not thread-safe.
///
///
/// command is null.
///
///
/// Powershell instance cannot be changed in its
/// current state.
///
public PSCommand AddCommand(Command command)
{
if (null == command)
{
throw PSTraceSource.NewArgumentNullException("command");
}
if (_owner != null)
{
_owner.AssertChangesAreAccepted();
}
_currentCommand = command;
_commands.Add(_currentCommand);
return this;
}
///
/// Add a parameter to the last added command.
/// For example, to construct a command string "get-process | select-object -property name"
///
/// PSCommand command = new PSCommand("get-process").
/// AddCommand("select-object").AddParameter("property","name");
///
///
///
/// Name of the parameter.
///
///
/// Value for the parameter.
///
///
/// A PSCommand instance with added
/// to the parameter list of the last command.
///
///
/// This method is not thread safe.
///
///
/// Name is non null and name length is zero after trimming whitespace.
///
///
/// Powershell instance cannot be changed in its
/// current state.
///
public PSCommand AddParameter(string parameterName, object value)
{
if (null == _currentCommand)
{
throw PSTraceSource.NewInvalidOperationException(PSCommandStrings.ParameterRequiresCommand,
new object[] { "PSCommand" });
}
if (_owner != null)
{
_owner.AssertChangesAreAccepted();
}
_currentCommand.Parameters.Add(parameterName, value);
return this;
}
///
/// Adds a switch parameter to the last added command.
/// For example, to construct a command string "get-process | sort-object -descending"
///
/// PSCommand command = new PSCommand("get-process").
/// AddCommand("sort-object").AddParameter("descending");
///
///
///
/// Name of the parameter.
///
///
/// A PSCommand instance with added
/// to the parameter list of the last command.
///
///
/// This method is not thread safe.
///
///
/// Name is non null and name length is zero after trimming whitespace.
///
///
/// Powershell instance cannot be changed in its
/// current state.
///
public PSCommand AddParameter(string parameterName)
{
if (null == _currentCommand)
{
throw PSTraceSource.NewInvalidOperationException(PSCommandStrings.ParameterRequiresCommand,
new object[] { "PSCommand" });
}
if (_owner != null)
{
_owner.AssertChangesAreAccepted();
}
_currentCommand.Parameters.Add(parameterName, true);
return this;
}
///
/// Adds an argument to the last added command.
/// For example, to construct a command string "get-process | select-object name"
///
/// PSCommand command = new PSCommand("get-process").
/// AddCommand("select-object").AddParameter("name");
///
///
/// This will add the value "name" to the positional parameter list of "select-object"
/// cmdlet. When the command is invoked, this value will get bound to positional parameter 0
/// of the "select-object" cmdlet which is "Property".
///
///
/// Value for the parameter.
///
///
/// A PSCommand instance parameter value added
/// to the parameter list of the last command.
///
///
/// Powershell instance cannot be changed in its
/// current state.
///
///
/// This method is not thread safe.
///
public PSCommand AddArgument(object value)
{
if (null == _currentCommand)
{
throw PSTraceSource.NewInvalidOperationException(PSCommandStrings.ParameterRequiresCommand,
new object[] { "PSCommand" });
}
if (_owner != null)
{
_owner.AssertChangesAreAccepted();
}
_currentCommand.Parameters.Add(null, value);
return this;
}
///
/// Adds an additional statement for execution
///
/// For example,
///
/// Runspace rs = RunspaceFactory.CreateRunspace();
/// PowerShell ps = PowerShell.Create();
///
/// ps.Runspace = rs;
/// ps.AddCommand("Get-Process").AddArgument("idle");
/// ps.AddStatement().AddCommand("Get-Service").AddArgument("audiosrv");
/// ps.Invoke();
///
///
///
/// A PowerShell instance with the items in added
/// to the parameter list of the last command.
///
public PSCommand AddStatement()
{
if (_commands.Count == 0)
{
return this;
}
_commands[_commands.Count - 1].IsEndOfStatement = true;
return this;
}
#endregion
#region Properties and Methods
///
/// Gets the collection of commands from this PSCommand
/// instance.
///
public CommandCollection Commands
{
get
{
return _commands;
}
}
///
/// The PowerShell instance this PSCommand is associated to, or null if it is an standalone command
///
internal PowerShell Owner
{
get
{
return _owner;
}
set
{
_owner = value;
}
}
///
/// Clears the command(s).
///
public void Clear()
{
_commands.Clear();
_currentCommand = null;
}
///
/// Creates a shallow copy of the current PSCommand.
///
///
/// A shallow copy of the current PSCommand
///
public PSCommand Clone()
{
return new PSCommand(this);
}
#endregion
#region Private Methods
///
/// Initializes the instance. Called from the constructor.
///
///
/// Command to initialize the instance with.
///
///
/// true if the is script,
/// false otherwise.
///
///
/// if true local scope is used to run the script command.
///
///
/// Caller should check the input.
///
///
/// command is null
///
private void Initialize(string command, bool isScript, bool? useLocalScope)
{
_commands = new CommandCollection();
if (command != null)
{
_currentCommand = new Command(command, isScript, useLocalScope);
_commands.Add(_currentCommand);
}
}
#endregion
}
}