Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
PSCommand.cs518 linesDownload Raw Back to hostifaces
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Management.Automation.Runspaces;5 6using Dbg = System.Management.Automation.Diagnostics;7 8namespace System.Management.Automation9{10    /// <summary>11    /// Defines a PowerShell command / script object which can be used with12    /// <see cref="PowerShell"/> object.13    /// </summary>14    public sealed class PSCommand15    {16        #region Private Fields17 18        private PowerShell _owner;19        private CommandCollection _commands;20        private Command _currentCommand;21 22        #endregion23 24        #region Constructor25 26        /// <summary>27        /// Creates an empty PSCommand; a command or script must be added to this PSCommand before it can be executed.28        /// </summary>29        public PSCommand()30        {31            Initialize(null, false, null);32        }33 34        /// <summary>35        /// Internal copy constructor.36        /// </summary>37        /// <param name="commandToClone"></param>38        internal PSCommand(PSCommand commandToClone)39        {40            _commands = new CommandCollection();41            foreach (Command command in commandToClone.Commands)42            {43                Command clone = command.Clone();44                // Attach the cloned Command to this instance.45                _commands.Add(clone);46                _currentCommand = clone;47            }48        }49 50        /// <summary>51        /// Creates a PSCommand from the specified command.52        /// </summary>53        /// <param name="command">Command object to use.</param>54        internal PSCommand(Command command)55        {56            _currentCommand = command;57            _commands = new CommandCollection();58            _commands.Add(_currentCommand);59        }60 61        #endregion62 63        #region Command / Parameter Construction64 65        /// <summary>66        /// Add a command to construct a command pipeline.67        /// For example, to construct a command string "get-process | sort-object",68        ///     <code>69        ///         PSCommand command = new PSCommand("get-process").AddCommand("sort-object");70        ///     </code>71        /// </summary>72        /// <param name="command">73        /// A string representing the command.74        /// </param>75        /// <exception cref="InvalidPowerShellStateException">76        /// Powershell instance cannot be changed in its77        /// current state.78        /// </exception>79        /// <returns>80        /// A PSCommand instance with <paramref name="command"/> added.81        /// </returns>82        /// <remarks>83        /// This method is not thread safe.84        /// </remarks>85        /// <exception cref="ArgumentNullException">86        /// cmdlet is null.87        /// </exception>88        public PSCommand AddCommand(string command)89        {90            if (command == null)91            {92                throw PSTraceSource.NewArgumentNullException(nameof(command));93            }94 95            _owner?.AssertChangesAreAccepted();96 97            _currentCommand = new Command(command, false);98            _commands.Add(_currentCommand);99 100            return this;101        }102 103        /// <summary>104        /// Add a cmdlet to construct a command pipeline.105        /// For example, to construct a command string "get-process | sort-object",106        ///     <code>107        ///         PSCommand command = new PSCommand("get-process").AddCommand("sort-object");108        ///     </code>109        /// </summary>110        /// <param name="cmdlet">111        /// A string representing cmdlet.112        /// </param>113        /// <param name="useLocalScope">114        /// if true local scope is used to run the script command.115        /// </param>116        /// <exception cref="InvalidPowerShellStateException">117        /// Powershell instance cannot be changed in its118        /// current state.119        /// </exception>120        /// <returns>121        /// A PSCommand instance with <paramref name="cmdlet"/> added.122        /// </returns>123        /// <remarks>124        /// This method is not thread safe.125        /// </remarks>126        /// <exception cref="ArgumentNullException">127        /// cmdlet is null.128        /// </exception>129        public PSCommand AddCommand(string cmdlet, bool useLocalScope)130        {131            if (cmdlet == null)132            {133                throw PSTraceSource.NewArgumentNullException(nameof(cmdlet));134            }135 136            _owner?.AssertChangesAreAccepted();137 138            _currentCommand = new Command(cmdlet, false, useLocalScope);139            _commands.Add(_currentCommand);140 141            return this;142        }143 144        /// <summary>145        /// Add a piece of script to construct a command pipeline.146        /// For example, to construct a command string "get-process | foreach { $_.Name }"147        ///     <code>148        ///         PSCommand command = new PSCommand("get-process")149        ///             .AddScript("foreach { $_.Name }", true);150        ///     </code>151        /// </summary>152        /// <param name="script">153        /// A string representing the script.154        /// </param>155        /// <returns>156        /// A PSCommand instance with <paramref name="script"/> added.157        /// </returns>158        /// <remarks>159        /// This method is not thread-safe.160        /// </remarks>161        /// <exception cref="ArgumentNullException">162        /// command is null.163        /// </exception>164        /// <exception cref="InvalidPowerShellStateException">165        /// Powershell instance cannot be changed in its166        /// current state.167        /// </exception>168        public PSCommand AddScript(string script)169        {170            if (script == null)171            {172                throw PSTraceSource.NewArgumentNullException(nameof(script));173            }174 175            _owner?.AssertChangesAreAccepted();176 177            _currentCommand = new Command(script, true);178            _commands.Add(_currentCommand);179 180            return this;181        }182 183        /// <summary>184        /// Add a piece of script to construct a command pipeline.185        /// For example, to construct a command string "get-process | foreach { $_.Name }"186        ///     <code>187        ///         PSCommand command = new PSCommand("get-process")188        ///             .AddScript("foreach { $_.Name }", true);189        ///     </code>190        /// </summary>191        /// <param name="script">192        /// A string representing the script.193        /// </param>194        /// <param name="useLocalScope">195        /// if true local scope is used to run the script command.196        /// </param>197        /// <returns>198        /// A PSCommand instance with <paramref name="script"/> added.199        /// </returns>200        /// <remarks>201        /// This method is not thread-safe.202        /// </remarks>203        /// <exception cref="ArgumentNullException">204        /// command is null.205        /// </exception>206        /// <exception cref="InvalidPowerShellStateException">207        /// Powershell instance cannot be changed in its208        /// current state.209        /// </exception>210        public PSCommand AddScript(string script, bool useLocalScope)211        {212            if (script == null)213            {214                throw PSTraceSource.NewArgumentNullException(nameof(script));215            }216 217            _owner?.AssertChangesAreAccepted();218 219            _currentCommand = new Command(script, true, useLocalScope);220            _commands.Add(_currentCommand);221 222            return this;223        }224 225        /// <summary>226        /// Add a <see cref="Command"/> element to the current command227        /// pipeline.228        /// </summary>229        /// <param name="command">230        /// Command to add.231        /// </param>232        /// <returns>233        /// A PSCommand instance with <paramref name="command"/> added.234        /// </returns>235        /// <remarks>236        /// This method is not thread-safe.237        /// </remarks>238        /// <exception cref="ArgumentNullException">239        /// command is null.240        /// </exception>241        /// <exception cref="InvalidPowerShellStateException">242        /// Powershell instance cannot be changed in its243        /// current state.244        /// </exception>245        public PSCommand AddCommand(Command command)246        {247            if (command == null)248            {249                throw PSTraceSource.NewArgumentNullException(nameof(command));250            }251 252            _owner?.AssertChangesAreAccepted();253 254            _currentCommand = command;255            _commands.Add(_currentCommand);256 257            return this;258        }259 260        /// <summary>261        /// Add a parameter to the last added command.262        /// For example, to construct a command string "get-process | select-object -property name"263        ///     <code>264        ///         PSCommand command = new PSCommand("get-process")265        ///             .AddCommand("select-object")266        ///             .AddParameter("property", "name");267        ///     </code>268        /// </summary>269        /// <param name="parameterName">270        /// Name of the parameter.271        /// </param>272        /// <param name="value">273        /// Value for the parameter.274        /// </param>275        /// <returns>276        /// A PSCommand instance with <paramref name="parameterName"/> added277        /// to the parameter list of the last command.278        /// </returns>279        /// <remarks>280        /// This method is not thread safe.281        /// </remarks>282        /// <exception cref="ArgumentException">283        /// Name is non null and name length is zero after trimming whitespace.284        /// </exception>285        /// <exception cref="InvalidPowerShellStateException">286        /// Powershell instance cannot be changed in its287        /// current state.288        /// </exception>289        public PSCommand AddParameter(string parameterName, object value)290        {291            if (_currentCommand == null)292            {293                throw PSTraceSource.NewInvalidOperationException(PSCommandStrings.ParameterRequiresCommand,294                                                                 new object[] { "PSCommand" });295            }296 297            _owner?.AssertChangesAreAccepted();298 299            _currentCommand.Parameters.Add(parameterName, value);300            return this;301        }302 303        /// <summary>304        /// Adds a switch parameter to the last added command.305        /// For example, to construct a command string "get-process | sort-object -descending"306        ///     <code>307        ///         PSCommand command = new PSCommand("get-process")308        ///             .AddCommand("sort-object")309        ///             .AddParameter("descending");310        ///     </code>311        /// </summary>312        /// <param name="parameterName">313        /// Name of the parameter.314        /// </param>315        /// <returns>316        /// A PSCommand instance with <paramref name="parameterName"/> added317        /// to the parameter list of the last command.318        /// </returns>319        /// <remarks>320        /// This method is not thread safe.321        /// </remarks>322        /// <exception cref="ArgumentException">323        /// Name is non null and name length is zero after trimming whitespace.324        /// </exception>325        /// <exception cref="InvalidPowerShellStateException">326        /// Powershell instance cannot be changed in its327        /// current state.328        /// </exception>329        public PSCommand AddParameter(string parameterName)330        {331            if (_currentCommand == null)332            {333                throw PSTraceSource.NewInvalidOperationException(PSCommandStrings.ParameterRequiresCommand,334                                                                 new object[] { "PSCommand" });335            }336 337            _owner?.AssertChangesAreAccepted();338 339            _currentCommand.Parameters.Add(parameterName, true);340            return this;341        }342 343        /// <summary>344        /// Adds a <see cref="CommandParameter"/> instance to the last added command.345        /// </summary>346        internal PSCommand AddParameter(CommandParameter parameter)347        {348            if (_currentCommand == null)349            {350                throw PSTraceSource.NewInvalidOperationException(PSCommandStrings.ParameterRequiresCommand,351                                                                 new object[] { "PSCommand" });352            }353 354            _owner?.AssertChangesAreAccepted();355 356            _currentCommand.Parameters.Add(parameter);357            return this;358        }359 360        /// <summary>361        /// Adds an argument to the last added command.362        /// For example, to construct a command string "get-process | select-object name"363        ///     <code>364        ///         PSCommand command = new PSCommand("get-process")365        ///             .AddCommand("select-object")366        ///             .AddArgument("name");367        ///     </code>368        /// This will add the value "name" to the positional parameter list of "select-object"369        /// cmdlet. When the command is invoked, this value will get bound to positional parameter 0370        /// of the "select-object" cmdlet which is "Property".371        /// </summary>372        /// <param name="value">373        /// Value for the parameter.374        /// </param>375        /// <returns>376        /// A PSCommand instance parameter value <paramref name="value"/> added377        /// to the parameter list of the last command.378        /// </returns>379        /// <exception cref="InvalidPowerShellStateException">380        /// Powershell instance cannot be changed in its381        /// current state.382        /// </exception>383        /// <remarks>384        /// This method is not thread safe.385        /// </remarks>386        public PSCommand AddArgument(object value)387        {388            if (_currentCommand == null)389            {390                throw PSTraceSource.NewInvalidOperationException(PSCommandStrings.ParameterRequiresCommand,391                                                                 new object[] { "PSCommand" });392            }393 394            _owner?.AssertChangesAreAccepted();395 396            _currentCommand.Parameters.Add(null, value);397            return this;398        }399 400        /// <summary>401        /// Adds an additional statement for execution402        ///403        /// For example,404        ///     <code>405        ///         Runspace rs = RunspaceFactory.CreateRunspace();406        ///         PowerShell ps = PowerShell.Create();407        ///408        ///         ps.Runspace = rs;409        ///         ps.AddCommand("Get-Process").AddArgument("idle");410        ///         ps.AddStatement().AddCommand("Get-Service").AddArgument("audiosrv");411        ///         ps.Invoke();412        ///     </code>413        /// </summary>414        /// <returns>415        /// A PowerShell instance with the items in <paramref name="parameters"/> added416        /// to the parameter list of the last command.417        /// </returns>418        public PSCommand AddStatement()419        {420            if (_commands.Count == 0)421            {422                return this;423            }424 425            _commands[_commands.Count - 1].IsEndOfStatement = true;426            return this;427        }428 429        #endregion430 431        #region Properties and Methods432 433        /// <summary>434        /// Gets the collection of commands from this PSCommand435        /// instance.436        /// </summary>437        public CommandCollection Commands438        {439            get440            {441                return _commands;442            }443        }444 445        /// <summary>446        /// The PowerShell instance this PSCommand is associated to, or null if it is an standalone command.447        /// </summary>448        internal PowerShell Owner449        {450            get451            {452                return _owner;453            }454 455            set456            {457                _owner = value;458            }459        }460 461        /// <summary>462        /// Clears the command(s).463        /// </summary>464        public void Clear()465        {466            _commands.Clear();467            _currentCommand = null;468        }469 470        /// <summary>471        /// Creates a shallow copy of the current PSCommand.472        /// </summary>473        /// <returns>474        /// A shallow copy of the current PSCommand475        /// </returns>476        public PSCommand Clone()477        {478            return new PSCommand(this);479        }480 481        #endregion482 483        #region Private Methods484 485        /// <summary>486        /// Initializes the instance. Called from the constructor.487        /// </summary>488        /// <param name="command">489        /// Command to initialize the instance with.490        /// </param>491        /// <param name="isScript">492        /// true if the <paramref name="command"/> is script,493        /// false otherwise.494        /// </param>495        /// <param name="useLocalScope">496        /// if true local scope is used to run the script command.497        /// </param>498        /// <remarks>499        /// Caller should check the input.500        /// </remarks>501        /// <exception cref="ArgumentNullException">502        /// command is null503        /// </exception>504        private void Initialize(string command, bool isScript, bool? useLocalScope)505        {506            _commands = new CommandCollection();507 508            if (command != null)509            {510                _currentCommand = new Command(command, isScript, useLocalScope);511                _commands.Add(_currentCommand);512            }513        }514 515        #endregion516    }517}518