Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
Command.cs903 linesDownload Raw Back to hostifaces
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections.Generic;5using System.Collections.ObjectModel;6using System.Management.Automation.Internal;7 8using Microsoft.Management.Infrastructure;9 10using Dbg = System.Management.Automation.Diagnostics;11 12namespace System.Management.Automation.Runspaces13{14    /// <summary>15    /// Defines a Command object which can be added to <see cref="Pipeline"/> object16    /// for invocation.17    /// </summary>18    public sealed class Command19    {20        #region constructors21 22        /// <summary>23        /// Initializes a new instance of Command class using specified command parameter.24        /// </summary>25        /// <param name="command">Name of the command or script contents.</param>26        /// <exception cref="ArgumentNullException">Command is null.</exception>27        public Command(string command)28            : this(command, false, null)29        {30        }31 32        /// <summary>33        /// Initializes a new instance of Command class using specified command parameter.34        /// </summary>35        /// <param name="command">The command name or script contents.</param>36        /// <param name="isScript">True if this command represents a script, otherwise; false.</param>37        /// <exception cref="ArgumentNullException">Command is null.</exception>38        public Command(string command, bool isScript)39            : this(command, isScript, null)40        {41        }42 43        /// <summary>44        /// Constructor.45        /// </summary>46        /// <param name="command">The command name or script contents.</param>47        /// <param name="isScript">True if this command represents a script, otherwise; false.</param>48        /// <param name="useLocalScope">If true local scope is used to run the script command.</param>49        /// <exception cref="ArgumentNullException">Command is null.</exception>50        public Command(string command, bool isScript, bool useLocalScope)51        {52            IsEndOfStatement = false;53            if (command == null)54            {55                throw PSTraceSource.NewArgumentNullException(nameof(command));56            }57 58            CommandText = command;59            IsScript = isScript;60            _useLocalScope = useLocalScope;61        }62 63        internal Command(string command, bool isScript, bool? useLocalScope)64        {65            IsEndOfStatement = false;66            if (command == null)67            {68                throw PSTraceSource.NewArgumentNullException(nameof(command));69            }70 71            CommandText = command;72            IsScript = isScript;73            _useLocalScope = useLocalScope;74        }75 76        internal Command(string command, bool isScript, bool? useLocalScope, bool mergeUnclaimedPreviousErrorResults)77            : this(command, isScript, useLocalScope)78        {79            if (mergeUnclaimedPreviousErrorResults)80            {81                _mergeUnclaimedPreviousCommandResults = PipelineResultTypes.Error | PipelineResultTypes.Output;82            }83        }84 85        internal Command(CommandInfo commandInfo)86            : this(commandInfo, false)87        {88        }89 90        internal Command(CommandInfo commandInfo, bool isScript)91        {92            IsEndOfStatement = false;93            CommandInfo = commandInfo;94            CommandText = CommandInfo.Name;95            IsScript = isScript;96        }97 98        /// <summary>99        /// Copy constructor for clone operations.100        /// </summary>101        /// <param name="command">The source <see cref="Command"/> instance.</param>102        internal Command(Command command)103        {104            IsScript = command.IsScript;105            _useLocalScope = command._useLocalScope;106            CommandText = command.CommandText;107            MergeInstructions = command.MergeInstructions;108            MergeMyResult = command.MergeMyResult;109            MergeToResult = command.MergeToResult;110            _mergeUnclaimedPreviousCommandResults = command._mergeUnclaimedPreviousCommandResults;111            IsEndOfStatement = command.IsEndOfStatement;112            CommandInfo = command.CommandInfo;113 114            foreach (CommandParameter param in command.Parameters)115            {116                Parameters.Add(new CommandParameter(param.Name, param.Value));117            }118        }119 120        #endregion constructors121 122        #region Properties123 124        /// <summary>125        /// Gets the set of parameters for this command.126        /// </summary>127        /// <remarks>128        /// This property is used to add positional or named parameters to the command.129        /// </remarks>130        public CommandParameterCollection Parameters { get; } = new CommandParameterCollection();131 132        /// <summary>133        /// Access the command string.134        /// </summary>135        /// <value>The command name, if <see cref="Command.IsScript"/> is false; otherwise; the script contents</value>136        public string CommandText { get; } = string.Empty;137 138        /// <summary>139        /// Access the commandInfo.140        /// </summary>141        /// <value>The command info object</value>142        internal CommandInfo CommandInfo { get; }143 144        /// <summary>145        /// Access the value indicating if this <see cref="Command"/> represents a script.146        /// </summary>147        public bool IsScript { get; }148 149        /// <summary>150        /// Access the value indicating if LocalScope is to be used for running151        /// this script command.152        /// </summary>153        /// <value>True if this command is a script and localScope is154        /// used for executing the script</value>155        /// <remarks>This value is always false for non-script commands</remarks>156        public bool UseLocalScope157        {158            get { return _useLocalScope ?? false; }159        }160 161        /// <summary>162        /// Gets or sets the command origin for this command. A command origin163        /// of 'Runspace' (the default) applies Runspace restrictions to this command.164        /// A command origin of 'Internal' does not apply runspace restrictions.165        /// </summary>166        public CommandOrigin CommandOrigin { get; set; } = CommandOrigin.Runspace;167 168        /// <summary>169        /// Access the actual value indicating if LocalScope is to be used for running170        /// this script command.  Needed for serialization in remoting.171        /// </summary>172        internal bool? UseLocalScopeNullable173        {174            get { return _useLocalScope; }175        }176 177        /// <summary>178        /// Gets or sets DollarUnderbar ($_) value to be used with script command.179        /// This is used by foreach-object -parallel where each piped input ($_) is associated180        /// with a parallel running script block.181        /// </summary>182        internal object DollarUnderbar { get; set; } = AutomationNull.Value;183 184        /// <summary>185        /// Checks if the current command marks the end of a statement (see PowerShell.AddStatement())186        /// </summary>187        public bool IsEndOfStatement { get; internal set; }188 189        #endregion Properties190 191        #region Methods192 193        /// <summary>194        /// Creates a new <see cref="Command"/> that is a copy of the current instance.195        /// </summary>196        /// <returns>A new <see cref="Command"/> that is a copy of this instance.</returns>197        internal Command Clone()198        {199            return new Command(this);200        }201 202        /// <summary>203        /// For diagnostic purposes.204        /// </summary>205        /// <returns></returns>206        public override string ToString()207        {208            return CommandText;209        }210 211        #endregion Methods212 213        #region Merge214 215        private PipelineResultTypes _mergeUnclaimedPreviousCommandResults =216            PipelineResultTypes.None;217        /// <summary>218        /// Sets this command as the mergepoint for previous unclaimed219        /// commands' results.220        /// </summary>221        /// <value></value>222        /// <remarks>223        /// Currently only supported operation is to merge224        /// Output and Error.225        /// </remarks>226        /// <exception cref="NotSupportedException">227        /// Currently only supported operation is to merge Output and Error.228        /// Attempt to set the property to something other than229        /// PipelineResultTypes.Error | PipelineResultTypes.Output results230        /// in this exception.231        /// </exception>232        public PipelineResultTypes MergeUnclaimedPreviousCommandResults233        {234            get235            {236                return _mergeUnclaimedPreviousCommandResults;237            }238 239            set240            {241                if (value == PipelineResultTypes.None)242                {243                    _mergeUnclaimedPreviousCommandResults = value;244                    return;245                }246 247                if (value != (PipelineResultTypes.Error | PipelineResultTypes.Output))248                {249                    throw PSTraceSource.NewNotSupportedException();250                }251 252                _mergeUnclaimedPreviousCommandResults = value;253            }254        }255 256        //257        // These properties are kept for backwards compatibility for V2258        // over the wire, which allows merging only for Error stream.259        //260 261        internal PipelineResultTypes MergeMyResult { get; private set; } = PipelineResultTypes.None;262 263        internal PipelineResultTypes MergeToResult { get; private set; } = PipelineResultTypes.None;264 265        //266        // For V3 we allow merging from all streams except Output.267        //268        internal enum MergeType269        {270            Error = 0,271            Warning = 1,272            Verbose = 2,273            Debug = 3,274            Information = 4275        }276 277        internal const int MaxMergeType = (int)(MergeType.Information + 1);278 279        /// <summary>280        /// Internal accessor for _mergeInstructions. It is used by serialization281        /// code.282        /// </summary>283        internal PipelineResultTypes[] MergeInstructions { get; set; } = new PipelineResultTypes[MaxMergeType];284 285        /// <summary>286        /// Merges this commands results.287        /// </summary>288        /// <param name="myResult">289        /// Pipeline stream to be redirected.290        /// </param>291        /// <param name="toResult">292        /// Pipeline stream in to which myResult is merged293        /// </param>294        /// <exception cref="ArgumentException">295        /// myResult parameter is not PipelineResultTypes.Error or296        /// toResult parameter is not PipelineResultTypes.Output297        /// </exception>298        /// <remarks>299        /// Currently only operation supported is to merge error of command to output of300        /// command.301        /// </remarks>302        public void MergeMyResults(PipelineResultTypes myResult, PipelineResultTypes toResult)303        {304            if (myResult == PipelineResultTypes.None && toResult == PipelineResultTypes.None)305            {306                // For V2 backwards compatibility.307                MergeMyResult = myResult;308                MergeToResult = toResult;309 310                for (int i = 0; i < MaxMergeType; ++i)311                {312                    MergeInstructions[i] = PipelineResultTypes.None;313                }314 315                return;316            }317 318            // Validate parameters.319            if (myResult == PipelineResultTypes.None || myResult == PipelineResultTypes.Output)320            {321                throw PSTraceSource.NewArgumentException(nameof(myResult), RunspaceStrings.InvalidMyResultError);322            }323 324            if (myResult == PipelineResultTypes.Error && toResult != PipelineResultTypes.Output)325            {326                throw PSTraceSource.NewArgumentException(nameof(toResult), RunspaceStrings.InvalidValueToResultError);327            }328 329            if (toResult != PipelineResultTypes.Output && toResult != PipelineResultTypes.Null)330            {331                throw PSTraceSource.NewArgumentException(nameof(toResult), RunspaceStrings.InvalidValueToResult);332            }333 334            // For V2 backwards compatibility.335            if (myResult == PipelineResultTypes.Error)336            {337                MergeMyResult = myResult;338                MergeToResult = toResult;339            }340 341            // Set internal merge instructions.342            if (myResult == PipelineResultTypes.Error || myResult == PipelineResultTypes.All)343            {344                MergeInstructions[(int)MergeType.Error] = toResult;345            }346 347            if (myResult == PipelineResultTypes.Warning || myResult == PipelineResultTypes.All)348            {349                MergeInstructions[(int)MergeType.Warning] = toResult;350            }351 352            if (myResult == PipelineResultTypes.Verbose || myResult == PipelineResultTypes.All)353            {354                MergeInstructions[(int)MergeType.Verbose] = toResult;355            }356 357            if (myResult == PipelineResultTypes.Debug || myResult == PipelineResultTypes.All)358            {359                MergeInstructions[(int)MergeType.Debug] = toResult;360            }361 362            if (myResult == PipelineResultTypes.Information || myResult == PipelineResultTypes.All)363            {364                MergeInstructions[(int)MergeType.Information] = toResult;365            }366        }367 368        /// <summary>369        /// Set the merge settings on commandProcessor.370        /// </summary>371        /// <param name="commandProcessor"></param>372        private373        void374        SetMergeSettingsOnCommandProcessor(CommandProcessorBase commandProcessor)375        {376            Dbg.Assert(commandProcessor != null, "caller should validate the parameter");377 378            MshCommandRuntime mcr = commandProcessor.Command.commandRuntime as MshCommandRuntime;379 380            if (_mergeUnclaimedPreviousCommandResults != PipelineResultTypes.None)381            {382                // Currently only merging previous unclaimed error and output is supported.383                if (mcr != null)384                {385                    mcr.MergeUnclaimedPreviousErrorResults = true;386                }387            }388 389            // Error merge.390            if (MergeInstructions[(int)MergeType.Error] == PipelineResultTypes.Output)391            {392                // Currently only merging error with output is supported.393                mcr.ErrorMergeTo = MshCommandRuntime.MergeDataStream.Output;394            }395 396            // Warning merge.397            PipelineResultTypes toType = MergeInstructions[(int)MergeType.Warning];398            if (toType != PipelineResultTypes.None)399            {400                mcr.WarningOutputPipe = GetRedirectionPipe(toType, mcr);401            }402 403            // Verbose merge.404            toType = MergeInstructions[(int)MergeType.Verbose];405            if (toType != PipelineResultTypes.None)406            {407                mcr.VerboseOutputPipe = GetRedirectionPipe(toType, mcr);408            }409 410            // Debug merge.411            toType = MergeInstructions[(int)MergeType.Debug];412            if (toType != PipelineResultTypes.None)413            {414                mcr.DebugOutputPipe = GetRedirectionPipe(toType, mcr);415            }416 417            // Information merge.418            toType = MergeInstructions[(int)MergeType.Information];419            if (toType != PipelineResultTypes.None)420            {421                mcr.InformationOutputPipe = GetRedirectionPipe(toType, mcr);422            }423        }424 425        private static Pipe GetRedirectionPipe(426            PipelineResultTypes toType,427            MshCommandRuntime mcr)428        {429            if (toType == PipelineResultTypes.Output)430            {431                return mcr.OutputPipe;432            }433 434            Pipe pipe = new Pipe();435            pipe.NullPipe = true;436            return pipe;437        }438 439        #endregion Merge440 441        /// <summary>442        /// Create a CommandProcessorBase for this Command.443        /// </summary>444        /// <param name="executionContext"></param>445        /// <param name="addToHistory"></param>446        /// <param name="origin"></param>447        /// <returns></returns>448        internal449        CommandProcessorBase450        CreateCommandProcessor451        (452            ExecutionContext executionContext,453            bool addToHistory,454            CommandOrigin origin455        )456        {457            Dbg.Assert(executionContext != null, "Caller should verify the parameters");458 459            CommandProcessorBase commandProcessorBase;460 461            if (IsScript)462            {463                if ((executionContext.LanguageMode == PSLanguageMode.NoLanguage) &&464                    (origin == Automation.CommandOrigin.Runspace))465                {466                    throw InterpreterError.NewInterpreterException(CommandText, typeof(ParseException),467                        null, "ScriptsNotAllowed", ParserStrings.ScriptsNotAllowed);468                }469 470                ScriptBlock scriptBlock = executionContext.Engine.ParseScriptBlock(CommandText, addToHistory);471                if (origin == Automation.CommandOrigin.Internal)472                {473                    scriptBlock.LanguageMode = PSLanguageMode.FullLanguage;474                }475 476                // If running in restricted language mode, verify that the parse tree represents on legitimate477                // constructions...478                switch (scriptBlock.LanguageMode)479                {480                    case PSLanguageMode.RestrictedLanguage:481                        scriptBlock.CheckRestrictedLanguage(null, null, false);482                        break;483                    case PSLanguageMode.FullLanguage:484                        // Interactive script commands are permitted in this mode.485                        break;486                    case PSLanguageMode.ConstrainedLanguage:487                        // Constrained Language is checked at runtime.488                        break;489                    default:490                        // This should never happen...491                        Diagnostics.Assert(false, "Invalid language mode was set when building a ScriptCommandProcessor");492                        throw new InvalidOperationException("Invalid language mode was set when building a ScriptCommandProcessor");493                }494 495                if (scriptBlock.UsesCmdletBinding)496                {497                    FunctionInfo functionInfo = new FunctionInfo(string.Empty, scriptBlock, executionContext);498                    commandProcessorBase = new CommandProcessor(functionInfo, executionContext,499                                                                _useLocalScope ?? false, fromScriptFile: false, sessionState: executionContext.EngineSessionState);500                }501                else502                {503                    commandProcessorBase = new DlrScriptCommandProcessor(scriptBlock,504                                                                         executionContext, _useLocalScope ?? false,505                                                                         origin,506                                                                         executionContext.EngineSessionState,507                                                                         DollarUnderbar);508                }509            }510            else511            {512                // RestrictedLanguage / NoLanguage do not support dot-sourcing when CommandOrigin is Runspace513                if ((_useLocalScope.HasValue) && (!_useLocalScope.Value))514                {515                    switch (executionContext.LanguageMode)516                    {517                        case PSLanguageMode.RestrictedLanguage:518                        case PSLanguageMode.NoLanguage:519                            string message = StringUtil.Format(RunspaceStrings.UseLocalScopeNotAllowed,520                                "UseLocalScope",521                                nameof(PSLanguageMode.RestrictedLanguage),522                                nameof(PSLanguageMode.NoLanguage));523                            throw new RuntimeException(message);524                        case PSLanguageMode.FullLanguage:525                            // Interactive script commands are permitted in this mode...526                            break;527                    }528                }529 530                commandProcessorBase = executionContext.CommandDiscovery.LookupCommandProcessor(CommandText, origin, _useLocalScope);531            }532 533            CommandParameterCollection parameters = Parameters;534 535            if (parameters != null)536            {537                bool isNativeCommand = commandProcessorBase is NativeCommandProcessor;538                foreach (CommandParameter publicParameter in parameters)539                {540                    CommandParameterInternal internalParameter = CommandParameter.ToCommandParameterInternal(publicParameter, isNativeCommand);541                    commandProcessorBase.AddParameter(internalParameter);542                }543            }544 545            string helpTarget;546            HelpCategory helpCategory;547            if (commandProcessorBase.IsHelpRequested(out helpTarget, out helpCategory))548            {549                commandProcessorBase = CommandProcessorBase.CreateGetHelpCommandProcessor(550                    executionContext,551                    helpTarget,552                    helpCategory);553            }554 555            // Set the merge settings556            SetMergeSettingsOnCommandProcessor(commandProcessorBase);557 558            return commandProcessorBase;559        }560 561        #region Private fields562 563        /// <summary>564        /// This is used for script commands (i.e. _isScript is true). If565        /// _useLocalScope is true, script is run in LocalScope.  If566        /// null, it was unspecified and a suitable default is used (true567        /// for non-script, false for script).  Note that the public568        /// property is bool, not bool? (from V1), so it should probably569        /// be deprecated, at least for internal use.570        /// </summary>571        private readonly bool? _useLocalScope;572 573        #endregion Private fields574 575        #region Serialization / deserialization for remoting576 577        /// <summary>578        /// Creates a Command object from a PSObject property bag.579        /// PSObject has to be in the format returned by ToPSObjectForRemoting method.580        /// </summary>581        /// <param name="commandAsPSObject">PSObject to rehydrate.</param>582        /// <returns>583        /// Command rehydrated from a PSObject property bag584        /// </returns>585        /// <exception cref="ArgumentNullException">586        /// Thrown if the PSObject is null.587        /// </exception>588        /// <exception cref="System.Management.Automation.Remoting.PSRemotingDataStructureException">589        /// Thrown when the PSObject is not in the expected format590        /// </exception>591        internal static Command FromPSObjectForRemoting(PSObject commandAsPSObject)592        {593            if (commandAsPSObject == null)594            {595                throw PSTraceSource.NewArgumentNullException(nameof(commandAsPSObject));596            }597 598            string commandText = RemotingDecoder.GetPropertyValue<string>(commandAsPSObject, RemoteDataNameStrings.CommandText);599            bool isScript = RemotingDecoder.GetPropertyValue<bool>(commandAsPSObject, RemoteDataNameStrings.IsScript);600            bool? useLocalScopeNullable = RemotingDecoder.GetPropertyValue<bool?>(commandAsPSObject, RemoteDataNameStrings.UseLocalScopeNullable);601            Command command = new Command(commandText, isScript, useLocalScopeNullable);602 603            // For V2 backwards compatibility.604            PipelineResultTypes mergeMyResult = RemotingDecoder.GetPropertyValue<PipelineResultTypes>(commandAsPSObject, RemoteDataNameStrings.MergeMyResult);605            PipelineResultTypes mergeToResult = RemotingDecoder.GetPropertyValue<PipelineResultTypes>(commandAsPSObject, RemoteDataNameStrings.MergeToResult);606            command.MergeMyResults(mergeMyResult, mergeToResult);607 608            command.MergeUnclaimedPreviousCommandResults = RemotingDecoder.GetPropertyValue<PipelineResultTypes>(commandAsPSObject, RemoteDataNameStrings.MergeUnclaimedPreviousCommandResults);609 610            // V3 merge instructions will not be returned by V2 server and this is expected.611            if (commandAsPSObject.Properties[RemoteDataNameStrings.MergeError] != null)612            {613                command.MergeInstructions[(int)MergeType.Error] = RemotingDecoder.GetPropertyValue<PipelineResultTypes>(commandAsPSObject, RemoteDataNameStrings.MergeError);614            }615 616            if (commandAsPSObject.Properties[RemoteDataNameStrings.MergeWarning] != null)617            {618                command.MergeInstructions[(int)MergeType.Warning] = RemotingDecoder.GetPropertyValue<PipelineResultTypes>(commandAsPSObject, RemoteDataNameStrings.MergeWarning);619            }620 621            if (commandAsPSObject.Properties[RemoteDataNameStrings.MergeVerbose] != null)622            {623                command.MergeInstructions[(int)MergeType.Verbose] = RemotingDecoder.GetPropertyValue<PipelineResultTypes>(commandAsPSObject, RemoteDataNameStrings.MergeVerbose);624            }625 626            if (commandAsPSObject.Properties[RemoteDataNameStrings.MergeDebug] != null)627            {628                command.MergeInstructions[(int)MergeType.Debug] = RemotingDecoder.GetPropertyValue<PipelineResultTypes>(commandAsPSObject, RemoteDataNameStrings.MergeDebug);629            }630 631            if (commandAsPSObject.Properties[RemoteDataNameStrings.MergeInformation] != null)632            {633                command.MergeInstructions[(int)MergeType.Information] = RemotingDecoder.GetPropertyValue<PipelineResultTypes>(commandAsPSObject, RemoteDataNameStrings.MergeInformation);634            }635 636            foreach (PSObject parameterAsPSObject in RemotingDecoder.EnumerateListProperty<PSObject>(commandAsPSObject, RemoteDataNameStrings.Parameters))637            {638                command.Parameters.Add(CommandParameter.FromPSObjectForRemoting(parameterAsPSObject));639            }640 641            return command;642        }643 644        /// <summary>645        /// Returns this object as a PSObject property bag646        /// that can be used in a remoting protocol data object.647        /// </summary>648        /// <param name="psRPVersion">PowerShell remoting protocol version.</param>649        /// <returns>This object as a PSObject property bag.</returns>650        internal PSObject ToPSObjectForRemoting(Version psRPVersion)651        {652            PSObject commandAsPSObject = RemotingEncoder.CreateEmptyPSObject();653 654            commandAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.CommandText, this.CommandText));655            commandAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.IsScript, this.IsScript));656            commandAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.UseLocalScopeNullable, this.UseLocalScopeNullable));657 658            // For V2 backwards compatibility.659            commandAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.MergeMyResult, this.MergeMyResult));660            commandAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.MergeToResult, this.MergeToResult));661 662            commandAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.MergeUnclaimedPreviousCommandResults, this.MergeUnclaimedPreviousCommandResults));663 664            if (psRPVersion != null &&665                psRPVersion >= RemotingConstants.ProtocolVersion_2_3)666            {667                // V5 merge instructions668                commandAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.MergeError, MergeInstructions[(int)MergeType.Error]));669                commandAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.MergeWarning, MergeInstructions[(int)MergeType.Warning]));670                commandAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.MergeVerbose, MergeInstructions[(int)MergeType.Verbose]));671                commandAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.MergeDebug, MergeInstructions[(int)MergeType.Debug]));672                commandAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.MergeInformation, MergeInstructions[(int)MergeType.Information]));673            }674            else if (psRPVersion != null &&675                psRPVersion >= RemotingConstants.ProtocolVersion_2_2)676            {677                // V3 merge instructions.678                commandAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.MergeError, MergeInstructions[(int)MergeType.Error]));679                commandAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.MergeWarning, MergeInstructions[(int)MergeType.Warning]));680                commandAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.MergeVerbose, MergeInstructions[(int)MergeType.Verbose]));681                commandAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.MergeDebug, MergeInstructions[(int)MergeType.Debug]));682 683                // If they've explicitly redirected the Information stream, generate an error. Don't684                // generate an error if they've done "*", as that makes any new stream a breaking change.685                if ((MergeInstructions[(int)MergeType.Information] == PipelineResultTypes.Output) &&686                    (MergeInstructions.Length != MaxMergeType))687                {688                    throw new RuntimeException(689                        StringUtil.Format(RunspaceStrings.InformationRedirectionNotSupported));690                }691            }692            else693            {694                // If they've explicitly redirected an unsupported stream, generate an error. Don't695                // generate an error if they've done "*", as that makes any new stream a breaking change.696                if (MergeInstructions.Length != MaxMergeType)697                {698                    if (MergeInstructions[(int)MergeType.Warning] == PipelineResultTypes.Output)699                    {700                        throw new RuntimeException(701                            StringUtil.Format(RunspaceStrings.WarningRedirectionNotSupported));702                    }703 704                    if (MergeInstructions[(int)MergeType.Verbose] == PipelineResultTypes.Output)705                    {706                        throw new RuntimeException(707                            StringUtil.Format(RunspaceStrings.VerboseRedirectionNotSupported));708                    }709 710                    if (MergeInstructions[(int)MergeType.Debug] == PipelineResultTypes.Output)711                    {712                        throw new RuntimeException(713                            StringUtil.Format(RunspaceStrings.DebugRedirectionNotSupported));714                    }715 716                    if (MergeInstructions[(int)MergeType.Information] == PipelineResultTypes.Output)717                    {718                        throw new RuntimeException(719                            StringUtil.Format(RunspaceStrings.InformationRedirectionNotSupported));720                    }721                }722            }723 724            List<PSObject> parametersAsListOfPSObjects = new List<PSObject>(this.Parameters.Count);725            foreach (CommandParameter parameter in this.Parameters)726            {727                parametersAsListOfPSObjects.Add(parameter.ToPSObjectForRemoting());728            }729 730            commandAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.Parameters, parametersAsListOfPSObjects));731 732            return commandAsPSObject;733        }734 735        #endregion736 737        #region Win Blue Extensions738 739#if !CORECLR // PSMI Not Supported On CSS740        internal CimInstance ToCimInstance()741        {742            CimInstance c = InternalMISerializer.CreateCimInstance("PS_Command");743            CimProperty commandTextProperty = InternalMISerializer.CreateCimProperty("CommandText",744                                                                                     this.CommandText,745                                                                                     Microsoft.Management.Infrastructure.CimType.String);746            c.CimInstanceProperties.Add(commandTextProperty);747            CimProperty isScriptProperty = InternalMISerializer.CreateCimProperty("IsScript",748                                                                                  this.IsScript,749                                                                                  Microsoft.Management.Infrastructure.CimType.Boolean);750            c.CimInstanceProperties.Add(isScriptProperty);751 752            if (this.Parameters != null && this.Parameters.Count > 0)753            {754                List<CimInstance> parameterInstances = new List<CimInstance>();755                foreach (var p in this.Parameters)756                {757                    parameterInstances.Add(p.ToCimInstance());758                }759 760                if (parameterInstances.Count > 0)761                {762                    CimProperty parametersProperty = InternalMISerializer.CreateCimProperty("Parameters",763                                                                                            parameterInstances.ToArray(),764                                                                                            Microsoft.Management.Infrastructure.CimType.ReferenceArray);765                    c.CimInstanceProperties.Add(parametersProperty);766                }767            }768 769            return c;770        }771#endif772 773        #endregion Win Blue Extensions774    }775 776    /// <summary>777    /// Enum defining the types of streams coming out of a pipeline.778    /// </summary>779    [Flags]780    public enum PipelineResultTypes781    {782        /// <summary>783        /// Default streaming behavior.784        /// </summary>785        None,786 787        /// <summary>788        /// Success output.789        /// </summary>790        Output,791 792        /// <summary>793        /// Error output.794        /// </summary>795        Error,796 797        /// <summary>798        /// Warning information stream.799        /// </summary>800        Warning,801 802        /// <summary>803        /// Verbose information stream.804        /// </summary>805        Verbose,806 807        /// <summary>808        /// Debug information stream.809        /// </summary>810        Debug,811 812        /// <summary>813        /// Information information stream.814        /// </summary>815        Information,816 817        /// <summary>818        /// All streams.819        /// </summary>820        All,821 822        /// <summary>823        /// Redirect to nothing.824        /// </summary>825        Null826    }827 828    /// <summary>829    /// Defines a collection of Commands. This collection is used by <see cref="Pipeline"/> to define830    /// elements of pipeline.831    /// </summary>832    public sealed class CommandCollection : Collection<Command>833    {834        /// <summary>835        /// Make the default constructor internal.836        /// </summary>837        internal CommandCollection()838        {839        }840 841        /// <summary>842        /// Adds a new command for given string.843        /// </summary>844        /// <exception cref="System.ArgumentNullException">845        /// command is null.846        /// </exception>847        public void Add(string command)848        {849            if (string.Equals(command, "out-default", StringComparison.OrdinalIgnoreCase))850            {851                this.Add(command, true);852            }853            else854            {855                this.Add(new Command(command));856            }857        }858 859        internal void Add(string command, bool mergeUnclaimedPreviousCommandError)860        {861            this.Add(new Command(command, false, false, mergeUnclaimedPreviousCommandError));862        }863 864        /// <summary>865        /// Adds a new script command.866        /// </summary>867        /// <param name="scriptContents">Script contents.</param>868        /// <exception cref="System.ArgumentNullException">869        /// scriptContents is null.870        /// </exception>871        public void AddScript(string scriptContents)872        {873            this.Add(new Command(scriptContents, true));874        }875 876        /// <summary>877        /// Adds a new scrip command for given script.878        /// </summary>879        /// <param name="scriptContents">Script contents.</param>880        /// <param name="useLocalScope">If true local scope is used to run the script command.</param>881        /// <exception cref="System.ArgumentNullException">882        /// scriptContents is null.883        /// </exception>884        public void AddScript(string scriptContents, bool useLocalScope)885        {886            this.Add(new Command(scriptContents, true, useLocalScope));887        }888 889        /// <summary>890        /// Gets the string representation of the command collection to be used for history.891        /// </summary>892        /// <returns>893        /// string representing the command(s)894        /// </returns>895        internal string GetCommandStringForHistory()896        {897            Diagnostics.Assert(this.Count != 0, "this is called when there is at least one element in the collection");898            Command firstCommand = this[0];899            return firstCommand.CommandText;900        }901    }902}903