MegaBites-AI/Windows-powershell
0372
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 