Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
InitialSessionState.cs5683 linesDownload Raw Back to engine
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections;5using System.Collections.Concurrent;6using System.Collections.Generic;7using System.Collections.ObjectModel;8using System.Diagnostics.CodeAnalysis;9using System.Diagnostics.Tracing;10using System.IO;11using System.Linq;12using System.Management.Automation.Host;13using System.Management.Automation.Internal;14using System.Management.Automation.Language;15using System.Management.Automation.Provider;16using System.Management.Automation.Security;17using System.Reflection;18using System.Runtime.CompilerServices;19using System.Text;20using System.Threading;21using System.Threading.Tasks;22 23using Microsoft.PowerShell.Commands;24 25using Debug = System.Management.Automation.Diagnostics;26 27namespace System.Management.Automation.Runspaces28{29    internal static class EarlyStartup30    {31        internal static void Init()32        {33            // Code added here should:34            //   * run every time we start PowerSHell35            //   * have high CPU cost36            //   * be ordered from most expensive to least expensive, or at least needed earliest37            //   * this method should return quickly, so all work should be run in one or more tasks.38            //   * code called from here should correctly handle being called twice, in case initialization39            //     is needed in the main code path before the task completes.40            //41            // Code added here should not:42            //   * count on running - not all hosts will call this method43            //   * have high disk cost44 45            // We shouldn't create too many tasks.46#if !UNIX47            // Amsi initialize can be a little slow.48            Task.Run(() => AmsiUtils.WinScanContent(content: string.Empty, sourceMetadata: string.Empty, warmUp: true));49#endif50            // Initialize the types 'Compiler', 'CachedReflectionInfo', and 'ExpressionCache'.51            // Their type initializers do a lot of reflection operations.52            // We will access 'Compiler' members when creating the first session state.53            Task.Run(() => _ = Compiler.DottedLocalsTupleType);54 55            // One other task for other stuff that's faster, but still a little slow.56            Task.Run(() =>57            {58                // Loading the resources for System.Management.Automation can be expensive,59                // so force that to happen early on a background thread.60                _ = RunspaceInit.OutputEncodingDescription;61 62                // This will init some tables and could load some assemblies.63                // We will access 'LanguagePrimitives' when binding built-in variables for the Runspace.64                LanguagePrimitives.GetEnumerator(null);65 66                // This will init some tables and could load some assemblies.67                // We will access 'TypeAccelerators' when auto-loading the PSReadLine module, which happens last.68                _ = TypeAccelerators.builtinTypeAccelerators;69            });70        }71    }72 73    /// <summary>74    /// Baseclass for defining elements that can be added75    /// to an InitialSessionState object.76    /// </summary>77    public abstract class InitialSessionStateEntry78    {79        /// <summary>80        /// The ctor so that each derived class has a name.81        /// </summary>82        /// <param name="name"></param>83        protected InitialSessionStateEntry(string name)84        {85            Name = name;86        }87 88        /// <summary>89        /// The name of this entry.90        /// </summary>91        public string Name { get; internal set; }92 93        /// <summary>94        /// The SnapIn to load from initially.95        /// </summary>96        public PSSnapInInfo PSSnapIn { get; private set; }97 98        internal void SetPSSnapIn(PSSnapInInfo psSnapIn)99        {100            PSSnapIn = psSnapIn;101        }102 103        /// <summary>104        /// The SnapIn to load from initially.105        /// </summary>106        public PSModuleInfo Module { get; private set; }107 108        internal void SetModule(PSModuleInfo module)109        {110            Module = module;111        }112 113        /// <summary>114        /// Shallow-clone this object.115        /// </summary>116        /// <returns>The cloned object...</returns>117        public abstract InitialSessionStateEntry Clone();118    }119 120    /// <summary>121    /// Class to constrain session state entries.122    /// </summary>123    public abstract class ConstrainedSessionStateEntry : InitialSessionStateEntry124    {125        /// <summary>126        /// </summary>127        /// <param name="name"></param>128        /// <param name="visibility"></param>129        protected ConstrainedSessionStateEntry(string name, SessionStateEntryVisibility visibility)130            : base(name)131        {132            Visibility = visibility;133        }134 135        /// <summary>136        /// </summary>137        public SessionStateEntryVisibility Visibility { get; set; }138    }139 140    /// <summary>141    /// Command class so that all the commands can derive off this one.142    /// Adds the flexibility of adding additional derived class,143    /// such as ProxyCommand for Exchange.144    /// Derived classes - Alias, Application, Cmdlet, Function, Script.145    /// </summary>146    public abstract class SessionStateCommandEntry : ConstrainedSessionStateEntry147    {148        /// <summary>149        /// Base constructor for all SessionState commands.150        /// </summary>151        /// <param name="name"></param>152        protected SessionStateCommandEntry(string name)153            : base(name, SessionStateEntryVisibility.Public)154        {155        }156 157        /// <summary>158        /// </summary>159        /// <param name="name"></param>160        /// <param name="visibility"></param>161        protected internal SessionStateCommandEntry(string name, SessionStateEntryVisibility visibility)162            : base(name, visibility)163        {164        }165 166        /// <summary>167        /// Returns the type of the command using an enum168        /// instead of requiring a full reflection type check.169        /// </summary>170        public CommandTypes CommandType { get; internal set; }171 172        /// <summary>173        /// Is internal so it can be set by the engine code...174        /// This is used to specify whether this command was imported or not175        /// If noClobber is specified during Import-Module, it is set to false.176        /// </summary>177        internal bool _isImported = true;178    }179 180    /// <summary>181    /// Type file configuration entry...182    /// </summary>183    public sealed class SessionStateTypeEntry : InitialSessionStateEntry184    {185        /// <summary>186        /// Loads all entries from the types file.187        /// </summary>188        /// <param name="fileName"></param>189        public SessionStateTypeEntry(string fileName)190            : base(fileName)191        {192            if (string.IsNullOrWhiteSpace(fileName))193            {194                throw PSTraceSource.NewArgumentException(nameof(fileName));195            }196 197            FileName = fileName.Trim();198        }199 200        /// <summary>201        /// Loads all the types specified in the typeTable.202        /// </summary>203        /// <param name="typeTable"></param>204        public SessionStateTypeEntry(TypeTable typeTable)205            : base("*")206        {207            if (typeTable == null)208            {209                throw PSTraceSource.NewArgumentNullException(nameof(typeTable));210            }211 212            TypeTable = typeTable;213        }214 215        /// <summary>216        /// Loads all entries from the typeData.217        /// </summary>218        /// <param name="typeData"></param>219        /// <param name="isRemove"></param>220        public SessionStateTypeEntry(TypeData typeData, bool isRemove)221            : base("*")222        {223            if (typeData == null)224            {225                throw PSTraceSource.NewArgumentNullException(nameof(typeData));226            }227 228            TypeData = typeData;229            IsRemove = isRemove;230        }231 232        /// <summary>233        /// Shallow-clone this object.234        /// </summary>235        /// <returns>The cloned object.</returns>236        public override InitialSessionStateEntry Clone()237        {238            SessionStateTypeEntry entry;239            if (FileName != null)240            {241                entry = new SessionStateTypeEntry(FileName);242            }243            else if (TypeTable != null)244            {245                entry = new SessionStateTypeEntry(TypeTable);246            }247            else248            {249                entry = new SessionStateTypeEntry(TypeData, IsRemove);250            }251 252            entry.SetPSSnapIn(this.PSSnapIn);253            entry.SetModule(this.Module);254            return entry;255        }256 257        /// <summary>258        /// The pathname of the types.ps1xml file. This can be null if259        /// TypeTable constructor or TypeData constructor is used.260        /// </summary>261        public string FileName { get; }262 263        /// <summary>264        /// The TypeTable specified with constructor. This can be null if265        /// FileName constructor or TypeData constructor is used.266        /// </summary>267        public TypeTable TypeTable { get; }268 269        /// <summary>270        /// The TypeData we want to update with. This can be null if271        /// FileName constructor or TypeTable constructor is used.272        /// </summary>273        public TypeData TypeData { get; }274 275        /// <summary>276        /// The operation will be done on the typedata. This is only277        /// meaningful when the TypeData constructor is used.278        /// </summary>279        public bool IsRemove { get; }280 281        // So that we can specify the type information on the fly,282        // without using Types.ps1xml file283        // public SessionStateTypeEntry(string name, xmlreader definition);284        // public string Definition { get; }285    }286 287    /// <summary>288    /// Format file configuration entry...289    /// </summary>290    public sealed class SessionStateFormatEntry : InitialSessionStateEntry291    {292        /// <summary>293        /// Loads the entire formats file.294        /// </summary>295        /// <param name="fileName"></param>296        public SessionStateFormatEntry(string fileName)297            : base("*")298        {299            if (string.IsNullOrWhiteSpace(fileName))300            {301                throw PSTraceSource.NewArgumentException(nameof(fileName));302            }303 304            FileName = fileName.Trim();305        }306 307        /// <summary>308        /// Loads all the format data specified in the formatTable.309        /// </summary>310        /// <param name="formattable"></param>311        public SessionStateFormatEntry(FormatTable formattable)312            : base("*")313        {314            if (formattable == null)315            {316                throw PSTraceSource.NewArgumentNullException(nameof(formattable));317            }318 319            Formattable = formattable;320        }321 322        /// <summary>323        /// Loads all the format data specified in the typeDefinition.324        /// </summary>325        /// <param name="typeDefinition"></param>326        public SessionStateFormatEntry(ExtendedTypeDefinition typeDefinition)327            : base("*")328        {329            if (typeDefinition == null)330            {331                throw PSTraceSource.NewArgumentNullException(nameof(typeDefinition));332            }333 334            FormatData = typeDefinition;335        }336 337        /// <summary>338        /// Shallow-clone this object...339        /// </summary>340        /// <returns>The cloned object.</returns>341        public override InitialSessionStateEntry Clone()342        {343            SessionStateFormatEntry entry;344 345            if (FileName != null)346            {347                entry = new SessionStateFormatEntry(FileName);348            }349            else if (Formattable != null)350            {351                entry = new SessionStateFormatEntry(Formattable);352            }353            else354            {355                entry = new SessionStateFormatEntry(FormatData);356            }357 358            entry.SetPSSnapIn(this.PSSnapIn);359            entry.SetModule(this.Module);360            return entry;361        }362 363        /// <summary>364        /// The name of the format file referenced by this entry...365        /// </summary>366        public string FileName { get; }367 368        /// <summary>369        /// The FormatTable specified with constructor. This can be null if370        /// FileName constructor is used.371        /// </summary>372        public FormatTable Formattable { get; }373 374        /// <summary>375        /// The FormatData specified with constructor.376        /// This can be null if the FileName or FormatTable constructors are used.377        /// </summary>378        public ExtendedTypeDefinition FormatData { get; }379 380        // So that we can specify the format information on the fly,381        // without using Format.ps1xml file382        // public SessionStateFormatEntry(string name, xmlreader definition);383        // public string Definition { get; }384    }385 386    /// <summary>387    /// An assembly to load for this sessionstate...388    /// </summary>389    public sealed class SessionStateAssemblyEntry : InitialSessionStateEntry390    {391        /// <summary>392        /// Create a named entry for the assembly to load with both the393        /// name and the path to the assembly as a backup.394        /// </summary>395        /// <param name="name">The name of the assembly to load.</param>396        /// <param name="fileName">The path to the assembly to use as an alternative.</param>397        public SessionStateAssemblyEntry(string name, string fileName)398            : base(name)399        {400            FileName = fileName;401        }402 403        /// <summary>404        /// Create a named entry for the assembly to load, specifying405        /// just the name.406        /// </summary>407        /// <param name="name">The name of the assembly to load.</param>408        public SessionStateAssemblyEntry(string name)409            : base(name)410        {411        }412 413        /// <summary>414        /// Shallow-clone this object.415        /// </summary>416        /// <returns>The cloned object.</returns>417        public override InitialSessionStateEntry Clone()418        {419            var entry = new SessionStateAssemblyEntry(Name, FileName);420            entry.SetPSSnapIn(this.PSSnapIn);421            entry.SetModule(this.Module);422            return entry;423        }424 425        /// <summary>426        /// Return the assembly file name...427        /// </summary>428        public string FileName { get; }429    }430 431    /// <summary>432    /// List a cmdlet to add to this session state entry.433    /// </summary>434    public sealed class SessionStateCmdletEntry : SessionStateCommandEntry435    {436        /// <summary>437        /// </summary>438        /// <param name="name"></param>439        /// <param name="implementingType"></param>440        /// <param name="helpFileName"></param>441        public SessionStateCmdletEntry(string name, Type implementingType, string helpFileName)442            : base(name, SessionStateEntryVisibility.Public)443        {444            ImplementingType = implementingType;445            HelpFileName = helpFileName;446            CommandType = CommandTypes.Cmdlet;447        }448 449        /// <summary>450        /// </summary>451        /// <param name="name"></param>452        /// <param name="implementingType"></param>453        /// <param name="helpFileName"></param>454        /// <param name="visibility"></param>455        internal SessionStateCmdletEntry(string name, Type implementingType, string helpFileName, SessionStateEntryVisibility visibility)456            : base(name, visibility)457        {458            ImplementingType = implementingType;459            HelpFileName = helpFileName;460            CommandType = CommandTypes.Cmdlet;461        }462 463        /// <summary>464        /// Shallow-clone this object...465        /// </summary>466        /// <returns></returns>467        public override InitialSessionStateEntry Clone()468        {469            SessionStateCmdletEntry entry = new SessionStateCmdletEntry(Name, ImplementingType, HelpFileName, Visibility);470            entry.SetPSSnapIn(this.PSSnapIn);471            entry.SetModule(this.Module);472            return entry;473        }474 475        /// <summary>476        /// </summary>477        public Type ImplementingType { get; }478 479        /// <summary>480        /// </summary>481        public string HelpFileName { get; }482    }483 484    /// <summary>485    /// </summary>486    public sealed class SessionStateProviderEntry : ConstrainedSessionStateEntry487    {488        /// <summary>489        /// </summary>490        /// <param name="name"></param>491        /// <param name="implementingType"></param>492        /// <param name="helpFileName"></param>493        public SessionStateProviderEntry(string name, Type implementingType, string helpFileName)494            : base(name, SessionStateEntryVisibility.Public)495        {496            ImplementingType = implementingType;497            HelpFileName = helpFileName;498        }499 500        internal SessionStateProviderEntry(string name, Type implementingType, string helpFileName, SessionStateEntryVisibility visibility)501            : base(name, visibility)502        {503            ImplementingType = implementingType;504            HelpFileName = helpFileName;505        }506 507        /// <summary>508        /// Shallow-clone this object...509        /// </summary>510        /// <returns>The cloned object.</returns>511        public override InitialSessionStateEntry Clone()512        {513            SessionStateProviderEntry entry = new SessionStateProviderEntry(Name, ImplementingType, HelpFileName, this.Visibility);514            entry.SetPSSnapIn(this.PSSnapIn);515            entry.SetModule(this.Module);516            return entry;517        }518 519        /// <summary>520        /// </summary>521        public Type ImplementingType { get; }522 523        /// <summary>524        /// </summary>525        public string HelpFileName { get; }526    }527 528    /// <summary>529    /// </summary>530    public sealed class SessionStateScriptEntry : SessionStateCommandEntry531    {532        /// <summary>533        /// Create a session state command entry instance.534        /// </summary>535        /// <param name="path">The path to the script.</param>536        public SessionStateScriptEntry(string path)537            : base(path, SessionStateEntryVisibility.Public)538        {539            Path = path;540            CommandType = CommandTypes.ExternalScript;541        }542 543        /// <summary>544        /// Create a session state command entry instance with the specified visibility.545        /// </summary>546        /// <param name="path">The path to the script.</param>547        /// <param name="visibility">Visibility of the script.</param>548        internal SessionStateScriptEntry(string path, SessionStateEntryVisibility visibility)549            : base(path, visibility)550        {551            Path = path;552            CommandType = CommandTypes.ExternalScript;553        }554 555        /// <summary>556        /// Shallow-clone this object...557        /// </summary>558        /// <returns>The cloned object.</returns>559        public override InitialSessionStateEntry Clone()560        {561            SessionStateScriptEntry entry = new SessionStateScriptEntry(Path, Visibility);562            entry.SetModule(this.Module);563            return entry;564        }565 566        /// <summary>567        /// </summary>568        public string Path { get; }569    }570 571    /// <summary>572    /// </summary>573    public sealed class SessionStateAliasEntry : SessionStateCommandEntry574    {575        /// <summary>576        /// Define an alias entry to add to the initial session state.577        /// </summary>578        /// <param name="name">The name of the alias entry to add.</param>579        /// <param name="definition">The name of the command it resolves to.</param>580        public SessionStateAliasEntry(string name, string definition)581            : base(name, SessionStateEntryVisibility.Public)582        {583            Definition = definition;584            CommandType = CommandTypes.Alias;585        }586 587        /// <summary>588        /// Define an alias entry to add to the initial session state.589        /// </summary>590        /// <param name="name">The name of the alias entry to add.</param>591        /// <param name="definition">The name of the command it resolves to.</param>592        /// <param name="description">A description of the purpose of the alias.</param>593        public SessionStateAliasEntry(string name, string definition, string description)594            : base(name, SessionStateEntryVisibility.Public)595        {596            Definition = definition;597            CommandType = CommandTypes.Alias;598            Description = description;599        }600 601        /// <summary>602        /// Define an alias entry to add to the initial session state.603        /// </summary>604        /// <param name="name">The name of the alias entry to add.</param>605        /// <param name="definition">The name of the command it resolves to.</param>606        /// <param name="description">A description of the purpose of the alias.</param>607        /// <param name="options">Options defining the scope visibility, readonly and constant.</param>608        public SessionStateAliasEntry(string name, string definition, string description, ScopedItemOptions options)609            : base(name, SessionStateEntryVisibility.Public)610        {611            Definition = definition;612            CommandType = CommandTypes.Alias;613            Description = description;614            Options = options;615        }616 617        /// <summary>618        /// Define an alias entry to add to the initial session state.619        /// </summary>620        /// <param name="name">The name of the alias entry to add.</param>621        /// <param name="definition">The name of the command it resolves to.</param>622        /// <param name="description">A description of the purpose of the alias.</param>623        /// <param name="options">Options defining the scope visibility, readonly and constant.</param>624        /// <param name="visibility"></param>625        internal SessionStateAliasEntry(string name, string definition, string description, ScopedItemOptions options, SessionStateEntryVisibility visibility)626            : base(name, visibility)627        {628            Definition = definition;629            CommandType = CommandTypes.Alias;630            Description = description;631            Options = options;632        }633        /// <summary>634        /// Shallow-clone this object...635        /// </summary>636        /// <returns>The cloned object.</returns>637        public override InitialSessionStateEntry Clone()638        {639            SessionStateAliasEntry entry = new SessionStateAliasEntry(Name, Definition, Description, Options, Visibility);640            entry.SetModule(this.Module);641            return entry;642        }643 644        /// <summary>645        /// The string defining the body of this alias...646        /// </summary>647        public string Definition { get; }648 649        /// <summary>650        /// A string describing this alias...651        /// </summary>652        public string Description { get; } = string.Empty;653 654        /// <summary>655        /// Options controlling scope visibility and setability for this entry.656        /// </summary>657        public ScopedItemOptions Options { get; } = ScopedItemOptions.None;658    }659 660    /// <summary>661    /// </summary>662    public sealed class SessionStateApplicationEntry : SessionStateCommandEntry663    {664        /// <summary>665        /// Used to define a permitted script in this session state. If the path is666        /// "*", then any path is permitted.667        /// </summary>668        /// <param name="path">The full path to the application.</param>669        public SessionStateApplicationEntry(string path)670            : base(path, SessionStateEntryVisibility.Public)671        {672            Path = path;673            CommandType = CommandTypes.Application;674        }675 676        /// <summary>677        /// Used to define a permitted script in this session state. If the path is678        /// "*", then any path is permitted.679        /// </summary>680        /// <param name="path">The full path to the application.</param>681        /// <param name="visibility">Sets the external visibility of the path.</param>682        internal SessionStateApplicationEntry(string path, SessionStateEntryVisibility visibility)683            : base(path, visibility)684        {685            Path = path;686            CommandType = CommandTypes.Application;687        }688 689        /// <summary>690        /// Shallow-clone this object...691        /// </summary>692        /// <returns>The cloned object.</returns>693        public override InitialSessionStateEntry Clone()694        {695            SessionStateApplicationEntry entry = new SessionStateApplicationEntry(Path, Visibility);696            entry.SetModule(this.Module);697            return entry;698        }699 700        /// <summary>701        /// The path to this application...702        /// </summary>703        public string Path { get; }704    }705 706    /// <summary>707    /// </summary>708    public sealed class SessionStateFunctionEntry : SessionStateCommandEntry709    {710        /// <summary>711        /// Represents a function definition in an Initial session state object.712        /// </summary>713        /// <param name="name">The name of the function.</param>714        /// <param name="definition">The definition of the function.</param>715        /// <param name="options">Options controlling scope-related elements of this object.</param>716        /// <param name="helpFile">The name of the help file associated with the function.</param>717        public SessionStateFunctionEntry(string name, string definition, ScopedItemOptions options, string helpFile)718            : base(name, SessionStateEntryVisibility.Public)719        {720            Definition = definition;721            CommandType = CommandTypes.Function;722            Options = options;723            ScriptBlock = ScriptBlock.Create(Definition);724            ScriptBlock.LanguageMode = PSLanguageMode.FullLanguage;725 726            HelpFile = helpFile;727        }728 729        /// <summary>730        /// Represents a function definition in an Initial session state object.731        /// </summary>732        /// <param name="name">The name of the function.</param>733        /// <param name="definition">The definition of the function.</param>734        /// <param name="helpFile">The name of the help file associated with the function.</param>735        public SessionStateFunctionEntry(string name, string definition, string helpFile)736            : this(name, definition, ScopedItemOptions.None, helpFile)737        {738        }739 740        /// <summary>741        /// Represents a function definition in an Initial session state object.742        /// </summary>743        /// <param name="name">The name of the function.</param>744        /// <param name="definition">The definition of the function.</param>745        public SessionStateFunctionEntry(string name, string definition)746            : this(name, definition, ScopedItemOptions.None, null)747        {748        }749 750        /// <summary>751        /// This is an internal copy constructor.752        /// </summary>753        internal SessionStateFunctionEntry(string name, string definition, ScopedItemOptions options,754            SessionStateEntryVisibility visibility, ScriptBlock scriptBlock, string helpFile)755            : base(name, visibility)756        {757            Definition = definition;758            CommandType = CommandTypes.Function;759            Options = options;760            ScriptBlock = scriptBlock;761            HelpFile = helpFile;762        }763 764        internal static SessionStateFunctionEntry GetDelayParsedFunctionEntry(string name, string definition, bool isProductCode, PSLanguageMode languageMode)765        {766            var fnEntry = GetDelayParsedFunctionEntry(name, definition, isProductCode);767            fnEntry.ScriptBlock.LanguageMode = languageMode;768            return fnEntry;769        }770 771        internal static SessionStateFunctionEntry GetDelayParsedFunctionEntry(string name, string definition, bool isProductCode)772        {773            var sb = ScriptBlock.CreateDelayParsedScriptBlock(definition, isProductCode);774            return new SessionStateFunctionEntry(name, definition, ScopedItemOptions.None, SessionStateEntryVisibility.Public, sb, null);775        }776 777        internal static SessionStateFunctionEntry GetDelayParsedFunctionEntry(string name, string definition, ScriptBlock sb)778        {779            return new SessionStateFunctionEntry(name, definition, ScopedItemOptions.None, SessionStateEntryVisibility.Public, sb, null);780        }781 782        /// <summary>783        /// Shallow-clone this object...784        /// </summary>785        /// <returns>The cloned object.</returns>786        public override InitialSessionStateEntry Clone()787        {788            SessionStateFunctionEntry entry = new SessionStateFunctionEntry(Name, Definition, Options, Visibility, ScriptBlock, HelpFile);789            entry.SetModule(this.Module);790            return entry;791        }792 793        /// <summary>794        /// Sets the name of the help file associated with the function.795        /// </summary>796        internal void SetHelpFile(string help)797        {798            HelpFile = help;799        }800 801        /// <summary>802        /// The string to use to define this function...803        /// </summary>804        public string Definition { get; }805 806        /// <summary>807        /// The script block for this function.808        /// </summary>809        internal ScriptBlock ScriptBlock { get; set; }810 811        /// <summary>812        /// Options controlling scope visibility and setability for this entry.813        /// </summary>814        public ScopedItemOptions Options { get; } = ScopedItemOptions.None;815 816        /// <summary>817        /// The name of the help file associated with the function.818        /// </summary>819        public string HelpFile { get; private set; }820    }821 822    /// <summary>823    /// </summary>824    public sealed class SessionStateVariableEntry : ConstrainedSessionStateEntry825    {826        /// <summary>827        /// Is used to define a variable that should be created when828        /// the runspace is opened. Note - if this object is cloned,829        /// then the clone will contain a reference to the original object830        /// not a clone of it.831        /// </summary>832        /// <param name="name">The name of the variable.</param>833        /// <param name="value">The value to set the variable to.</param>834        /// <param name="description">A descriptive string to attach to the variable.</param>835        public SessionStateVariableEntry(string name, object value, string description)836            : base(name, SessionStateEntryVisibility.Public)837        {838            Value = value;839            Description = description;840        }841 842        /// <summary>843        /// Is used to define a variable that should be created when844        /// the runspace is opened. Note - if this object is cloned,845        /// then the clone will contain a reference to the original object846        /// not a clone of it.847        /// </summary>848        /// <param name="name">The name of the variable.</param>849        /// <param name="value">The value to set the variable to.</param>850        /// <param name="description">A descriptive string to attach to the variable.</param>851        /// <param name="options">Options like readonly, constant, allscope, etc.</param>852        public SessionStateVariableEntry(string name, object value, string description, ScopedItemOptions options)853            : base(name, SessionStateEntryVisibility.Public)854        {855            Value = value;856            Description = description;857            Options = options;858        }859 860        /// <summary>861        /// Is used to define a variable that should be created when862        /// the runspace is opened. Note - if this object is cloned,863        /// then the clone will contain a reference to the original object864        /// not a clone of it.865        /// </summary>866        /// <param name="name">The name of the variable.</param>867        /// <param name="value">The value to set the variable to.</param>868        /// <param name="description">A descriptive string to attach to the variable.</param>869        /// <param name="options">Options like readonly, constant, allscope, etc.</param>870        /// <param name="attributes">A list of attributes to attach to the variable.</param>871        public SessionStateVariableEntry(string name, object value, string description, ScopedItemOptions options, Collection<Attribute> attributes)872            : base(name, SessionStateEntryVisibility.Public)873        {874            Value = value;875            Description = description;876            Options = options;877            _attributes = attributes;878        }879 880        /// <summary>881        /// Is used to define a variable that should be created when882        /// the runspace is opened. Note - if this object is cloned,883        /// then the clone will contain a reference to the original object884        /// not a clone of it.885        /// </summary>886        /// <param name="name">The name of the variable.</param>887        /// <param name="value">The value to set the variable to.</param>888        /// <param name="description">A descriptive string to attach to the variable.</param>889        /// <param name="options">Options like readonly, constant, allscope, etc.</param>890        /// <param name="attribute">A single attribute to attach to the variable.</param>891        public SessionStateVariableEntry(string name, object value, string description, ScopedItemOptions options, Attribute attribute)892            : base(name, SessionStateEntryVisibility.Public)893        {894            Value = value;895            Description = description;896            Options = options;897            _attributes = new Collection<Attribute>();898            _attributes.Add(attribute);899        }900 901        /// <summary>902        /// Is used to define a variable that should be created when903        /// the runspace is opened. Note - if this object is cloned,904        /// then the clone will contain a reference to the original object905        /// not a clone of it.906        /// </summary>907        /// <param name="name">The name of the variable.</param>908        /// <param name="value">The value to set the variable to.</param>909        /// <param name="description">A descriptive string to attach to the variable.</param>910        /// <param name="options">Options like readonly, constant, allscope, etc.</param>911        /// <param name="attributes">A single attribute to attach to the variable.</param>912        /// <param name="visibility"></param>913        internal SessionStateVariableEntry(string name, object value, string description, ScopedItemOptions options, Collection<Attribute> attributes, SessionStateEntryVisibility visibility)914            : base(name, visibility)915        {916            Value = value;917            Description = description;918            Options = options;919            _attributes = attributes;920        }921 922        /// <summary>923        /// Shallow-clone this object...924        /// </summary>925        /// <returns>The cloned object.</returns>926        public override InitialSessionStateEntry Clone()927        {928            // Copy the attribute collection if necessary...929            Collection<Attribute> attrs = null;930            if (_attributes != null && _attributes.Count > 0)931            {932                attrs = new Collection<Attribute>(_attributes);933            }934 935            return new SessionStateVariableEntry(Name, Value, Description, Options, attrs, Visibility);936        }937 938        /// <summary>939        /// The value to bind to this variable.940        /// </summary>941        public object Value { get; }942 943        /// <summary>944        /// The description associated with this variable.945        /// </summary>946        public string Description { get; } = string.Empty;947 948        /// <summary>949        /// The options associated with this variable (e.g. readonly, allscope, etc.)950        /// </summary>951        public ScopedItemOptions Options { get; } = ScopedItemOptions.None;952 953        /// <summary>954        /// The attributes that will be attached to this object.955        /// </summary>956        public Collection<Attribute> Attributes957        {958            get { return _attributes ??= new Collection<Attribute>(); }959        }960 961        private Collection<Attribute> _attributes;962    }963 964    /// <summary>965    /// </summary>966    /// <typeparam name="T"></typeparam>967    public sealed class InitialSessionStateEntryCollection<T> : IEnumerable<T> where T : InitialSessionStateEntry968    {969        /// <summary>970        /// Create an empty collection...971        /// </summary>972        public InitialSessionStateEntryCollection()973        {974            _internalCollection = new Collection<T>();975        }976 977        /// <summary>978        /// Create an new collection, copying in the passed items...979        /// </summary>980        /// <param name="items"></param>981        public InitialSessionStateEntryCollection(IEnumerable<T> items)982        {983            ArgumentNullException.ThrowIfNull(items);984 985            _internalCollection = new Collection<T>();986 987            foreach (T item in items)988            {989                _internalCollection.Add(item);990            }991        }992 993        /// <summary>994        /// Clone this collection.995        /// </summary>996        /// <returns>The cloned collection.</returns>997        public InitialSessionStateEntryCollection<T> Clone()998        {999            InitialSessionStateEntryCollection<T> result;1000            lock (_syncObject)1001            {1002                result = new InitialSessionStateEntryCollection<T>();1003 1004                foreach (T item in _internalCollection)1005                {1006                    result.Add((T)item.Clone());1007                }1008            }1009 1010            return result;1011        }1012 1013        /// <summary>1014        /// Reset the collection.1015        /// </summary>1016        public void Reset()1017        {1018            lock (_syncObject)1019            {1020                _internalCollection.Clear();1021            }1022        }1023 1024        /// <summary>1025        /// Returns a count of the number of items in the collection...1026        /// </summary>1027        public int Count1028        {1029            get { return _internalCollection.Count; }1030        }1031 1032        /// <summary>1033        /// </summary>1034        /// <param name="index"></param>1035        /// <returns></returns>1036        public T this[int index]1037        {1038            get1039            {1040                T result;1041                lock (_syncObject)1042                {1043                    result = _internalCollection[index];1044                }1045 1046                return result;1047            }1048        }1049 1050        /// <summary>1051        /// To find the entries based on name.1052        /// Why collection - Different SnapIn/modules and same entity names.1053        /// If used on command collection entry, then for the same name, one can have multiple output.1054        /// </summary>1055        /// <param name="name"></param>1056        /// <returns></returns>1057        public Collection<T> this[string name]1058        {1059            get1060            {1061                Collection<T> result = new Collection<T>();1062                lock (_syncObject)1063                {1064                    foreach (T element in _internalCollection)1065                    {1066                        if (element.Name.Equals(name, StringComparison.OrdinalIgnoreCase))1067                        {1068                            result.Add(element);1069                        }1070                    }1071                }1072 1073                return result;1074            }1075        }1076 1077        /// <summary>1078        /// Find entries based on string name which can include wildcards.1079        /// </summary>1080        /// <param name="name"></param>1081        /// <returns></returns>1082        internal Collection<T> LookUpByName(string name)1083        {1084            if (name == null)1085            {1086                throw new PSArgumentNullException(nameof(name));1087            }1088 1089            Collection<T> result = new Collection<T>();1090            WildcardPattern namePattern = WildcardPattern.Get(name, WildcardOptions.IgnoreCase);1091            lock (_syncObject)1092            {1093                foreach (T element in _internalCollection)1094                {1095                    if (namePattern.IsMatch(element.Name))1096                    {1097                        result.Add(element);1098                    }1099                }1100            }1101 1102            return result;1103        }1104 1105        /// <summary>1106        /// </summary>1107        /// <param name="index"></param>1108        public void RemoveItem(int index)1109        {1110            lock (_syncObject)1111            {1112                _internalCollection.RemoveAt(index);1113            }1114        }1115 1116        /// <summary>1117        /// Remove a number of items starting at the specified index.1118        /// </summary>1119        /// <param name="index"></param>1120        /// <param name="count"></param>1121        public void RemoveItem(int index, int count)1122        {1123            lock (_syncObject)1124            {1125                while (count-- > 0)1126                {1127                    _internalCollection.RemoveAt(index);1128                }1129            }1130        }1131 1132        /// <summary>1133        /// Clears the collection...1134        /// </summary>1135        public void Clear()1136        {1137            lock (_syncObject)1138            {1139                _internalCollection.Clear();1140            }1141        }1142 1143        /// <summary>1144        /// This overload exists so that we can remove items based on the item name, rather than1145        /// its position in the collection. The type argument can be null but we'll throw an error if1146        /// we can't distinguish between multiple entries of the same name but different types1147        /// and the type hasn't been specified.1148        /// BUGBUG - brucepay - the throw thing is not implemented yet...1149        /// </summary>1150        /// <param name="name">The name of the element to remove.</param>1151        /// <param name="type">The type of object to remove, can be null to remove any type.</param>1152        public void Remove(string name, object type)1153        {1154            ArgumentNullException.ThrowIfNull(name);1155 1156            lock (_syncObject)1157            {1158                Type objType = null;1159 1160                if (type != null)1161                {1162                    objType = type as Type ?? type.GetType();1163                }1164 1165                // Work backwards through the collection...1166                for (int i = _internalCollection.Count - 1; i >= 0; i--)1167                {1168                    T element = _internalCollection[i];1169                    if (element == null)1170                    {1171                        continue;1172                    }1173 1174                    if ((objType == null || element.GetType() == objType) &&1175                        string.Equals(element.Name, name, StringComparison.OrdinalIgnoreCase))1176                    {1177                        _internalCollection.RemoveAt(i);1178                    }1179                }1180            }1181        }1182 1183        /// <summary>1184        /// Add an item to this collection.1185        /// </summary>1186        /// <param name="item">The item to add...</param>1187        public void Add(T item)1188        {1189            ArgumentNullException.ThrowIfNull(item);1190 1191            lock (_syncObject)1192            {1193                _internalCollection.Add(item);1194            }1195        }1196 1197        /// <summary>1198        /// Add items to this collection.1199        /// </summary>1200        /// <param name="items"></param>

Showing the first 1,200 of 5683 lines. Download the file for the rest.