/// <summary> /// Export the specified functions... /// </summary> protected override void ProcessRecord() { if (Context.EngineSessionState == Context.TopLevelSessionState) { string message = StringUtil.Format(Modules.CanOnlyBeUsedFromWithinAModule); InvalidOperationException invalidOp = new InvalidOperationException(message); ErrorRecord er = new ErrorRecord(invalidOp, "Modules_CanOnlyExecuteExportModuleMemberInsideAModule", ErrorCategory.PermissionDenied, null); ThrowTerminatingError(er); } // Prevent script injection attack by disallowing ExportModuleMemberCommand to export module members across // language boundaries. This will prevent injected untrusted script from exporting private trusted module functions. if (Context.EngineSessionState.Module?.LanguageMode != null && Context.LanguageMode != Context.EngineSessionState.Module.LanguageMode) { var se = new PSSecurityException(Modules.CannotExportMembersAccrossLanguageBoundaries); var er = new ErrorRecord(se, "Modules_CannotExportMembersAccrossLanguageBoundaries", ErrorCategory.SecurityError, this); ThrowTerminatingError(er); } ModuleIntrinsics.ExportModuleMembers(this, this.Context.EngineSessionState, _functionPatterns, _cmdletPatterns, _aliasPatterns, _variablePatterns, null); }
internal static List <string> GetDefaultAvailableModuleFiles(bool force, bool preferSystemModulePath, System.Management.Automation.ExecutionContext context) { Pipeline currentlyRunningPipeline = context.CurrentRunspace.GetCurrentlyRunningPipeline(); if (!force && (currentlyRunningPipeline != null)) { lock (cachedAvailableModuleFiles) { if ((currentlyRunningPipeline.InstanceId == pipelineInstanceIdForModuleFileCache) && (cachedAvailableModuleFiles.Count > 0)) { return(cachedAvailableModuleFiles); } } } List <string> availableModuleFiles = new List <string>(); List <string> modulePaths = new List <string>(); foreach (string str in ModuleIntrinsics.GetModulePath(preferSystemModulePath, context)) { if (Directory.Exists(str)) { GetDefaultAvailableModuleFiles(str, availableModuleFiles, modulePaths); } } if (currentlyRunningPipeline != null) { lock (cachedAvailableModuleFiles) { pipelineInstanceIdForModuleFileCache = currentlyRunningPipeline.InstanceId; cachedAvailableModuleFiles = availableModuleFiles; } } return(availableModuleFiles); }
/// <summary> /// Take an enumeration of modules and only return those that match a specification /// in the given specification table, or have no corresponding entry in the specification table. /// </summary> /// <param name="modules">The modules to filter by specification match.</param> /// <param name="moduleSpecificationTable">The specification lookup table to filter the modules on.</param> /// <returns>The modules that match their corresponding table entry, or which have no table entry.</returns> private static IEnumerable <PSModuleInfo> FilterModulesForSpecificationMatch( IEnumerable <PSModuleInfo> modules, IDictionary <string, ModuleSpecification> moduleSpecificationTable) { Dbg.Assert(moduleSpecificationTable != null, $"Caller to verify that {nameof(moduleSpecificationTable)} is not null"); Dbg.Assert(moduleSpecificationTable.Count != 0, $"Caller to verify that {nameof(moduleSpecificationTable)} is not empty"); foreach (PSModuleInfo module in modules) { // TODO: // moduleSpecification.Name may be a path and will not match module.Name when they refer to the same module. // This actually causes the module to be returned always, so other specification checks are skipped erroneously. // Instead we need to be able to look up or match modules by path as well (e.g. a new comparer for PSModuleInfo). // No table entry means we return the module if (!moduleSpecificationTable.TryGetValue(module.Name, out ModuleSpecification moduleSpecification)) { yield return(module); continue; } // Modules with table entries only get returned if they match them if (ModuleIntrinsics.IsModuleMatchingModuleSpec(module, moduleSpecification)) { yield return(module); } } }
/// <summary> /// Get valid module files from module paths. /// </summary> private IEnumerable <string> GetValidModuleFiles(HashSet <string> moduleNamesToFind) { var modulePaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase); foreach (string path in ModuleIntrinsics.GetModulePath(includeSystemModulePath: false, Context)) { string uniquePath = path.TrimEnd(Utils.Separators.Directory); if (!modulePaths.Add(uniquePath)) { continue; } foreach (string moduleFile in ModuleUtils.GetDefaultAvailableModuleFiles(uniquePath)) { // We only care about module manifest files because that's where experimental features are declared. if (!moduleFile.EndsWith(StringLiterals.PowerShellDataFileExtension, StringComparison.OrdinalIgnoreCase)) { continue; } if (moduleNamesToFind != null) { string currentModuleName = ModuleIntrinsics.GetModuleName(moduleFile); if (!moduleNamesToFind.Contains(currentModuleName)) { continue; } } yield return(moduleFile); } } }
/// <summary> /// Get a list of module files from the given directory without recursively searching all sub-directories. /// This method assumes the given directory is a module folder or a version sub-directory of a module folder. /// </summary> internal static List <string> GetModuleFilesFromAbsolutePath(string directory) { List <string> result = new List <string>(); string fileName = Path.GetFileName(directory); // If the given directory doesn't exist or it's the root folder, then return an empty list. if (!Directory.Exists(directory) || string.IsNullOrEmpty(fileName)) { return(result); } // If the user give the module path including version, the module name could be the parent folder name. if (Version.TryParse(fileName, out Version ver)) { string parentDirPath = Path.GetDirectoryName(directory); string parentDirName = Path.GetFileName(parentDirPath); // If the parent directory is NOT a root folder, then it could be the module folder. if (!string.IsNullOrEmpty(parentDirName)) { string manifestPath = Path.Combine(directory, parentDirName); manifestPath += StringLiterals.PowerShellDataFileExtension; if (File.Exists(manifestPath) && ver.Equals(ModuleIntrinsics.GetManifestModuleVersion(manifestPath))) { result.Add(manifestPath); return(result); } } } // If we reach here, then use the given directory as the module folder. foreach (Version version in GetModuleVersionSubfolders(directory)) { string manifestPath = Path.Combine(directory, version.ToString(), fileName); manifestPath += StringLiterals.PowerShellDataFileExtension; if (File.Exists(manifestPath) && version.Equals(ModuleIntrinsics.GetManifestModuleVersion(manifestPath))) { result.Add(manifestPath); } } foreach (string ext in ModuleIntrinsics.PSModuleExtensions) { string moduleFile = Path.Combine(directory, fileName) + ext; if (File.Exists(moduleFile)) { result.Add(moduleFile); // when finding the default modules we stop when the first // match is hit - searching in order .psd1, .psm1, .dll, // if a file is found but is not readable then it is an error. break; } } return(result); }
private void ImportSystemModules() { this._initialSessionState.ImportPSModulesFromPath(ModuleIntrinsics.GetSystemwideModulePath()); string localModulePath = Environment.GetEnvironmentVariable("PSMODULEPATH"); if (!string.IsNullOrEmpty(localModulePath)) { this._initialSessionState.ImportPSModulesFromPath(localModulePath); } }
protected override void ProcessRecord() { if (base.Context.EngineSessionState == base.Context.TopLevelSessionState) { InvalidOperationException exception = new InvalidOperationException(StringUtil.Format(Modules.CanOnlyBeUsedFromWithinAModule, new object[0])); ErrorRecord errorRecord = new ErrorRecord(exception, "Modules_CanOnlyExecuteExportModuleMemberInsideAModule", ErrorCategory.PermissionDenied, null); base.ThrowTerminatingError(errorRecord); } ModuleIntrinsics.ExportModuleMembers(this, base.Context.EngineSessionState, this._functionPatterns, this._cmdletPatterns, this._aliasPatterns, this._variablePatterns, null); }
internal static bool IsOnSystem32ModulePath(string path) { #if UNIX return(false); #else Dbg.Assert(!string.IsNullOrEmpty(path), $"Caller to verify that {nameof(path)} is not null or empty"); string windowsPowerShellPSHomePath = ModuleIntrinsics.GetWindowsPowerShellPSHomeModulePath(); return(path.StartsWith(windowsPowerShellPSHomePath, StringComparison.OrdinalIgnoreCase)); #endif }
protected override void EndProcessing() { if (this._scriptBlock != null) { string path = Guid.NewGuid().ToString(); if (string.IsNullOrEmpty(this._name)) { this._name = "__DynamicModule_" + path; } try { base.Context.Modules.IncrementModuleNestingDepth(this, this._name); ArrayList results = null; PSModuleInfo sourceModule = null; try { sourceModule = base.Context.Modules.CreateModule(this._name, path, this._scriptBlock, null, out results, this._arguments); if (!sourceModule.SessionState.Internal.UseExportList) { List <WildcardPattern> cmdletPatterns = (base.BaseCmdletPatterns != null) ? base.BaseCmdletPatterns : base.MatchAll; List <WildcardPattern> functionPatterns = (base.BaseFunctionPatterns != null) ? base.BaseFunctionPatterns : base.MatchAll; ModuleIntrinsics.ExportModuleMembers(this, sourceModule.SessionState.Internal, functionPatterns, cmdletPatterns, base.BaseAliasPatterns, base.BaseVariablePatterns, null); } } catch (RuntimeException exception) { exception.ErrorRecord.PreserveInvocationInfoOnce = true; base.WriteError(exception.ErrorRecord); } if (sourceModule != null) { if (this._returnResult) { base.ImportModuleMembers(sourceModule, string.Empty); base.WriteObject(results, true); } else if (this._asCustomObject) { base.WriteObject(sourceModule.AsCustomObject()); } else { base.ImportModuleMembers(sourceModule, string.Empty); base.WriteObject(sourceModule); } } } finally { base.Context.Modules.DecrementModuleNestingCount(); } } }
internal static IEnumerable <string> GetDefaultAvailableModuleFiles(bool isForAutoDiscovery, ExecutionContext context) { HashSet <string> uniqueModuleFiles = new HashSet <string>(StringComparer.OrdinalIgnoreCase); foreach (string directory in ModuleIntrinsics.GetModulePath(isForAutoDiscovery, context)) { var needWriteProgressCompleted = false; ProgressRecord analysisProgress = null; // Write a progress message for UNC paths, so that users know what is happening try { if ((context.CurrentCommandProcessor != null) && Utils.PathIsUnc(directory)) { analysisProgress = new ProgressRecord(0, Modules.DeterminingAvailableModules, string.Format(CultureInfo.InvariantCulture, Modules.SearchingUncShare, directory)) { RecordType = ProgressRecordType.Processing }; context.CurrentCommandProcessor.CommandRuntime.WriteProgress(analysisProgress); needWriteProgressCompleted = true; } } catch (InvalidOperationException) { // This may be called when we are not allowed to write progress, // So eat the invalid operation } try { foreach (string moduleFile in ModuleUtils.GetDefaultAvailableModuleFiles(directory)) { if (uniqueModuleFiles.Add(moduleFile)) { yield return(moduleFile); } } } finally { if (needWriteProgressCompleted) { analysisProgress.RecordType = ProgressRecordType.Completed; context.CurrentCommandProcessor.CommandRuntime.WriteProgress(analysisProgress); } } } }
/// <summary> /// Export the specified functions... /// </summary> protected override void ProcessRecord() { if (Context.EngineSessionState == Context.TopLevelSessionState) { string message = StringUtil.Format(Modules.CanOnlyBeUsedFromWithinAModule); InvalidOperationException invalidOp = new InvalidOperationException(message); ErrorRecord er = new ErrorRecord(invalidOp, "Modules_CanOnlyExecuteExportModuleMemberInsideAModule", ErrorCategory.PermissionDenied, null); ThrowTerminatingError(er); } ModuleIntrinsics.ExportModuleMembers(this, this.Context.EngineSessionState, _functionPatterns, _cmdletPatterns, _aliasPatterns, _variablePatterns, null); }
/// <summary> /// Get enabled experimental features based on the specified name patterns. /// </summary> private IEnumerable <ExperimentalFeature> GetEnabledExperimentalFeatures(IEnumerable <WildcardPattern> namePatterns) { var moduleFeatures = new List <string>(); var moduleNames = new HashSet <string>(StringComparer.OrdinalIgnoreCase); foreach (string featureName in ExperimentalFeature.EnabledExperimentalFeatureNames) { // Only process the feature names that matches any name patterns. if (SessionStateUtilities.MatchesAnyWildcardPattern(featureName, namePatterns, defaultValue: true)) { if (ExperimentalFeature.EngineExperimentalFeatureMap.TryGetValue(featureName, out ExperimentalFeature feature)) { yield return(feature); } else { moduleFeatures.Add(featureName); int lastDotIndex = featureName.LastIndexOf('.'); moduleNames.Add(featureName.Substring(0, lastDotIndex)); } } } if (moduleFeatures.Count > 0) { var featuresFromGivenModules = new Dictionary <string, ExperimentalFeature>(StringComparer.OrdinalIgnoreCase); foreach (string moduleFile in GetValidModuleFiles(moduleNames)) { foreach (var feature in ModuleIntrinsics.GetExperimentalFeature(moduleFile)) { featuresFromGivenModules.TryAdd(feature.Name, feature); } } foreach (string featureName in moduleFeatures) { if (featuresFromGivenModules.TryGetValue(featureName, out ExperimentalFeature feature)) { yield return(feature); } else { yield return(new ExperimentalFeature(featureName, description: null, source: null, isEnabled: true)); } } } }
/// <summary> /// Copy the module specification while normalizing the name /// so that paths become absolute and use the right directory separators. /// </summary> /// <param name="context">The current execution context. Used for path normalization.</param> /// <param name="basePath">The base path where a relative path should be interpreted with respect to.</param> /// <returns>A fresh module specification object with the name normalized for use internally.</returns> internal ModuleSpecification WithNormalizedName(ExecutionContext context, string basePath) { // Save allocating a new module spec if we don't need to change anything if (!ModuleIntrinsics.IsModuleNamePath(Name)) { return(this); } return(new ModuleSpecification() { Guid = Guid, MaximumVersion = MaximumVersion, Version = Version, RequiredVersion = RequiredVersion, Name = ModuleIntrinsics.NormalizeModuleName(Name, basePath, context) }); }
internal static List <string> GetModuleVersionsFromAbsolutePath(string directory) { List <string> result = new List <string>(); string fileName = Path.GetFileName(directory); Version moduleVersion; // if the user give the module path including version, we should be able to find the module as well if (Version.TryParse(fileName, out moduleVersion) && Directory.Exists(Directory.GetParent(directory).ToString())) { fileName = Directory.GetParent(directory).Name; } foreach (var version in GetModuleVersionSubfolders(directory)) { var qualifiedPathWithVersion = Path.Combine(directory, Path.Combine(version.ToString(), fileName)); string manifestPath = qualifiedPathWithVersion + StringLiterals.PowerShellDataFileExtension; if (File.Exists(manifestPath)) { bool isValidModuleVersion = version.Equals(ModuleIntrinsics.GetManifestModuleVersion(manifestPath)); if (isValidModuleVersion) { result.Add(manifestPath); } } } foreach (string ext in ModuleIntrinsics.PSModuleExtensions) { string moduleFile = Path.Combine(directory, fileName) + ext; if (!Utils.NativeFileExists(moduleFile)) { continue; } result.Add(moduleFile); // when finding the default modules we stop when the first // match is hit - searching in order .psd1, .psm1, .dll // if a file is found but is not readable then it is an // error break; } return(result); }
/// <summary> /// Get available experimental features based on the specified name patterns. /// </summary> internal IEnumerable <ExperimentalFeature> GetAvailableExperimentalFeatures(IEnumerable <WildcardPattern> namePatterns) { foreach (ExperimentalFeature feature in ExperimentalFeature.EngineExperimentalFeatures) { if (SessionStateUtilities.MatchesAnyWildcardPattern(feature.Name, namePatterns, defaultValue: true)) { yield return(feature); } } foreach (string moduleFile in GetValidModuleFiles(moduleNamesToFind: null)) { ExperimentalFeature[] features = ModuleIntrinsics.GetExperimentalFeature(moduleFile); foreach (var feature in features) { if (SessionStateUtilities.MatchesAnyWildcardPattern(feature.Name, namePatterns, defaultValue: true)) { yield return(feature); } } } }
/// <summary> /// Take an enumeration of modules and only return those that match a specification /// in the given specification table, or have no corresponding entry in the specification table. /// </summary> /// <param name="modules">The modules to filter by specification match.</param> /// <param name="moduleSpecificationTable">The specification lookup table to filter the modules on.</param> /// <returns>The modules that match their corresponding table entry, or which have no table entry.</returns> private static IEnumerable <PSModuleInfo> FilterModulesForSpecificationMatch( IEnumerable <PSModuleInfo> modules, IDictionary <string, ModuleSpecification> moduleSpecificationTable) { Dbg.Assert(moduleSpecificationTable != null, $"Caller to verify that {nameof(moduleSpecificationTable)} is not null"); Dbg.Assert(moduleSpecificationTable.Count != 0, $"Caller to verify that {nameof(moduleSpecificationTable)} is not empty"); foreach (PSModuleInfo module in modules) { IEnumerable <ModuleSpecification> candidateModuleSpecs = GetCandidateModuleSpecs(moduleSpecificationTable, module); // Modules with table entries only get returned if they match them // We skip the name check since modules have already been prefiltered base on the moduleSpec path/name foreach (ModuleSpecification moduleSpec in candidateModuleSpecs) { if (ModuleIntrinsics.IsModuleMatchingModuleSpec(module, moduleSpec, skipNameCheck: true)) { yield return(module); } } } }
/// <summary> /// Take an enumeration of modules and only return those that match a specification /// in the given specification table, or have no corresponding entry in the specification table. /// </summary> /// <param name="modules">The modules to filter by specification match.</param> /// <param name="moduleSpecificationTable">The specification lookup table to filter the modules on.</param> /// <returns>The modules that match their corresponding table entry, or which have no table entry.</returns> private static IEnumerable <PSModuleInfo> FilterModulesForSpecificationMatch( IEnumerable <PSModuleInfo> modules, IDictionary <string, ModuleSpecification> moduleSpecificationTable) { Dbg.Assert(moduleSpecificationTable != null, $"Caller to verify that {nameof(moduleSpecificationTable)} is not null"); Dbg.Assert(moduleSpecificationTable.Count != 0, $"Caller to verify that {nameof(moduleSpecificationTable)} is not empty"); foreach (PSModuleInfo module in modules) { // No table entry means we return the module if (!moduleSpecificationTable.TryGetValue(module.Name, out ModuleSpecification moduleSpecification)) { yield return(module); continue; } // Modules with table entries only get returned if they match them if (ModuleIntrinsics.IsModuleMatchingModuleSpec(module, moduleSpecification)) { yield return(module); } } }
/// <summary> /// Create the new module... /// </summary> protected override void EndProcessing() { // Create a module from a scriptblock... if (_scriptBlock != null) { string gs = System.Guid.NewGuid().ToString(); if (String.IsNullOrEmpty(_name)) { _name = PSModuleInfo.DynamicModulePrefixString + gs; } try { Context.Modules.IncrementModuleNestingDepth(this, _name); List <object> results = null; PSModuleInfo localModule = null; try { // The path for a "dynamic" module will be a GUID so it's unique. localModule = Context.Modules.CreateModule(_name, gs, _scriptBlock, null, out results, _arguments); // Export all functions and variables if no exports were specified... if (!localModule.SessionState.Internal.UseExportList) { List <WildcardPattern> cmdletPatterns = BaseCmdletPatterns ?? MatchAll; List <WildcardPattern> functionPatterns = BaseFunctionPatterns ?? MatchAll; ModuleIntrinsics.ExportModuleMembers(this, localModule.SessionState.Internal, functionPatterns, cmdletPatterns, BaseAliasPatterns, BaseVariablePatterns, null); } } catch (RuntimeException e) { // Preserve the inner module invocation info... e.ErrorRecord.PreserveInvocationInfoOnce = true; WriteError(e.ErrorRecord); } // If the module was created successfully, then process the result... if (localModule != null) { if (_returnResult) { // import the specified members... ImportModuleMembers(localModule, string.Empty /* no -Prefix for New-Module cmdlet */); WriteObject(results, true); } else if (_asCustomObject) { WriteObject(localModule.AsCustomObject()); } else { // import the specified members... ImportModuleMembers(localModule, string.Empty /* no -Prefix for New-Module cmdlet */); WriteObject(localModule); } } } finally { Context.Modules.DecrementModuleNestingCount(); } return; } }
/// <summary> /// Gets a list of matching commands. /// </summary> /// <param name="pattern">Command pattern.</param> /// <param name="context">Execution context.</param> /// <param name="commandOrigin">Command origin.</param> /// <param name="rediscoverImportedModules">If true, rediscovers imported modules.</param> /// <param name="moduleVersionRequired">Specific module version to be required.</param> /// <param name="useFuzzyMatching">Use fuzzy matching.</param> /// <param name="useAbbreviationExpansion">Use abbreviation expansion for matching.</param> /// <returns>Returns matching CommandInfo IEnumerable.</returns> internal static IEnumerable <CommandInfo> GetMatchingCommands(string pattern, ExecutionContext context, CommandOrigin commandOrigin, bool rediscoverImportedModules = false, bool moduleVersionRequired = false, bool useFuzzyMatching = false, bool useAbbreviationExpansion = false) { // Otherwise, if it had wildcards, just return the "AvailableCommand" // type of command info. WildcardPattern commandPattern = WildcardPattern.Get(pattern, WildcardOptions.IgnoreCase); CmdletInfo cmdletInfo = context.SessionState.InvokeCommand.GetCmdlet("Microsoft.PowerShell.Core\\Get-Module"); PSModuleAutoLoadingPreference moduleAutoLoadingPreference = CommandDiscovery.GetCommandDiscoveryPreference(context, SpecialVariables.PSModuleAutoLoadingPreferenceVarPath, "PSModuleAutoLoadingPreference"); if ((moduleAutoLoadingPreference != PSModuleAutoLoadingPreference.None) && ((commandOrigin == CommandOrigin.Internal) || ((cmdletInfo != null) && (cmdletInfo.Visibility == SessionStateEntryVisibility.Public)))) { foreach (string modulePath in GetDefaultAvailableModuleFiles(isForAutoDiscovery: false, context)) { // Skip modules that have already been loaded so that we don't expose private commands. string moduleName = Path.GetFileNameWithoutExtension(modulePath); List <PSModuleInfo> modules = context.Modules.GetExactMatchModules(moduleName, all: false, exactMatch: true); PSModuleInfo tempModuleInfo = null; if (modules.Count != 0) { // 1. We continue to the next module path if we don't want to re-discover those imported modules // 2. If we want to re-discover the imported modules, but one or more commands from the module were made private, // then we don't do re-discovery if (!rediscoverImportedModules || modules.Exists(module => module.ModuleHasPrivateMembers)) { continue; } if (modules.Count == 1) { PSModuleInfo psModule = modules[0]; tempModuleInfo = new PSModuleInfo(psModule.Name, psModule.Path, context: null, sessionState: null); tempModuleInfo.SetModuleBase(psModule.ModuleBase); foreach (KeyValuePair <string, CommandInfo> entry in psModule.ExportedCommands) { if (commandPattern.IsMatch(entry.Value.Name) || (useFuzzyMatching && FuzzyMatcher.IsFuzzyMatch(entry.Value.Name, pattern)) || (useAbbreviationExpansion && string.Equals(pattern, AbbreviateName(entry.Value.Name), StringComparison.OrdinalIgnoreCase))) { CommandInfo current = null; switch (entry.Value.CommandType) { case CommandTypes.Alias: current = new AliasInfo(entry.Value.Name, definition: null, context); break; case CommandTypes.Function: current = new FunctionInfo(entry.Value.Name, ScriptBlock.EmptyScriptBlock, context); break; case CommandTypes.Filter: current = new FilterInfo(entry.Value.Name, ScriptBlock.EmptyScriptBlock, context); break; case CommandTypes.Configuration: current = new ConfigurationInfo(entry.Value.Name, ScriptBlock.EmptyScriptBlock, context); break; case CommandTypes.Cmdlet: current = new CmdletInfo(entry.Value.Name, implementingType: null, helpFile: null, PSSnapin: null, context); break; default: Dbg.Assert(false, "cannot be hit"); break; } current.Module = tempModuleInfo; yield return(current); } } continue; } } string moduleShortName = Path.GetFileNameWithoutExtension(modulePath); IDictionary <string, CommandTypes> exportedCommands = AnalysisCache.GetExportedCommands(modulePath, testOnly: false, context); if (exportedCommands == null) { continue; } tempModuleInfo = new PSModuleInfo(moduleShortName, modulePath, sessionState: null, context: null); if (InitialSessionState.IsEngineModule(moduleShortName)) { tempModuleInfo.SetModuleBase(Utils.DefaultPowerShellAppBase); } // moduleVersionRequired is bypassed by FullyQualifiedModule from calling method. This is the only place where guid will be involved. if (moduleVersionRequired && modulePath.EndsWith(StringLiterals.PowerShellDataFileExtension, StringComparison.OrdinalIgnoreCase)) { tempModuleInfo.SetVersion(ModuleIntrinsics.GetManifestModuleVersion(modulePath)); tempModuleInfo.SetGuid(ModuleIntrinsics.GetManifestGuid(modulePath)); } foreach (KeyValuePair <string, CommandTypes> pair in exportedCommands) { string commandName = pair.Key; CommandTypes commandTypes = pair.Value; if (commandPattern.IsMatch(commandName) || (useFuzzyMatching && FuzzyMatcher.IsFuzzyMatch(commandName, pattern)) || (useAbbreviationExpansion && string.Equals(pattern, AbbreviateName(commandName), StringComparison.OrdinalIgnoreCase))) { bool shouldExportCommand = true; // Verify that we don't already have it represented in the initial session state. if ((context.InitialSessionState != null) && (commandOrigin == CommandOrigin.Runspace)) { foreach (SessionStateCommandEntry commandEntry in context.InitialSessionState.Commands[commandName]) { string moduleCompareName = null; if (commandEntry.Module != null) { moduleCompareName = commandEntry.Module.Name; } else if (commandEntry.PSSnapIn != null) { moduleCompareName = commandEntry.PSSnapIn.Name; } if (string.Equals(moduleShortName, moduleCompareName, StringComparison.OrdinalIgnoreCase)) { if (commandEntry.Visibility == SessionStateEntryVisibility.Private) { shouldExportCommand = false; } } } } if (shouldExportCommand) { if ((commandTypes & CommandTypes.Alias) == CommandTypes.Alias) { yield return(new AliasInfo(commandName, null, context) { Module = tempModuleInfo }); } if ((commandTypes & CommandTypes.Cmdlet) == CommandTypes.Cmdlet) { yield return(new CmdletInfo(commandName, implementingType: null, helpFile: null, PSSnapin: null, context: context) { Module = tempModuleInfo }); } if ((commandTypes & CommandTypes.Function) == CommandTypes.Function) { yield return(new FunctionInfo(commandName, ScriptBlock.EmptyScriptBlock, context) { Module = tempModuleInfo }); } if ((commandTypes & CommandTypes.Configuration) == CommandTypes.Configuration) { yield return(new ConfigurationInfo(commandName, ScriptBlock.EmptyScriptBlock, context) { Module = tempModuleInfo }); } } } } } } }
/// <summary> /// Determine whether a module info matches a given module specification table and specified PSEdition value. /// </summary> /// <param name="moduleInfo"></param> /// <param name="moduleSpecTable"></param> /// <param name="edition"></param> /// <returns></returns> private static bool ModuleMatch(PSModuleInfo moduleInfo, IDictionary<string, ModuleSpecification> moduleSpecTable, string edition) { ModuleSpecification moduleSpecification; return (String.IsNullOrEmpty(edition) || moduleInfo.CompatiblePSEditions.Contains(edition, StringComparer.OrdinalIgnoreCase)) && (!moduleSpecTable.TryGetValue(moduleInfo.Name, out moduleSpecification) || ModuleIntrinsics.IsModuleMatchingModuleSpec(moduleInfo, moduleSpecification)); }
/// <summary> /// Initializes a new instance of the <see cref="PowerShellProcessInstance"/> class. Initializes the underlying dotnet process class. /// </summary> /// <param name="powerShellVersion">Specifies the version of powershell.</param> /// <param name="credential">Specifies a user account credentials.</param> /// <param name="initializationScript">Specifies a script that will be executed when the powershell process is initialized.</param> /// <param name="useWow64">Specifies if the powershell process will be 32-bit.</param> /// <param name="workingDirectory">Specifies the initial working directory for the new powershell process.</param> public PowerShellProcessInstance(Version powerShellVersion, PSCredential credential, ScriptBlock initializationScript, bool useWow64, string workingDirectory) { string exePath = PwshExePath; bool startingWindowsPowerShell51 = false; #if !UNIX // if requested PS version was "5.1" then we start Windows PS instead of PS Core startingWindowsPowerShell51 = (powerShellVersion != null) && (powerShellVersion.Major == 5) && (powerShellVersion.Minor == 1); if (startingWindowsPowerShell51) { if (WinPwshExePath is null) { throw new PSInvalidOperationException(RemotingErrorIdStrings.WindowsPowerShellNotPresent); } exePath = WinPwshExePath; if (useWow64) { string procArch = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"); if ((!string.IsNullOrEmpty(procArch)) && (procArch.Equals("amd64", StringComparison.OrdinalIgnoreCase) || procArch.Equals("ia64", StringComparison.OrdinalIgnoreCase))) { exePath = WinPwshExePath.ToLowerInvariant().Replace("\\system32\\", "\\syswow64\\"); if (!File.Exists(exePath)) { string message = PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.WowComponentNotPresent, exePath); throw new PSInvalidOperationException(message); } } } } #endif // 'WindowStyle' is used only if 'UseShellExecute' is 'true'. Since 'UseShellExecute' is set // to 'false' in our use, we can ignore the 'WindowStyle' setting in the initialization below. _startInfo = new ProcessStartInfo { FileName = exePath, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, #if !UNIX LoadUserProfile = true, #endif }; #if !UNIX if (startingWindowsPowerShell51) { _startInfo.ArgumentList.Add("-Version"); _startInfo.ArgumentList.Add("5.1"); // if starting Windows PowerShell, need to remove PowerShell specific segments of PSModulePath _startInfo.Environment["PSModulePath"] = ModuleIntrinsics.GetWindowsPowerShellModulePath(); } #endif _startInfo.ArgumentList.Add("-s"); _startInfo.ArgumentList.Add("-NoLogo"); _startInfo.ArgumentList.Add("-NoProfile"); if (!string.IsNullOrWhiteSpace(workingDirectory) && !startingWindowsPowerShell51) { _startInfo.ArgumentList.Add("-wd"); _startInfo.ArgumentList.Add(workingDirectory); } if (initializationScript != null) { var scriptBlockString = initializationScript.ToString(); if (!string.IsNullOrEmpty(scriptBlockString)) { var encodedCommand = Convert.ToBase64String(Encoding.Unicode.GetBytes(scriptBlockString)); _startInfo.ArgumentList.Add("-EncodedCommand"); _startInfo.ArgumentList.Add(encodedCommand); } } if (credential != null) { Net.NetworkCredential netCredential = credential.GetNetworkCredential(); _startInfo.UserName = netCredential.UserName; _startInfo.Domain = string.IsNullOrEmpty(netCredential.Domain) ? "." : netCredential.Domain; _startInfo.Password = credential.Password; } Process = new Process { StartInfo = _startInfo, EnableRaisingEvents = true }; }
/// <summary> /// Create the new module... /// </summary> protected override void EndProcessing() { // Create a module from a scriptblock... if (_scriptBlock != null) { // Check ScriptBlock language mode. If it is different than the context language mode // then throw error since private trusted script functions may be exposed. if (Context.LanguageMode == PSLanguageMode.ConstrainedLanguage && _scriptBlock.LanguageMode == PSLanguageMode.FullLanguage) { this.ThrowTerminatingError( new ErrorRecord( new PSSecurityException(Modules.CannotCreateModuleWithScriptBlock), "Modules_CannotCreateModuleWithFullLanguageScriptBlock", ErrorCategory.SecurityError, null)); } string gs = System.Guid.NewGuid().ToString(); if (string.IsNullOrEmpty(_name)) { _name = PSModuleInfo.DynamicModulePrefixString + gs; } try { Context.Modules.IncrementModuleNestingDepth(this, _name); List <object> results = null; PSModuleInfo localModule = null; try { // The path for a "dynamic" module will be a GUID so it's unique. localModule = Context.Modules.CreateModule(_name, gs, _scriptBlock, null, out results, _arguments); // Export all functions and variables if no exports were specified... if (!localModule.SessionState.Internal.UseExportList) { List <WildcardPattern> cmdletPatterns = BaseCmdletPatterns ?? MatchAll; List <WildcardPattern> functionPatterns = BaseFunctionPatterns ?? MatchAll; ModuleIntrinsics.ExportModuleMembers(this, localModule.SessionState.Internal, functionPatterns, cmdletPatterns, BaseAliasPatterns, BaseVariablePatterns, null); } } catch (RuntimeException e) { // Preserve the inner module invocation info... e.ErrorRecord.PreserveInvocationInfoOnce = true; WriteError(e.ErrorRecord); } // If the module was created successfully, then process the result... if (localModule != null) { if (_returnResult) { // import the specified members... ImportModuleMembers(localModule, string.Empty /* no -Prefix for New-Module cmdlet */); WriteObject(results, true); } else if (_asCustomObject) { WriteObject(localModule.AsCustomObject()); } else { // import the specified members... ImportModuleMembers(localModule, string.Empty /* no -Prefix for New-Module cmdlet */); WriteObject(localModule); } } } finally { Context.Modules.DecrementModuleNestingCount(); } return; } }
private void DoOpenHelper() { if (this._disposed) { throw PSTraceSource.NewObjectDisposedException("runspace"); } bool startLifeCycleEventWritten = false; runspaceInitTracer.WriteLine("begin open runspace", new object[0]); try { if (this.InitialSessionState != null) { this._engine = new AutomationEngine(base.Host, null, this.InitialSessionState); } else { this._engine = new AutomationEngine(base.Host, this.RunspaceConfiguration, null); } this._engine.Context.CurrentRunspace = this; MshLog.LogEngineLifecycleEvent(this._engine.Context, EngineState.Available); startLifeCycleEventWritten = true; this._commandFactory = new System.Management.Automation.CommandFactory(this._engine.Context); this._history = new Microsoft.PowerShell.Commands.History(this._engine.Context); this._jobRepository = new System.Management.Automation.JobRepository(); this._jobManager = new System.Management.Automation.JobManager(); this._runspaceRepository = new System.Management.Automation.RunspaceRepository(); runspaceInitTracer.WriteLine("initializing built-in aliases and variable information", new object[0]); this.InitializeDefaults(); } catch (Exception exception) { CommandProcessorBase.CheckForSevereException(exception); runspaceInitTracer.WriteLine("Runspace open failed", new object[0]); this.LogEngineHealthEvent(exception); if (startLifeCycleEventWritten) { MshLog.LogEngineLifecycleEvent(this._engine.Context, EngineState.Stopped); } base.SetRunspaceState(RunspaceState.Broken, exception); base.RaiseRunspaceStateEvents(); throw; } base.SetRunspaceState(RunspaceState.Opened); base.RunspaceOpening.Set(); base.RaiseRunspaceStateEvents(); runspaceInitTracer.WriteLine("runspace opened successfully", new object[0]); string environmentVariable = Environment.GetEnvironmentVariable("PSMODULEPATH"); if (this.InitialSessionState != null) { try { Environment.SetEnvironmentVariable("PSMODULEPATH", ModuleIntrinsics.GetSystemwideModulePath()); this.ProcessImportModule(this.InitialSessionState.CoreModulesToImport, startLifeCycleEventWritten); this._engine.Context.EngineSessionState.Module = null; } finally { Environment.SetEnvironmentVariable("PSMODULEPATH", environmentVariable); } this.ProcessImportModule(this.InitialSessionState.ModuleSpecificationsToImport, startLifeCycleEventWritten); InitialSessionState.SetSessionStateDrive(this._engine.Context, true); if (this.InitialSessionState.WarmUpTabCompletionOnIdle) { ScriptBlock action = ScriptBlock.Create("$null = [System.Management.Automation.CommandCompletion]::CompleteInput('Set-Location', 12, $null)"); this._engine.Context.Events.SubscribeEvent(null, null, "PowerShell.OnIdle", null, action, true, false, 1); } } }