Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
ModuleCmdletBase.cs7495 linesDownload Raw Back to Modules
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System;5using System.Collections;6using System.Collections.Generic;7using System.Collections.ObjectModel;8using System.Diagnostics.CodeAnalysis;9using System.Globalization;10using System.IO;11using System.Linq;12using System.Management.Automation;13using System.Management.Automation.Configuration;14using System.Management.Automation.Internal;15using System.Management.Automation.Language;16using System.Management.Automation.Runspaces;17using System.Management.Automation.Security;18using System.Reflection;19using System.Runtime.InteropServices;20using System.Text;21using System.Xml;22using System.Diagnostics;23 24using Microsoft.PowerShell.Cmdletization;25 26using Dbg = System.Management.Automation.Diagnostics;27 28//29// Now define the set of commands for manipulating modules.30//31 32namespace Microsoft.PowerShell.Commands33{34    #region ModuleCmdletBase class35 36    /// <summary>37    /// This is the base class for some of the module cmdlets. It contains a number of38    /// utility functions for these classes.39    /// </summary>40    public class ModuleCmdletBase : PSCmdlet41    {42        /// <summary>43        /// Flags defining how a module manifest should be processed.44        /// </summary>45        [Flags]46        internal enum ManifestProcessingFlags47        {48            /// <summary>49            /// Write errors (otherwise no non-terminating-errors are written)50            /// </summary>51            WriteErrors = 0x1,52 53            /// <summary>54            /// Return null on first error (otherwise we try to process other elements of the manifest)55            /// </summary>56            NullOnFirstError = 0x2,57 58            /// <summary>59            /// Load elements of the manifest (i.e. types/format.ps1xml, nested modules, etc.)60            /// </summary>61            LoadElements = 0x4,62 63            /// <summary>64            /// Write warnings.65            /// </summary>66            WriteWarnings = 0x8,67 68            /// <summary>69            /// Force full module manifest processing.70            /// </summary>71            Force = 0x10,72 73            /// <summary>74            /// Ignore PowerShellHostName and PowerShellHostVersion while75            /// processing Manifest fields.76            /// This is used for GetModule where loading elements does not happen.77            /// </summary>78            IgnoreHostNameAndHostVersion = 0x20,79        }80 81        /// <summary>82        /// Options set during module import.83        /// </summary>84        [SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes")]85        protected internal struct ImportModuleOptions86        {87            /// <summary>88            /// Holds the value of NoClobber parameter in Import-Module89            /// This is used when importing modules.90            /// </summary>91            internal bool NoClobber;92 93            /// <summary>94            /// If Scope parameter is Local, this is true.95            /// </summary>96            internal bool Local;97 98            /// <summary>99            /// Lets nested module import to export all of its functions, regardless of language boundaries.100            /// This will be allowed when the manifest explicitly exports functions which will limit all visible module functions.101            /// </summary>102            internal bool AllowNestedModuleFunctionsToExport;103 104            /// <summary>105            /// Flag that controls Export-PSSession -AllowClobber parameter in generating proxy modules from remote sessions.106            /// Historically -AllowClobber in these scenarios was set as True.107            /// </summary>108            internal bool NoClobberExportPSSession;109 110            /// <summary>111            /// Flag that controls skipping the System32 module path when searching a module in module paths. It also suppresses112            /// writing out errors when specified.113            /// </summary>114            internal bool SkipSystem32ModulesAndSuppressError;115        }116 117        /// <summary>118        /// This parameter specified a prefix used to modify names of imported commands.119        /// </summary>120        internal string BasePrefix { get; set; } = string.Empty;121 122        /// <summary>123        /// Flags -force operations.124        /// </summary>125        internal bool BaseForce { get; set; }126 127        /// <summary>128        /// Flags -global operations (affects what gets returned by TargetSessionState)129        /// </summary>130        internal bool BaseGlobal { get; set; }131 132        /// <summary>133        /// If set, CompatiblePSEditions checking will be disabled for modules on the System32 path.134        /// </summary>135        internal bool BaseSkipEditionCheck { get; set; }136 137        internal SessionState TargetSessionState138        {139            get140            {141                if (BaseGlobal)142                {143                    return this.Context.TopLevelSessionState.PublicSessionState;144                }145                else146                {147                    return this.Context.SessionState;148                }149            }150        }151 152        /// <summary>153        /// Flags -passthru operations.154        /// </summary>155        internal bool BasePassThru { get; set; }156 157        /// <summary>158        /// Flags -passthru operations.159        /// </summary>160        internal bool BaseAsCustomObject { get; set; }161 162        /// <summary>163        /// Wildcard patterns for the function to import.164        /// </summary>165        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Cmdlet parameters.")]166        internal List<WildcardPattern> BaseFunctionPatterns { get; set; }167 168        /// <summary>169        /// Wildcard patterns for the cmdlets to import.170        /// </summary>171        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Cmdlet parameters.")]172        internal List<WildcardPattern> BaseCmdletPatterns { get; set; }173 174        /// <summary>175        /// Wildcard patterns for the variables to import.176        /// </summary>177        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Cmdlet parameters.")]178        internal List<WildcardPattern> BaseVariablePatterns { get; set; }179 180        /// <summary>181        /// Wildcard patterns for the aliases to import.182        /// </summary>183        [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Cmdlet parameters.")]184        internal List<WildcardPattern> BaseAliasPatterns { get; set; }185 186        /// <summary>187        /// The minimum version number to check the module against. Used the underlying property188        /// for derived cmdlet parameters.189        /// </summary>190        internal Version BaseMinimumVersion { get; set; }191 192        /// <summary>193        /// The maximum version number to check the module against. Used the underlying property194        /// for derived cmdlet parameters.195        /// </summary>196        internal Version BaseMaximumVersion { get; set; }197 198        /// <summary>199        /// The version number to check the module against. Used the underlying property200        /// for derived cmdlet parameters.201        /// </summary>202        internal Version BaseRequiredVersion { get; set; }203 204        /// <summary>205        /// The Guid to check the module against. Used the underlying property206        /// for derived cmdlet parameters.207        /// </summary>208        internal Guid? BaseGuid { get; set; }209 210        /// <summary>211        /// The arguments to pass to the scriptblock used to create the module.212        /// </summary>213        [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", Justification = "Cmdlets use arrays for parameters.")]214        protected object[] BaseArgumentList { get; set; }215 216        /// <summary>217        /// Disable warnings on cmdlet and function names that have non-standard verbs218        /// or non-standard characters in the noun.219        /// </summary>220        protected bool BaseDisableNameChecking { get; set; } = true;221 222        /// <summary>223        /// Add module path to app domain level module path cache if name is not rooted.224        /// </summary>225        protected bool AddToAppDomainLevelCache { get; set; } = false;226 227        /// <summary>228        /// A handy match all pattern used to initialize various import and export lists...229        /// </summary>230        internal List<WildcardPattern> MatchAll231        {232            get233            {234                if (_matchAll == null)235                {236                    _matchAll = new List<WildcardPattern>();237                    _matchAll.Add(WildcardPattern.Get("*", WildcardOptions.IgnoreCase));238                }239 240                return _matchAll;241            }242        }243 244        private List<WildcardPattern> _matchAll;245 246        // The list of commands permitted in a module manifest247        internal static readonly string[] PermittedCmdlets = new string[] {248            "Import-LocalizedData", "ConvertFrom-StringData", "Write-Host", "Out-Host", "Join-Path" };249 250        internal static readonly string[] ModuleManifestMembers = new string[] {251            "ModuleToProcess",252            "NestedModules",253            "GUID",254            "Author",255            "CompanyName",256            "Copyright",257            "ModuleVersion",258            "Description",259            "PowerShellVersion",260            "PowerShellHostName",261            "PowerShellHostVersion",262            "CLRVersion",263            "DotNetFrameworkVersion",264            "ProcessorArchitecture",265            "RequiredModules",266            "TypesToProcess",267            "FormatsToProcess",268            "ScriptsToProcess",269            "PrivateData",270            "RequiredAssemblies",271            "ModuleList",272            "FileList",273            "FunctionsToExport",274            "VariablesToExport",275            "AliasesToExport",276            "CmdletsToExport",277            "DscResourcesToExport",278            "CompatiblePSEditions",279            "HelpInfoURI",280            "RootModule",281            "DefaultCommandPrefix"282        };283 284        private static readonly string[] s_moduleVersionMembers = new string[] {285            "ModuleName",286            "GUID",287            "ModuleVersion"288        };289 290        /// <summary>291        /// List of PowerShell built-in modules that are shipped with PowerShell only, not on PS Gallery.292        /// </summary>293        protected static readonly HashSet<string> BuiltInModules = new(StringComparer.OrdinalIgnoreCase)294        {295            "CimCmdlets",296            "Microsoft.PowerShell.Diagnostics",297            "Microsoft.PowerShell.Host",298            "Microsoft.PowerShell.Management",299            "Microsoft.PowerShell.Security",300            "Microsoft.PowerShell.Utility",301            "Microsoft.WSMan.Management",302            "PSDiagnostics",303        };304 305        /// <summary>306        /// When module manifests lack a CompatiblePSEditions field,307        /// they will be treated as if they have this value.308        /// The PSModuleInfo will still reflect the lack of value.309        /// </summary>310        internal static IReadOnlyList<string> DefaultCompatiblePSEditions { get; } = new string[]311        {312            "Desktop"313        };314 315        /// <summary>316        /// A counter for modules that are loaded using WindowsPS compat session.317        /// </summary>318        internal static int s_WindowsPowerShellCompatUsageCounter = 0;319 320        /// <summary>321        /// Session name for WindowsPS compat remoting session.322        /// </summary>323        internal const string WindowsPowerShellCompatRemotingSessionName = "WinPSCompatSession";324 325        /// <summary>326        /// Synchronization object for creation/cleanup of WindowsPS compat remoting session.327        /// </summary>328        internal static readonly object s_WindowsPowerShellCompatSyncObject = new object();329 330        private readonly Dictionary<string, PSModuleInfo> _currentlyProcessingModules = new Dictionary<string, PSModuleInfo>();331 332        internal bool LoadUsingModulePath(333            IEnumerable<string> modulePath,334            string name,335            SessionState ss,336            ImportModuleOptions options,337            ManifestProcessingFlags manifestProcessingFlags,338            out PSModuleInfo module)339        {340            return LoadUsingModulePath(parentModule: null, modulePath, name, ss, options, manifestProcessingFlags, out module);341        }342 343        internal bool LoadUsingModulePath(344            PSModuleInfo parentModule,345            IEnumerable<string> modulePath,346            string name,347            SessionState ss,348            ImportModuleOptions options,349            ManifestProcessingFlags manifestProcessingFlags,350            out PSModuleInfo module)351        {352            string extension = Path.GetExtension(name);353            string fileBaseName;354            module = null;355            if (string.IsNullOrEmpty(extension) || !ModuleIntrinsics.IsPowerShellModuleExtension(extension))356            {357                fileBaseName = name;358                extension = null;359            }360            else361            {362                fileBaseName = name.Substring(0, name.Length - extension.Length);363            }364 365            // Now search using the module path...366            bool found = false;367            foreach (string path in modulePath)368            {369                if (options.SkipSystem32ModulesAndSuppressError && ModuleUtils.IsOnSystem32ModulePath(path))370                {371                    continue;372                }373#if UNIX374                foreach (string folder in Directory.EnumerateDirectories(path))375                {376                    string moduleName = Path.GetFileName(folder);377                    if (string.Equals(moduleName, fileBaseName, StringComparison.OrdinalIgnoreCase))378                    {379                        fileBaseName = moduleName;380#endif381                string qualifiedPath = Path.Combine(path, fileBaseName);382                module = LoadUsingMultiVersionModuleBase(qualifiedPath, manifestProcessingFlags, options, out found);383                if (!found)384                {385                    if (name.AsSpan().IndexOfAny('\\', '/') == -1)386                    {387                        qualifiedPath = Path.Combine(qualifiedPath, fileBaseName);388                    }389                    else if (Directory.Exists(qualifiedPath))390                    {391                        // if it points to a directory, add the basename back onto the path...392                        qualifiedPath = Path.Combine(qualifiedPath, Path.GetFileName(fileBaseName));393                    }394 395                    module = LoadUsingExtensions(parentModule, name, qualifiedPath, extension, null, this.BasePrefix, ss, options, manifestProcessingFlags, out found);396                }397 398                if (found)399                {400                    break;401                }402#if UNIX403                    }404                }405 406                if (found)407                {408                    break;409                }410#endif411            }412 413            if (found)414            {415                // Cache the module's exported commands after importing it, or if the -Refresh flag is used on "Get-Module -List"416                if ((module != null) && !module.HadErrorsLoading)417                {418                    AnalysisCache.CacheModuleExports(module, Context);419                }420            }421 422            return found;423        }424 425        /// <summary>426        /// Loads the latest valid version if moduleBase is a multi-versioned module directory.427        /// </summary>428        /// <param name="moduleBase">Module directory path.</param>429        /// <param name="manifestProcessingFlags">The flag that indicate manifest processing option.</param>430        /// <param name="importModuleOptions">The set of options that are used while importing a module.</param>431        /// <param name="found">True if a module was found.</param>432        /// <returns></returns>433        internal PSModuleInfo LoadUsingMultiVersionModuleBase(string moduleBase, ManifestProcessingFlags manifestProcessingFlags, ImportModuleOptions importModuleOptions, out bool found)434        {435            PSModuleInfo foundModule = null;436            found = false;437 438            foreach (var version in ModuleUtils.GetModuleVersionSubfolders(moduleBase))439            {440                // Skip the version folder if it is not equal to the required version or does not satisfy the minimum/maximum version criteria441                if (!ModuleIntrinsics.IsVersionMatchingConstraints(version, BaseRequiredVersion, BaseMinimumVersion, BaseMaximumVersion))442                {443                    continue;444                }445 446                var qualifiedPathWithVersion = Path.Combine(moduleBase,447                                                            Path.Combine(version.ToString(), Path.GetFileName(moduleBase)));448                string manifestPath = qualifiedPathWithVersion + StringLiterals.PowerShellDataFileExtension;449                var isValidModuleVersion = false;450                if (File.Exists(manifestPath))451                {452                    isValidModuleVersion = version.Equals(ModuleIntrinsics.GetManifestModuleVersion(manifestPath));453 454                    if (isValidModuleVersion)455                    {456                        foundModule = LoadUsingExtensions(null, moduleBase, qualifiedPathWithVersion,457                                                            StringLiterals.PowerShellDataFileExtension,458                                                            null,459                                                            this.BasePrefix, /*SessionState*/ null,460                                                            importModuleOptions,461                                                            manifestProcessingFlags,462                                                            out found);463                        if (found)464                        {465                            break;466                        }467                    }468                }469 470                if (!isValidModuleVersion)471                {472                    WriteVerbose(string.Format(CultureInfo.InvariantCulture, Modules.SkippingInvalidModuleVersionFolder,473                                                version.ToString(), moduleBase));474                }475            }476 477            return foundModule;478        }479 480        /// <summary>481        /// Load and execute the manifest psd1 file or a localized manifest psd1 file.482        /// </summary>483        private Hashtable LoadModuleManifestData(484            ExternalScriptInfo scriptInfo,485            string[] validMembers,486            ManifestProcessingFlags manifestProcessingFlags,487            ref bool containedErrors)488        {489            try490            {491                return LoadModuleManifestData(scriptInfo.Path, scriptInfo.ScriptBlock, validMembers, manifestProcessingFlags, ref containedErrors);492            }493            catch (RuntimeException pe)494            {495                if ((manifestProcessingFlags & ManifestProcessingFlags.WriteErrors) != 0)496                {497                    string message = StringUtil.Format(Modules.InvalidModuleManifest, scriptInfo.Path, pe.Message);498                    MissingMemberException mm = new MissingMemberException(message);499                    ErrorRecord er = new ErrorRecord(mm, "Modules_InvalidManifest",500                        ErrorCategory.ResourceUnavailable, scriptInfo.Path);501                    WriteError(er);502                }503 504                containedErrors = true;505                return null;506            }507        }508 509        /// <summary>510        /// Extra variables that are allowed to be referenced in module manifest file.511        /// </summary>512        private static readonly string[] s_extraAllowedVariables = new string[] { SpecialVariables.PSScriptRoot, SpecialVariables.PSEdition, SpecialVariables.EnabledExperimentalFeatures };513 514        /// <summary>515        /// Load and execute the manifest psd1 file or a localized manifest psd1 file.516        /// </summary>517        internal Hashtable LoadModuleManifestData(518            string moduleManifestPath,519            ScriptBlock scriptBlock,520            string[] validMembers,521            ManifestProcessingFlags manifestProcessingFlags,522            ref bool containedErrors)523        {524            string message;525 526            var importingModule = (manifestProcessingFlags & ManifestProcessingFlags.LoadElements) != 0;527            var writingErrors = (manifestProcessingFlags & ManifestProcessingFlags.WriteErrors) != 0;528 529            // Load the data file(s) to get the module info...530            try531            {532                scriptBlock.CheckRestrictedLanguage(PermittedCmdlets, s_extraAllowedVariables, true);533            }534            catch (RuntimeException pe)535            {536                if (writingErrors)537                {538                    message = StringUtil.Format(Modules.InvalidModuleManifest, moduleManifestPath, pe.Message);539                    MissingMemberException mm = new MissingMemberException(message);540                    ErrorRecord er = new ErrorRecord(mm, "Modules_InvalidManifest",541                        ErrorCategory.ResourceUnavailable, moduleManifestPath);542                    WriteError(er);543                }544 545                containedErrors = true;546                return null;547            }548 549            object result;550            object oldPSScriptRoot = Context.GetVariableValue(SpecialVariables.PSScriptRootVarPath);551            object oldPSCommandPath = Context.GetVariableValue(SpecialVariables.PSCommandPathVarPath);552            ArrayList errors = (ArrayList)Context.GetVariableValue(SpecialVariables.ErrorVarPath);553            int oldErrorCount = errors.Count;554 555            try556            {557                // Set the PSScriptRoot variable in the modules session state558                Context.SetVariable(SpecialVariables.PSScriptRootVarPath, Path.GetDirectoryName(moduleManifestPath));559                Context.SetVariable(SpecialVariables.PSCommandPathVarPath, moduleManifestPath);560 561                result = PSObject.Base(scriptBlock.InvokeReturnAsIs());562            }563            finally564            {565                Context.SetVariable(SpecialVariables.PSScriptRootVarPath, oldPSScriptRoot);566                Context.SetVariable(SpecialVariables.PSCommandPathVarPath, oldPSCommandPath);567 568                // We do not want any exceptions to show up in user's session state. So, we are removing errors in the finally block.569                // If we're not loading the manifest (and are examining it), prevent errors from showing up in570                // the user's session.571                if (!importingModule)572                {573                    while (errors.Count > oldErrorCount) { errors.RemoveAt(0); }574                }575            }576 577            Hashtable data = result as Hashtable;578            if (data == null)579            {580                if (writingErrors)581                {582                    message = StringUtil.Format(Modules.EmptyModuleManifest, moduleManifestPath);583                    ArgumentException ae = new ArgumentException(message);584                    ErrorRecord er = new ErrorRecord(ae, "Modules_InvalidManifest",585                        ErrorCategory.ResourceUnavailable, moduleManifestPath);586                    WriteError(er);587                }588 589                containedErrors = true;590                return null;591            }592 593            // MSFT:873446 Create a case insensitive comparer based hashtable to help594            // with case-insensitive comparison of keys.595            data = new Hashtable(data, StringComparer.OrdinalIgnoreCase);596            if (validMembers != null && !ValidateManifestHash(data, validMembers, moduleManifestPath, manifestProcessingFlags))597            {598                containedErrors = true;599                if ((manifestProcessingFlags & ManifestProcessingFlags.NullOnFirstError) != 0)600                    return null;601            }602 603            return data;604        }605 606        /// <summary>607        /// Verify the hash contains only valid members.  Write an error and return false if it is not valid.608        /// </summary>609        private bool ValidateManifestHash(610            Hashtable data,611            string[] validMembers,612            string moduleManifestPath,613            ManifestProcessingFlags manifestProcessingFlags)614        {615            bool result = true;616 617            StringBuilder badKeys = new StringBuilder();618            foreach (string s in data.Keys)619            {620                bool found = false;621 622                foreach (string member in validMembers)623                {624                    if (s.Equals(member, StringComparison.OrdinalIgnoreCase))625                    {626                        found = true;627                    }628                }629 630                if (!found)631                {632                    if (badKeys.Length > 0)633                        badKeys.Append(", ");634                    badKeys.Append('\'');635                    badKeys.Append(s);636                    badKeys.Append('\'');637                }638            }639 640            if (badKeys.Length > 0)641            {642                result = false;643                string message = null;644 645                if ((manifestProcessingFlags & ManifestProcessingFlags.WriteErrors) != 0)646                {647                    // Check for PowerShell Version before checking other keys648                    // If a PowerShellVersion exists and does not match the requirements, then the error is InsufficientPowerShellVersion649                    // Else, the error is InvalidManifestMember650                    Version powerShellVersion;651                    Version currentPowerShellVersion = PSVersionInfo.PSVersion;652                    if (GetScalarFromData<Version>(data, moduleManifestPath, "PowerShellVersion", manifestProcessingFlags, out powerShellVersion) &&653                        currentPowerShellVersion < powerShellVersion)654                    {655                        message = StringUtil.Format(Modules.ModuleManifestInsufficientPowerShellVersion,656                                                    currentPowerShellVersion,657                                                    moduleManifestPath, powerShellVersion);658                        InvalidOperationException ioe = new InvalidOperationException(message);659                        ErrorRecord er = new ErrorRecord(ioe, "Modules_InsufficientPowerShellVersion",660                                                         ErrorCategory.ResourceUnavailable, moduleManifestPath);661                        WriteError(er);662                    }663                    else664                    {665                        StringBuilder validMembersString = new StringBuilder("'");666                        validMembersString.Append(validMembers[0]);667                        for (int i = 1; i < validMembers.Length; i++)668                        {669                            validMembersString.Append("', '");670                            validMembersString.Append(validMembers[i]);671                        }672 673                        validMembersString.Append('\'');674                        message = StringUtil.Format(Modules.InvalidModuleManifestMember, moduleManifestPath, validMembersString, badKeys);675                        InvalidOperationException ioe = new InvalidOperationException(message);676                        ErrorRecord er = new ErrorRecord(ioe, "Modules_InvalidManifestMember",677                            ErrorCategory.InvalidData, moduleManifestPath);678                        WriteError(er);679                    }680                }681            }682 683            return result;684        }685 686        private PSModuleInfo LoadModuleNamedInManifest(687            PSModuleInfo parentModule,688            ModuleSpecification moduleSpecification,689            string moduleBase,690            bool searchModulePath,691            string prefix,692            SessionState ss,693            ImportModuleOptions options,694            ManifestProcessingFlags manifestProcessingFlags,695            object privateData,696            out bool found,697            string shortModuleName,698            PSLanguageMode? manifestLanguageMode)699        {700            PSModuleInfo module = null;701            PSModuleInfo tempModuleInfoFromVerification = null;702            found = false;703            bool moduleFileFound = false;704            bool wasRooted = false;705            Version savedBaseMinimumVersion = BaseMinimumVersion;706            Version savedBaseMaximumVersion = BaseMaximumVersion;707            Version savedBaseRequiredVersion = BaseRequiredVersion;708            Guid? savedBaseGuid = BaseGuid;709 710            var importingModule = manifestProcessingFlags.HasFlag(ManifestProcessingFlags.LoadElements);711            string extension = Path.GetExtension(moduleSpecification.Name);712 713            // First check for fully-qualified paths - either absolute or relative714            string rootedPath = ResolveRootedFilePath(moduleSpecification.Name, this.Context);715            if (string.IsNullOrEmpty(rootedPath))716            {717                // Use the name of the parent module if it's specified, otherwise, use the current module name.718                //  - If the current module is a nested module, then the parent module will be specified.719                //  - If the current module is a root module, then the parent module will not be specified.720                string moduleName = parentModule?.Name ?? ModuleIntrinsics.GetModuleName(moduleSpecification.Name);721                rootedPath = FixFileName(moduleName, moduleBase, moduleSpecification.Name, extension: null, canLoadAssembly: importingModule);722            }723            else724            {725                wasRooted = true;726            }727 728            try729            {730                this.Context.Modules.IncrementModuleNestingDepth(this, rootedPath);731                BaseMinimumVersion = null;732                BaseMaximumVersion = null;733                BaseRequiredVersion = null;734                BaseGuid = null;735 736                // See if it's one of the powershell module extensions...737                if (!ModuleIntrinsics.IsPowerShellModuleExtension(extension))738                {739                    // If the file exits, and it does not have a powershell module extension, we know for sure that the file is not a valid module740                    if (File.Exists(rootedPath))741                    {742                        PSInvalidOperationException invalidOperation = PSTraceSource.NewInvalidOperationException(743                                                                Modules.ManifestMemberNotValid,744                                                                moduleSpecification.Name,745                                                                "NestedModules",746                                                                parentModule?.Path,747                                                                StringUtil.Format(Modules.InvalidModuleExtension, extension, moduleSpecification.Name),748                                                                                    ModuleIntrinsics.GetModuleName(parentModule?.Path));749                        invalidOperation.SetErrorId("Modules_InvalidModuleExtension");750                        throw invalidOperation;751                    }752 753                    extension = null;754                }755 756                // Now load the module from the module directory first...757                if (extension == null)758                {759                    // No extension so we'll have to search using the extensions760                    //761                    if (VerifyIfNestedModuleIsAvailable(moduleSpecification, rootedPath, /*extension*/null, out tempModuleInfoFromVerification))762                    {763                        module = LoadUsingExtensions(764                            parentModule,765                            moduleSpecification.Name,766                            fileBaseName: rootedPath,767                            extension: null,768                            moduleBase, // not using base from tempModuleInfoFromVerification as we are looking under moduleBase directory769                            prefix,770                            ss,771                            options,772                            manifestProcessingFlags,773                            out found,774                            out moduleFileFound);775                    }776 777                    // Win8: 262157 - Import-Module is giving errors while loading Nested Modules. (This is a V2 bug)778                    // NestedModules = 'test2' ---> test2 is a directory under current module directory (e.g - Test1)779                    // We also need to look for Test1\Test2\Test2.(psd1/psm1/dll)780                    // With the call above, we are only looking at Test1\Test2.(psd1/psm1/dll)781                    if (!found && !moduleFileFound)782                    {783                        string newRootedPath = Path.Combine(rootedPath, moduleSpecification.Name);784                        string newModuleBase = Path.Combine(moduleBase, moduleSpecification.Name);785                        if (VerifyIfNestedModuleIsAvailable(moduleSpecification, newRootedPath, /*extension*/null, out tempModuleInfoFromVerification))786                        {787                            module = LoadUsingExtensions(788                                parentModule,789                                moduleSpecification.Name,790                                fileBaseName: newRootedPath,791                                extension: null,792                                newModuleBase, // not using base from tempModuleInfoFromVerification as we are looking under moduleBase directory793                                prefix,794                                ss,795                                options,796                                manifestProcessingFlags,797                                out found,798                                out moduleFileFound);799                        }800                    }801                }802                else803                {804                    // Ok - we have a complete file name so load that...805                    if (VerifyIfNestedModuleIsAvailable(moduleSpecification, rootedPath, extension, out tempModuleInfoFromVerification))806                    {807                        module = LoadModule(808                            parentModule,809                            rootedPath, // fileName810                            moduleBase, // not using base from tempModuleInfoFromVerification as we have a complete file name811                            prefix,812                            ss,813                            privateData,814                            ref options,815                            manifestProcessingFlags,816                            out found,817                            out moduleFileFound);818                    }819 820                    // Win8: 262157 - Import-Module is giving errors while loading Nested Modules. (This is a V2 bug)821                    // Only look for the file if the file was not found with the previous search822                    if (!found && !moduleFileFound)823                    {824                        string newRootedPath = Path.Combine(rootedPath, moduleSpecification.Name);825                        string newModuleBase = Path.Combine(moduleBase, moduleSpecification.Name);826                        if (VerifyIfNestedModuleIsAvailable(moduleSpecification, newRootedPath, extension, out tempModuleInfoFromVerification))827                        {828                            module = LoadModule(829                                parentModule,830                                newRootedPath, // fileName831                                newModuleBase, // not using base from tempModuleInfoFromVerification as we are looking under moduleBase directory832                                prefix,833                                ss,834                                privateData,835                                ref options,836                                manifestProcessingFlags,837                                out found,838                                out moduleFileFound);839                        }840                    }841                }842 843                // The rooted files wasn't found, so don't search anymore...844                if (!found && wasRooted)845                    return null;846 847                if (searchModulePath && !found && !moduleFileFound)848                {849                    if (VerifyIfNestedModuleIsAvailable(moduleSpecification, null, null, out tempModuleInfoFromVerification))850                    {851                        IEnumerable<string> modulePath = null;852                        if (tempModuleInfoFromVerification != null)853                        {854                            var subdirName = Path.GetFileName(tempModuleInfoFromVerification.ModuleBase);855                            Version version;856                            if (Version.TryParse(subdirName, out version))857                            {858                                var moduleBaseWithoutVersion = Path.GetDirectoryName(tempModuleInfoFromVerification.ModuleBase);859 860                                modulePath = new string[]861                                {862                                    Path.GetDirectoryName(moduleBaseWithoutVersion),863                                    moduleBaseWithoutVersion864                                };865                            }866                            else867                            {868                                modulePath = new string[]869                                {870                                    Path.GetDirectoryName(tempModuleInfoFromVerification.ModuleBase),871                                    tempModuleInfoFromVerification.ModuleBase872                                };873                            }874                        }875                        else876                        {877                            modulePath = ModuleIntrinsics.GetModulePath(false, this.Context);878                        }879 880                        // Otherwise try the module path881                        found = LoadUsingModulePath(parentModule, modulePath,882                                                    moduleSpecification.Name, ss,883                                                    options, manifestProcessingFlags, out module);884                    }885                }886 887                if (manifestLanguageMode.HasValue && found && (module != null) && module.LanguageMode.HasValue)888                {889                    // Check for script module language mode consistency.  All loaded script modules must have the same language mode as the manifest.890                    // If not then this indicates a malformed module and a possible exploit to make trusted private functions visible in a891                    // Constrained Language session.892                    if (module.LanguageMode != manifestLanguageMode)893                    {894                        if (SystemPolicy.GetSystemLockdownPolicy() != SystemEnforcementMode.Audit)895                        {896                            var languageModeError = PSTraceSource.NewInvalidOperationException(897                                Modules.MismatchedLanguageModes,898                                module.Name, manifestLanguageMode, module.LanguageMode);899                            languageModeError.SetErrorId("Modules_MismatchedLanguageModes");900                            throw languageModeError;901                        }902 903                        SystemPolicy.LogWDACAuditMessage(904                            context: Context,905                            title: Modules.WDACMismatchedLanguageModesTitle,906                            message: Modules.WDACMismatchedLanguageModesMessage,907                            fqid: "ModulesMismatchedLanguageModes",908                            dropIntoDebugger: true);909                    }910                }911 912                // At this point, we haven't found an actual module, so try loading it as a913                // PSSnapIn and then finally as an assembly in the GAC...914                if (!found && (moduleSpecification.Guid == null) && (moduleSpecification.Version == null) && (moduleSpecification.RequiredVersion == null) && (moduleSpecification.MaximumVersion == null))915                {916                    // If we are in module analysis and the parent module declares non-wildcarded ExportedCmdlets, then we don't need to917                    // actually process the binary module.918                    bool shouldLoadModule = true;919 920                    if ((parentModule != null) && !importingModule)921                    {922                        if ((parentModule.ExportedCmdlets != null) && (parentModule.ExportedCmdlets.Count > 0))923                        {924                            shouldLoadModule = false;925 926                            foreach (string exportedCmdlet in parentModule.ExportedCmdlets.Keys)927                            {928                                if (WildcardPattern.ContainsWildcardCharacters(exportedCmdlet))929                                {930                                    shouldLoadModule = true;931                                    break;932                                }933                            }934 935                            found = true;936                        }937                    }938 939                    if (shouldLoadModule)940                    {941                        try942                        {943                            // At this point, we are already exhaust all possible ways to load the nested module. The last option is to load it as a binary module/snapin.944                            module = LoadBinaryModule(945                                parentModule,946                                moduleSpecification.Name,947                                fileName: null,948                                assemblyToLoad: null,949                                moduleBase,950                                ss,951                                options,952                                manifestProcessingFlags,953                                prefix,954                                out found,955                                shortModuleName,956                                disableFormatUpdates: false);957                        }958                        catch (FileNotFoundException)959                        {960                            // Loading the nested module as a pssnapin or assembly is our last attempt to resolve the nested module.961                            // If we catch 'FileNotFoundException', it simply means that our last attempt failed because we couldn't find such a pssnapin or assembly.962                            // In this case, we can safely ignore this exception and throw a 'Modules_ModuleFileNotFound' error.963                        }964 965                        if ((module != null) && importingModule)966                        {967                            AddModuleToModuleTables(this.Context, this.TargetSessionState.Internal, module);968                        }969                    }970                }971 972                return module;973            }974            finally975            {976                BaseMinimumVersion = savedBaseMinimumVersion;977                BaseMaximumVersion = savedBaseMaximumVersion;978                BaseRequiredVersion = savedBaseRequiredVersion;979                BaseGuid = savedBaseGuid;980                this.Context.Modules.DecrementModuleNestingCount();981            }982        }983 984        internal List<PSModuleInfo> GetModule(string[] names, bool all, bool refresh)985        {986            List<PSModuleInfo> modulesToReturn = new List<PSModuleInfo>();987 988            // Two lists - one to hold Module Paths and one to hold Module Names989            // For Module Paths, we don't do any path resolution990            List<string> modulePaths = new List<string>();991            List<string> moduleNames = new List<string>();992 993            if (names != null)994            {995                foreach (var n in names)996                {997                    if (n.Contains(StringLiterals.DefaultPathSeparator) || n.Contains(StringLiterals.AlternatePathSeparator))998                    {999                        modulePaths.Add(n);1000                    }1001                    else1002                    {1003                        moduleNames.Add(n);1004                    }1005                }1006 1007                modulesToReturn.AddRange(GetModuleForRootedPaths(modulePaths, all, refresh));1008            }1009 1010            // If no names were passed to this function, then this API will return list of all available modules1011            if (names == null || moduleNames.Count > 0)1012            {1013                modulesToReturn.AddRange(GetModuleForNames(moduleNames, all, refresh));1014            }1015 1016            return modulesToReturn;1017        }1018 1019        private IEnumerable<PSModuleInfo> GetModuleForRootedPaths(List<string> modulePaths, bool all, bool refresh)1020        {1021            // This is to filter out duplicate modules1022            var modules = new HashSet<string>(StringComparer.OrdinalIgnoreCase);1023 1024            foreach (string mp in modulePaths)1025            {1026                bool containsWildCards = false;1027 1028                string modulePath = mp.TrimEnd('\\');1029 1030                // If the given path contains wildcards, we won't throw error if no match module path is found.1031                if (WildcardPattern.ContainsWildcardCharacters(modulePath))1032                {1033                    containsWildCards = true;1034                }1035 1036                // Now we resolve the possible paths in case it is relative path/path contains wildcards1037                var modulePathCollection = GetResolvedPathCollection(modulePath, this.Context);1038 1039                if (modulePathCollection != null)1040                {1041                    foreach (string resolvedModulePath in modulePathCollection)1042                    {1043                        string moduleName = Path.GetFileName(resolvedModulePath);1044 1045                        // If the given path is a valid module file, we will load the specific file1046                        if (!Directory.Exists(resolvedModulePath) && ModuleIntrinsics.IsPowerShellModuleExtension(Path.GetExtension(moduleName)))1047                        {1048                            PSModuleInfo module = CreateModuleInfoForGetModule(resolvedModulePath, refresh);1049                            if (module != null)1050                            {1051                                if (modules.Add(resolvedModulePath))1052                                {1053                                    yield return module;1054                                }1055                            }1056                        }1057                        else1058                        {1059                            // Given path is a directory, we first check if it is end with module version.1060                            Version version;1061                            if (Version.TryParse(moduleName, out version))1062                            {1063                                moduleName = Path.GetFileName(Directory.GetParent(resolvedModulePath).Name);1064                            }1065 1066                            var availableModuleFiles = all1067                                ? ModuleUtils.GetAllAvailableModuleFiles(resolvedModulePath)1068                                : ModuleUtils.GetModuleFilesFromAbsolutePath(resolvedModulePath);1069 1070                            bool foundModule = false;1071                            foreach (string file in availableModuleFiles)1072                            {1073                                PSModuleInfo module = CreateModuleInfoForGetModule(file, refresh);1074                                if (module != null)1075                                {1076                                    if (string.Equals(moduleName, module.Name, StringComparison.OrdinalIgnoreCase))1077                                    {1078                                        foundModule = true;1079                                        // We need to list all versions of the module.1080                                        string subModulePath = Path.GetDirectoryName(file);1081                                        if (modules.Add(subModulePath))1082                                        {1083                                            yield return module;1084                                        }1085                                    }1086                                }1087                            }1088 1089                            // Write error only if Name has no wild cards1090                            if (!foundModule && !containsWildCards)1091                            {1092                                WriteError(CreateModuleNotFoundError(resolvedModulePath));1093                            }1094                        }1095                    }1096                }1097                else1098                {1099                    if (!containsWildCards)1100                    {1101                        WriteError(CreateModuleNotFoundError(modulePath));1102                    }1103                }1104            }1105        }1106 1107        private static ErrorRecord CreateModuleNotFoundError(string modulePath)1108        {1109            string errorMessage = StringUtil.Format(Modules.ModuleNotFoundForGetModule, modulePath);1110            FileNotFoundException fnf = new FileNotFoundException(errorMessage);1111            ErrorRecord er = new ErrorRecord(fnf, "Modules_ModuleNotFoundForGetModule", ErrorCategory.ResourceUnavailable, modulePath);1112            return er;1113        }1114 1115        private IEnumerable<PSModuleInfo> GetModuleForNames(List<string> names, bool all, bool refresh)1116        {1117            IEnumerable<PSModuleInfo> allModules = null;1118            HashSet<string> modulePathSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);1119 1120            foreach (string path in ModuleIntrinsics.GetModulePath(false, Context))1121            {1122                string uniquePath = path.TrimEnd(Utils.Separators.Directory);1123 1124                // Ignore repeated module path.1125                if (!modulePathSet.Add(uniquePath))1126                {1127                    continue;1128                }1129 1130                try1131                {1132                    IEnumerable<PSModuleInfo> modulesFound = GetModulesFromOneModulePath(1133                        names, uniquePath, all, refresh).OrderBy(static m => m.Name);1134                    allModules = allModules == null ? modulesFound : allModules.Concat(modulesFound);1135                }1136                catch (Exception e) when (e is IOException || e is UnauthorizedAccessException)1137                {1138                    // ignore directories that can't be accessed1139                    continue;1140                }1141            }1142 1143            // Make sure we always return a non-null collection.1144            return allModules ?? Array.Empty<PSModuleInfo>();1145        }1146 1147        /// <summary>1148        /// Get modules based on the given names and module files.1149        /// </summary>1150        private IEnumerable<PSModuleInfo> GetModulesFromOneModulePath(List<string> names, string modulePath, bool all, bool refresh)1151        {1152            const WildcardOptions options = WildcardOptions.IgnoreCase | WildcardOptions.CultureInvariant;1153            IEnumerable<WildcardPattern> namePatterns = null;1154            if (names != null && names.Count > 0)1155            {1156                namePatterns = SessionStateUtilities.CreateWildcardsFromStrings(names, options);1157            }1158 1159            IEnumerable<string> moduleFiles = all1160                ? ModuleUtils.GetAllAvailableModuleFiles(modulePath)1161                : ModuleUtils.GetDefaultAvailableModuleFiles(modulePath);1162 1163            foreach (string file in moduleFiles)1164            {1165                if (namePatterns == null ||1166                    SessionStateUtilities.MatchesAnyWildcardPattern(1167                        Path.GetFileNameWithoutExtension(file), namePatterns, defaultValue: true))1168                {1169                    PSModuleInfo module = CreateModuleInfoForGetModule(file, refresh);1170                    if (module == null) { continue; }1171 1172                    if (all || !ModuleUtils.IsModuleInVersionSubdirectory(file, out Version directoryVersion) || directoryVersion == module.Version)1173                    {1174                        yield return module;1175                    }1176                }1177            }1178 1179            ClearAnalysisCaches();1180        }1181 1182        /// <summary>1183        /// Get the version type of input string MaximumVersion, translate "*" if there's any.1184        /// </summary>1185        internal static Version GetMaximumVersion(string stringVersion)1186        {1187            Version maxVersion;1188            // First, try to convert maxVersion to version directly1189            if (System.Version.TryParse(stringVersion, out maxVersion))1190            {1191                return maxVersion;1192            }1193            else1194            {1195                // If first conversion fails, try to convert * to maximum version1196                const string maxRange = "999999999";1197                if (stringVersion[stringVersion.Length - 1] == '*')1198                {1199                    stringVersion = stringVersion.Substring(0, stringVersion.Length - 1);1200                    stringVersion += maxRange;

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