private PSModuleInfo ImportModule_RemotelyViaPsrpSession_SinglePreimportedModule( ImportModuleOptions importModuleOptions, string remoteModuleName, Version remoteModuleVersion, PSSession psSession) { string temporaryModulePath = RemoteDiscoveryHelper.GetModulePath( remoteModuleName, remoteModuleVersion, psSession.ComputerName, this.Context.CurrentRunspace); string wildcardEscapedPath = WildcardPattern.Escape(temporaryModulePath); try { // // avoid importing a module twice // string localPsm1File = Path.Combine(temporaryModulePath, Path.GetFileName(temporaryModulePath) + ".psm1"); PSModuleInfo alreadyImportedModule = this.IsModuleImportUnnecessaryBecauseModuleIsAlreadyLoaded( localPsm1File, this.BasePrefix, importModuleOptions); if (alreadyImportedModule != null) { return alreadyImportedModule; } // // create proxy module in a temporary folder // using (var powerShell = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace)) { powerShell.AddCommand("Export-PSSession"); powerShell.AddParameter("OutputModule", wildcardEscapedPath); powerShell.AddParameter("AllowClobber", true); powerShell.AddParameter("Module", remoteModuleName); // remoteModulePath is currently unsupported by Get-Command and implicit remoting powerShell.AddParameter("Force", true); powerShell.AddParameter("FormatTypeName", "*"); powerShell.AddParameter("Session", psSession); string errorMessageTemplate = string.Format( CultureInfo.InvariantCulture, Modules.RemoteDiscoveryFailedToGenerateProxyForRemoteModule, remoteModuleName); int numberOfLocallyCreatedFiles = RemoteDiscoveryHelper.InvokePowerShell(powerShell, this.CancellationToken, this, errorMessageTemplate).Count(); if (numberOfLocallyCreatedFiles == 0) { return null; } } // // rename the psd1 file // string localPsd1File = Path.Combine(temporaryModulePath, remoteModuleName + ".psd1"); if (File.Exists(localPsd1File)) { File.Delete(localPsd1File); } File.Move( sourceFileName: Path.Combine(temporaryModulePath, Path.GetFileName(temporaryModulePath) + ".psd1"), destFileName: localPsd1File); string wildcardEscapedPsd1Path = WildcardPattern.Escape(localPsd1File); // // import the proxy module just as any other local module // object[] oldArgumentList = this.ArgumentList; try { this.ArgumentList = new object[] { psSession }; ImportModule_LocallyViaName(importModuleOptions, wildcardEscapedPsd1Path); } finally { this.ArgumentList = oldArgumentList; } // // make sure the temporary folder gets removed when the module is removed // PSModuleInfo moduleInfo; string psm1Path = Path.Combine(temporaryModulePath, Path.GetFileName(temporaryModulePath) + ".psm1"); if (!this.Context.Modules.ModuleTable.TryGetValue(psm1Path, out moduleInfo)) { if (Directory.Exists(temporaryModulePath)) { Directory.Delete(temporaryModulePath, recursive: true); } return null; } const string onRemoveScriptBody = @" Microsoft.PowerShell.Management\Remove-Item ` -LiteralPath $temporaryModulePath ` -Force ` -Recurse ` -ErrorAction SilentlyContinue if ($previousOnRemoveScript -ne $null) { & $previousOnRemoveScript $args } "; ScriptBlock onRemoveScriptBlock = this.Context.Engine.ParseScriptBlock(onRemoveScriptBody, false); onRemoveScriptBlock = onRemoveScriptBlock.GetNewClosure(); // create a separate scope for variables set below onRemoveScriptBlock.Module.SessionState.PSVariable.Set("temporaryModulePath", temporaryModulePath); onRemoveScriptBlock.Module.SessionState.PSVariable.Set("previousOnRemoveScript", moduleInfo.OnRemove); moduleInfo.OnRemove = onRemoveScriptBlock; return moduleInfo; } catch { if (Directory.Exists(temporaryModulePath)) { Directory.Delete(temporaryModulePath, recursive: true); } throw; } }
private PSModuleInfo ConvertCimModuleInfoToPSModuleInfo(RemoteDiscoveryHelper.CimModule cimModule, string computerName) { try { bool containedErrors = false; if (cimModule.MainManifest == null) { return(GetModuleInfoForRemoteModuleWithoutManifest(cimModule)); } string temporaryModuleManifestPath = Path.Combine( RemoteDiscoveryHelper.GetModulePath(cimModule.ModuleName, null, computerName, this.Context.CurrentRunspace), Path.GetFileName(cimModule.ModuleName)); Hashtable mainData = null; if (!containedErrors) { mainData = RemoteDiscoveryHelper.ConvertCimModuleFileToManifestHashtable( cimModule.MainManifest, temporaryModuleManifestPath, this, ref containedErrors); if (mainData == null) { return(GetModuleInfoForRemoteModuleWithoutManifest(cimModule)); } } if (!containedErrors) { mainData = RemoteDiscoveryHelper.RewriteManifest(mainData); } Hashtable localizedData = mainData; // TODO/FIXME - this needs full path support from the provider PSModuleInfo moduleInfo = null; if (!containedErrors) { ImportModuleOptions throwAwayOptions = new ImportModuleOptions(); moduleInfo = LoadModuleManifest( temporaryModuleManifestPath, null, // scriptInfo mainData, localizedData, 0 /* - don't write errors, don't load elements, don't return null on first error */, this.BaseMinimumVersion, this.BaseMaximumVersion, this.BaseRequiredVersion, this.BaseGuid, ref throwAwayOptions, ref containedErrors); } if ((moduleInfo == null) || containedErrors) { moduleInfo = GetModuleInfoForRemoteModuleWithoutManifest(cimModule); } return(moduleInfo); } catch (Exception e) { ErrorRecord errorRecord = RemoteDiscoveryHelper.GetErrorRecordForProcessingOfCimModule(e, cimModule.ModuleName); this.WriteError(errorRecord); return(null); } }
private IList<PSModuleInfo> ImportModule_RemotelyViaPsrpSession( ImportModuleOptions importModuleOptions, IEnumerable<string> moduleNames, IEnumerable<ModuleSpecification> fullyQualifiedNames, PSSession psSession) { var remotelyImportedModules = new List<PSModuleInfo>(); if (moduleNames != null) { foreach (string moduleName in moduleNames) { var tmp = ImportModule_RemotelyViaPsrpSession(importModuleOptions, moduleName, null, psSession); remotelyImportedModules.AddRange(tmp); } } if (fullyQualifiedNames != null) { foreach (var fullyQualifiedName in fullyQualifiedNames) { var tmp = ImportModule_RemotelyViaPsrpSession(importModuleOptions, null, fullyQualifiedName, psSession); remotelyImportedModules.AddRange(tmp); } } return remotelyImportedModules; }
private IList<PSModuleInfo> ImportModule_RemotelyViaPsrpSession( ImportModuleOptions importModuleOptions, string moduleName, ModuleSpecification fullyQualifiedName, PSSession psSession) { // // import the module in the remote session first // List<PSObject> remotelyImportedModules; using (var powerShell = System.Management.Automation.PowerShell.Create()) { powerShell.Runspace = psSession.Runspace; powerShell.AddCommand("Import-Module"); powerShell.AddParameter("DisableNameChecking", this.DisableNameChecking); powerShell.AddParameter("PassThru", true); if (fullyQualifiedName != null) { powerShell.AddParameter("FullyQualifiedName", fullyQualifiedName); } else { powerShell.AddParameter("Name", moduleName); if (this.MinimumVersion != null) { powerShell.AddParameter("Version", this.MinimumVersion); } if (this.RequiredVersion != null) { powerShell.AddParameter("RequiredVersion", this.RequiredVersion); } if (this.MaximumVersion != null) { powerShell.AddParameter("MaximumVersion", this.MaximumVersion); } } if (this.ArgumentList != null) { powerShell.AddParameter("ArgumentList", this.ArgumentList); } if (this.BaseForce) { powerShell.AddParameter("Force", true); } string errorMessageTemplate = string.Format( CultureInfo.InvariantCulture, Modules.RemoteDiscoveryRemotePsrpCommandFailed, string.Format(CultureInfo.InvariantCulture, "Import-Module -Name '{0}'", moduleName)); remotelyImportedModules = RemoteDiscoveryHelper.InvokePowerShell( powerShell, this.CancellationToken, this, errorMessageTemplate).ToList(); } List<PSModuleInfo> result = new List<PSModuleInfo>(); foreach (PSObject remotelyImportedModule in remotelyImportedModules) { PSPropertyInfo nameProperty = remotelyImportedModule.Properties["Name"]; if (nameProperty != null) { string remoteModuleName = (string)LanguagePrimitives.ConvertTo( nameProperty.Value, typeof(string), CultureInfo.InvariantCulture); PSPropertyInfo helpInfoProperty = remotelyImportedModule.Properties["HelpInfoUri"]; string remoteHelpInfoUri = null; if (helpInfoProperty != null) { remoteHelpInfoUri = (string)LanguagePrimitives.ConvertTo( helpInfoProperty.Value, typeof(string), CultureInfo.InvariantCulture); } PSPropertyInfo guidProperty = remotelyImportedModule.Properties["Guid"]; Guid remoteModuleGuid = Guid.Empty; if (guidProperty != null) { LanguagePrimitives.TryConvertTo(guidProperty.Value, out remoteModuleGuid); } PSPropertyInfo versionProperty = remotelyImportedModule.Properties["Version"]; Version remoteModuleVersion = null; if (versionProperty != null) { Version tmp; if (LanguagePrimitives.TryConvertTo<Version>(versionProperty.Value, CultureInfo.InvariantCulture, out tmp)) { remoteModuleVersion = tmp; } } PSModuleInfo moduleInfo = ImportModule_RemotelyViaPsrpSession_SinglePreimportedModule( importModuleOptions, remoteModuleName, remoteModuleVersion, psSession); // Set the HelpInfoUri and Guid as necessary, so that Save-Help can work with this module object // to retrieve help files from the remote site. if (moduleInfo != null) { // set the HelpInfoUri if it's needed if (string.IsNullOrEmpty(moduleInfo.HelpInfoUri) && !string.IsNullOrEmpty(remoteHelpInfoUri)) { moduleInfo.SetHelpInfoUri(remoteHelpInfoUri); } // set the Guid if it's needed if (remoteModuleGuid != Guid.Empty) { moduleInfo.SetGuid(remoteModuleGuid); } result.Add(moduleInfo); } } } return result; }
private void ImportModule_ViaAssembly(ImportModuleOptions importModuleOptions, Assembly suppliedAssembly) { bool moduleLoaded = false; // Loop through Module Cache to ensure that the module is not already imported. if (suppliedAssembly != null && Context.Modules.ModuleTable != null) { foreach (KeyValuePair<string, PSModuleInfo> pair in Context.Modules.ModuleTable) { // if the module in the moduleTable is an assembly module without path, the moduleName is the key. string moduleName = "dynamic_code_module_" + suppliedAssembly; if (pair.Value.Path == "") { if (pair.Key.Equals(moduleName, StringComparison.OrdinalIgnoreCase)) { moduleLoaded = true; if (BasePassThru) { WriteObject(pair.Value); } break; } else { continue; } } if (pair.Value.Path.Equals(suppliedAssembly.Location, StringComparison.OrdinalIgnoreCase)) { moduleLoaded = true; if (BasePassThru) { WriteObject(pair.Value); } break; } } } if (!moduleLoaded) { bool found; PSModuleInfo module = LoadBinaryModule(false, null, null, suppliedAssembly, null, null, importModuleOptions, ManifestProcessingFlags.LoadElements | ManifestProcessingFlags.WriteErrors | ManifestProcessingFlags.NullOnFirstError, this.BasePrefix, false /* loadTypes */ , false /* loadFormats */, out found); if (found && module != null) { // Add it to all module tables ... AddModuleToModuleTables(this.Context, this.TargetSessionState.Internal, module); if (BasePassThru) { WriteObject(module); } } } }
private PSModuleInfo ImportModule_LocallyViaName(ImportModuleOptions importModuleOptions, string name) { try { if (name.Equals("PSWorkflow", StringComparison.OrdinalIgnoreCase) && Utils.IsRunningFromSysWOW64()) { throw new NotSupportedException(AutomationExceptions.WorkflowDoesNotSupportWOW64); } bool found = false; PSModuleInfo foundModule = null; string cachedPath = null; string rootedPath = null; // See if we can use the cached path for the file. If a version number has been specified, then // we won't look in the cache if (this.MinimumVersion == null && this.MaximumVersion == null && this.RequiredVersion == null && PSModuleInfo.UseAppDomainLevelModuleCache && !this.BaseForce) { // See if the name is in the appdomain-level module path name cache... cachedPath = PSModuleInfo.ResolveUsingAppDomainLevelModuleCache(name); } if (!string.IsNullOrEmpty(cachedPath)) { if (File.Exists(cachedPath)) { rootedPath = cachedPath; } else { PSModuleInfo.RemoveFromAppDomainLevelCache(name); } } if (rootedPath == null) { // Check for full-qualified paths - either absolute or relative rootedPath = ResolveRootedFilePath(name, this.Context); } bool alreadyLoaded = false; if (!String.IsNullOrEmpty(rootedPath)) { // TODO/FIXME: use IsModuleAlreadyLoaded to get consistent behavior // TODO/FIXME: (for example checking ModuleType != Manifest below seems incorrect - cdxml modules also declare their own version) // PSModuleInfo alreadyLoadedModule = null; // Context.Modules.ModuleTable.TryGetValue(rootedPath, out alreadyLoadedModule); // if (!BaseForce && IsModuleAlreadyLoaded(alreadyLoadedModule)) // If the module has already been loaded, just emit it and continue... PSModuleInfo module; if (!BaseForce && Context.Modules.ModuleTable.TryGetValue(rootedPath, out module)) { if (RequiredVersion == null || module.Version.Equals(RequiredVersion) || (BaseMinimumVersion == null && BaseMaximumVersion == null) || module.ModuleType != ModuleType.Manifest || (BaseMinimumVersion == null && BaseMaximumVersion != null && module.Version <= BaseMaximumVersion) || (BaseMinimumVersion != null && BaseMaximumVersion == null && module.Version >= BaseMinimumVersion) || (BaseMinimumVersion != null && BaseMaximumVersion != null && module.Version >= BaseMinimumVersion && module.Version <= BaseMaximumVersion)) { alreadyLoaded = true; AddModuleToModuleTables(this.Context, this.TargetSessionState.Internal, module); ImportModuleMembers(module, this.BasePrefix, importModuleOptions); if (BaseAsCustomObject) { if (module.ModuleType != ModuleType.Script) { string message = StringUtil.Format(Modules.CantUseAsCustomObjectWithBinaryModule, module.Path); InvalidOperationException invalidOp = new InvalidOperationException(message); ErrorRecord er = new ErrorRecord(invalidOp, "Modules_CantUseAsCustomObjectWithBinaryModule", ErrorCategory.PermissionDenied, null); WriteError(er); } else { WriteObject(module.AsCustomObject()); } } else if (BasePassThru) { WriteObject(module); } found = true; foundModule = module; } } if (!alreadyLoaded) { // If the path names a file, load that file... if (File.Exists(rootedPath)) { PSModuleInfo moduleToRemove; if (Context.Modules.ModuleTable.TryGetValue(rootedPath, out moduleToRemove)) { RemoveModule(moduleToRemove); } foundModule = LoadModule(rootedPath, null, this.BasePrefix, null, ref importModuleOptions, ManifestProcessingFlags.LoadElements | ManifestProcessingFlags.WriteErrors | ManifestProcessingFlags.NullOnFirstError, out found); } else if (Directory.Exists(rootedPath)) { // Load the latest valid version if it is a multi-version module directory foundModule = LoadUsingMultiVersionModuleBase(rootedPath, ManifestProcessingFlags.LoadElements | ManifestProcessingFlags.WriteErrors | ManifestProcessingFlags.NullOnFirstError, importModuleOptions, out found); if (!found) { // If the path is a directory, double up the end of the string // then try to load that using extensions... rootedPath = Path.Combine(rootedPath, Path.GetFileName(rootedPath)); foundModule = LoadUsingExtensions(null, rootedPath, rootedPath, null, null, this.BasePrefix, /*SessionState*/ null, importModuleOptions, ManifestProcessingFlags.LoadElements | ManifestProcessingFlags.WriteErrors | ManifestProcessingFlags.NullOnFirstError, out found); } } } } else { // Check if module could be a snapin. This was the case for PowerShell version 2 engine modules. if (InitialSessionState.IsEngineModule(name)) { PSSnapInInfo snapin = ModuleCmdletBase.GetEngineSnapIn(Context, name); // Return the command if we found a module if (snapin != null) { // warn that this module already exists as a snapin string warningMessage = string.Format( CultureInfo.InvariantCulture, Modules.ModuleLoadedAsASnapin, snapin.Name); WriteWarning(warningMessage); found = true; return foundModule; } } // At this point, the name didn't resolve to an existing file or directory. // It may still be rooted (relative or absolute). If it is, then we'll only use // the extension search. If it's not rooted, use a path-based search. if (IsRooted(name)) { // If there is no extension, we'll have to search using the extensions if (!string.IsNullOrEmpty(Path.GetExtension(name))) { foundModule = LoadModule(name, null, this.BasePrefix, null, ref importModuleOptions, ManifestProcessingFlags.LoadElements | ManifestProcessingFlags.WriteErrors | ManifestProcessingFlags.NullOnFirstError, out found); } else { foundModule = LoadUsingExtensions(null, name, name, null, null, this.BasePrefix, /*SessionState*/ null, importModuleOptions, ManifestProcessingFlags.LoadElements | ManifestProcessingFlags.WriteErrors | ManifestProcessingFlags.NullOnFirstError, out found); } } else { IEnumerable<string> modulePath = ModuleIntrinsics.GetModulePath(false, this.Context); if (this.MinimumVersion == null && this.RequiredVersion == null && this.MaximumVersion == null) { this.AddToAppDomainLevelCache = true; } found = LoadUsingModulePath(found, modulePath, name, /* SessionState*/ null, importModuleOptions, ManifestProcessingFlags.LoadElements | ManifestProcessingFlags.WriteErrors | ManifestProcessingFlags.NullOnFirstError, out foundModule); } } if (!found) { ErrorRecord er = null; string message = null; if (BaseRequiredVersion != null) { message = StringUtil.Format(Modules.ModuleWithVersionNotFound, name, BaseRequiredVersion); } else if (BaseMinimumVersion != null && BaseMaximumVersion != null) { message = StringUtil.Format(Modules.MinimumVersionAndMaximumVersionNotFound, name, BaseMinimumVersion, BaseMaximumVersion); } else if (BaseMinimumVersion != null) { message = StringUtil.Format(Modules.ModuleWithVersionNotFound, name, BaseMinimumVersion); } else if (BaseMaximumVersion != null) { message = StringUtil.Format(Modules.MaximumVersionNotFound, name, BaseMaximumVersion); } if (BaseRequiredVersion != null || BaseMinimumVersion != null || BaseMaximumVersion != null) { FileNotFoundException fnf = new FileNotFoundException(message); er = new ErrorRecord(fnf, "Modules_ModuleWithVersionNotFound", ErrorCategory.ResourceUnavailable, name); } else { message = StringUtil.Format(Modules.ModuleNotFound, name); FileNotFoundException fnf = new FileNotFoundException(message); er = new ErrorRecord(fnf, "Modules_ModuleNotFound", ErrorCategory.ResourceUnavailable, name); } WriteError(er); } return foundModule; } catch (PSInvalidOperationException e) { ErrorRecord er = new ErrorRecord(e.ErrorRecord, e); WriteError(er); } return null; }
private void ImportModule_ViaLocalModuleInfo(ImportModuleOptions importModuleOptions, PSModuleInfo module) { try { PSModuleInfo alreadyLoadedModule = null; Context.Modules.ModuleTable.TryGetValue(module.Path, out alreadyLoadedModule); if (!BaseForce && IsModuleAlreadyLoaded(alreadyLoadedModule)) { AddModuleToModuleTables(this.Context, this.TargetSessionState.Internal, alreadyLoadedModule); // Even if the module has been loaded, import the specified members... ImportModuleMembers(alreadyLoadedModule, this.BasePrefix, importModuleOptions); if (BaseAsCustomObject) { if (alreadyLoadedModule.ModuleType != ModuleType.Script) { string message = StringUtil.Format(Modules.CantUseAsCustomObjectWithBinaryModule, alreadyLoadedModule.Path); InvalidOperationException invalidOp = new InvalidOperationException(message); ErrorRecord er = new ErrorRecord(invalidOp, "Modules_CantUseAsCustomObjectWithBinaryModule", ErrorCategory.PermissionDenied, null); WriteError(er); } else { WriteObject(alreadyLoadedModule.AsCustomObject()); } } else if (BasePassThru) { WriteObject(alreadyLoadedModule); } } else { PSModuleInfo moduleToRemove; if (Context.Modules.ModuleTable.TryGetValue(module.Path, out moduleToRemove)) { Dbg.Assert(BaseForce, "We should only remove and reload if -Force was specified"); RemoveModule(moduleToRemove); } PSModuleInfo moduleToProcess = module; try { // If we're passing in a dynamic module, then the session state will not be // null and we want to just add the module to the module table. Otherwise, it's // a module info from Get-Module -list so we need to read the actual module file. if (module.SessionState == null) { if (File.Exists(module.Path)) { bool found; moduleToProcess = LoadModule(module.Path, null, this.BasePrefix, /*SessionState*/ null, ref importModuleOptions, ManifestProcessingFlags.LoadElements | ManifestProcessingFlags.WriteErrors | ManifestProcessingFlags.NullOnFirstError, out found); Dbg.Assert(found, "Module should be found when referenced by its absolute path"); } } else if (!string.IsNullOrEmpty(module.Name)) { // It has a session state and a name but it's not in the module // table so it's ok to add it // Add it to the all module tables AddModuleToModuleTables(this.Context, this.TargetSessionState.Internal, moduleToProcess); if (moduleToProcess.SessionState != null) { ImportModuleMembers(moduleToProcess, this.BasePrefix, importModuleOptions); } if (BaseAsCustomObject && moduleToProcess.SessionState != null) { WriteObject(module.AsCustomObject()); } else if (BasePassThru) { WriteObject(moduleToProcess); } } } catch (IOException) { ; } } } catch (PSInvalidOperationException e) { ErrorRecord er = new ErrorRecord(e.ErrorRecord, e); WriteError(er); } }
/// <summary> /// Load the specified modules... /// </summary> /// <remarks> /// Examples: /// c:\temp\mdir\mdir.psm1 # load absolute path /// ./mdir.psm1 # load relative path /// c:\temp\mdir\mdir # resolve by using extensions. mdir is a directory, mdir.xxx is a file. /// c:\temp\mdir # load default module if mdir is directory /// module # $PSScriptRoot/module/module.psd1 (ps1,psm1,dll) /// module/foobar.psm1 # $PSScriptRoot/module/module.psm1 /// module/foobar # $PSScriptRoot/module/foobar.XXX if foobar is not a directory... /// module/foobar # $PSScriptRoot/module/foobar is a directory and $PSScriptRoot/module/foobar/foobar.XXX exists /// module/foobar/foobar.XXX /// </remarks> protected override void ProcessRecord() { if (BaseMaximumVersion != null && BaseMaximumVersion != null && BaseMaximumVersion < BaseMinimumVersion) { string message = StringUtil.Format(Modules.MinimumVersionAndMaximumVersionInvalidRange, BaseMinimumVersion, BaseMaximumVersion); throw new PSArgumentOutOfRangeException(message); } ImportModuleOptions importModuleOptions = new ImportModuleOptions(); importModuleOptions.NoClobber = NoClobber; if (!string.IsNullOrEmpty(Scope) && Scope.Equals(StringLiterals.Local, StringComparison.OrdinalIgnoreCase)) { importModuleOptions.Local = true; } if (this.ParameterSetName.Equals(ParameterSet_ModuleInfo, StringComparison.OrdinalIgnoreCase)) { // Process all of the specified PSModuleInfo objects. These would typically be coming in as a result // of doing Get-Module -list foreach (PSModuleInfo module in ModuleInfo) { RemoteDiscoveryHelper.DispatchModuleInfoProcessing( module, localAction: delegate () { ImportModule_ViaLocalModuleInfo(importModuleOptions, module); SetModuleBaseForEngineModules(module.Name, this.Context); }, cimSessionAction: (cimSession, resourceUri, cimNamespace) => ImportModule_RemotelyViaCimSession( importModuleOptions, new string[] { module.Name }, cimSession, resourceUri, cimNamespace), psSessionAction: psSession => ImportModule_RemotelyViaPsrpSession( importModuleOptions, new string[] { module.Path }, null, psSession)); } } else if (this.ParameterSetName.Equals(ParameterSet_Assembly, StringComparison.OrdinalIgnoreCase)) { // Now load all of the supplied assemblies... if (Assembly != null) { foreach (Assembly suppliedAssembly in Assembly) { ImportModule_ViaAssembly(importModuleOptions, suppliedAssembly); } } } else if (this.ParameterSetName.Equals(ParameterSet_Name, StringComparison.OrdinalIgnoreCase)) { foreach (string name in Name) { PSModuleInfo foundModule = ImportModule_LocallyViaName(importModuleOptions, name); if (null != foundModule) { SetModuleBaseForEngineModules(foundModule.Name, this.Context); TelemetryAPI.ReportModuleLoad(foundModule); } } } else if (this.ParameterSetName.Equals(ParameterSet_ViaPsrpSession, StringComparison.OrdinalIgnoreCase)) { ImportModule_RemotelyViaPsrpSession(importModuleOptions, this.Name, null, this.PSSession); } else if (this.ParameterSetName.Equals(ParameterSet_ViaCimSession, StringComparison.OrdinalIgnoreCase)) { ImportModule_RemotelyViaCimSession(importModuleOptions, this.Name, this.CimSession, this.CimResourceUri, this.CimNamespace); } else if (this.ParameterSetName.Equals(ParameterSet_FQName, StringComparison.OrdinalIgnoreCase)) { foreach (var modulespec in FullyQualifiedName) { RequiredVersion = modulespec.RequiredVersion; MinimumVersion = modulespec.Version; MaximumVersion = modulespec.MaximumVersion; BaseGuid = modulespec.Guid; PSModuleInfo foundModule = ImportModule_LocallyViaName(importModuleOptions, modulespec.Name); if (null != foundModule) { SetModuleBaseForEngineModules(foundModule.Name, this.Context); } } } else if (this.ParameterSetName.Equals(ParameterSet_FQName_ViaPsrpSession, StringComparison.OrdinalIgnoreCase)) { ImportModule_RemotelyViaPsrpSession(importModuleOptions, null, FullyQualifiedName, this.PSSession); } else { Dbg.Assert(false, "Unrecognized parameter set"); } }
private PSModuleInfo ImportModule_RemotelyViaCimModuleData( ImportModuleOptions importModuleOptions, RemoteDiscoveryHelper.CimModule remoteCimModule, CimSession cimSession) { try { if (remoteCimModule.MainManifest == null) { string errorMessage = string.Format( CultureInfo.InvariantCulture, Modules.EmptyModuleManifest, remoteCimModule.ModuleName + ".psd1"); ArgumentException argumentException = new ArgumentException(errorMessage); throw argumentException; } bool containedErrors = false; PSModuleInfo moduleInfo = null; // // read the original manifest // string temporaryModuleDirectory = RemoteDiscoveryHelper.GetModulePath( remoteCimModule.ModuleName, null, cimSession.ComputerName, this.Context.CurrentRunspace); string temporaryModuleManifestPath = Path.Combine( temporaryModuleDirectory, remoteCimModule.ModuleName + ".psd1"); Hashtable data = null; Hashtable localizedData = null; { ScriptBlockAst scriptBlockAst = null; Token[] throwAwayTokens; ParseError[] parseErrors; scriptBlockAst = Parser.ParseInput( remoteCimModule.MainManifest.FileData, temporaryModuleManifestPath, out throwAwayTokens, out parseErrors); if ((scriptBlockAst == null) || (parseErrors != null && parseErrors.Length > 0)) { throw new ParseException(parseErrors); } ScriptBlock scriptBlock = new ScriptBlock(scriptBlockAst, isFilter: false); data = LoadModuleManifestData( temporaryModuleManifestPath, scriptBlock, ModuleManifestMembers, ManifestProcessingFlags.NullOnFirstError | ManifestProcessingFlags.WriteErrors, /* - don't load elements */ ref containedErrors); if ((data == null) || containedErrors) { return null; } localizedData = data; } // // flatten module contents and rewrite the manifest to point to the flattened file hierarchy // // recalculate module path, taking into account the module version fetched above Version moduleVersion; if (!GetScalarFromData<Version>(data, null, "ModuleVersion", 0, out moduleVersion)) { moduleVersion = null; } temporaryModuleDirectory = RemoteDiscoveryHelper.GetModulePath( remoteCimModule.ModuleName, moduleVersion, cimSession.ComputerName, this.Context.CurrentRunspace); temporaryModuleManifestPath = Path.Combine( temporaryModuleDirectory, remoteCimModule.ModuleName + ".psd1"); // avoid loading an already loaded module PSModuleInfo alreadyImportedModule = this.IsModuleImportUnnecessaryBecauseModuleIsAlreadyLoaded( temporaryModuleManifestPath, this.BasePrefix, importModuleOptions); if (alreadyImportedModule != null) { return alreadyImportedModule; } try { Directory.CreateDirectory(temporaryModuleDirectory); IEnumerable<string> typesToProcess = CreateCimModuleFiles( remoteCimModule, RemoteDiscoveryHelper.CimFileCode.TypesV1, cimModuleFile => IsTypesPs1XmlFile(cimModuleFile, data), temporaryModuleDirectory); IEnumerable<string> formatsToProcess = CreateCimModuleFiles( remoteCimModule, RemoteDiscoveryHelper.CimFileCode.FormatV1, cimModuleFile => IsFormatPs1XmlFile(cimModuleFile, data), temporaryModuleDirectory); IEnumerable<string> nestedModules = CreateCimModuleFiles( remoteCimModule, RemoteDiscoveryHelper.CimFileCode.CmdletizationV1, IsCmdletizationFile, temporaryModuleDirectory); data = RemoteDiscoveryHelper.RewriteManifest( data, nestedModules: nestedModules, typesToProcess: typesToProcess, formatsToProcess: formatsToProcess); localizedData = RemoteDiscoveryHelper.RewriteManifest(localizedData); // // import the module // (from memory - this avoids the authenticode signature problems // that would be introduced by rewriting the contents of the manifest) // moduleInfo = LoadModuleManifest( temporaryModuleManifestPath, null, //scriptInfo data, localizedData, ManifestProcessingFlags.LoadElements | ManifestProcessingFlags.WriteErrors | ManifestProcessingFlags.NullOnFirstError, BaseMinimumVersion, BaseMaximumVersion, BaseRequiredVersion, BaseGuid, ref importModuleOptions, ref containedErrors); if (moduleInfo == null) { return null; } foreach (PSModuleInfo nestedModule in moduleInfo.NestedModules) { Type cmdletAdapter; bool gotCmdletAdapter = PSPrimitiveDictionary.TryPathGet( nestedModule.PrivateData as IDictionary, out cmdletAdapter, "CmdletsOverObjects", "CmdletAdapter"); Dbg.Assert(gotCmdletAdapter, "PrivateData from cdxml should always include cmdlet adapter"); if (!cmdletAdapter.AssemblyQualifiedName.Equals(StringLiterals.DefaultCmdletAdapter, StringComparison.OrdinalIgnoreCase)) { string errorMessage = string.Format( CultureInfo.InvariantCulture, CmdletizationCoreResources.ImportModule_UnsupportedCmdletAdapter, cmdletAdapter.FullName); ErrorRecord errorRecord = new ErrorRecord( new InvalidOperationException(errorMessage), "UnsupportedCmdletAdapter", ErrorCategory.InvalidData, cmdletAdapter); this.ThrowTerminatingError(errorRecord); } } if (IsMixedModePsCimModule(remoteCimModule)) { // warn that some commands have not been imported string warningMessage = string.Format( CultureInfo.InvariantCulture, Modules.MixedModuleOverCimSessionWarning, remoteCimModule.ModuleName); this.WriteWarning(warningMessage); } // // store the default session // Dbg.Assert(moduleInfo.ModuleType == ModuleType.Manifest, "Remote discovery should always produce a 'manifest' module"); Dbg.Assert(moduleInfo.NestedModules != null, "Remote discovery should always produce a 'manifest' module with nested modules entry"); Dbg.Assert(moduleInfo.NestedModules.Count > 0, "Remote discovery should always produce a 'manifest' module with some nested modules"); foreach (PSModuleInfo nestedModule in moduleInfo.NestedModules) { IDictionary cmdletsOverObjectsPrivateData; bool cmdletsOverObjectsPrivateDataWasFound = PSPrimitiveDictionary.TryPathGet<IDictionary>( nestedModule.PrivateData as IDictionary, out cmdletsOverObjectsPrivateData, ScriptWriter.PrivateDataKey_CmdletsOverObjects); Dbg.Assert(cmdletsOverObjectsPrivateDataWasFound, "Cmdletization should always set the PrivateData properly"); cmdletsOverObjectsPrivateData[ScriptWriter.PrivateDataKey_DefaultSession] = cimSession; } // // make sure the temporary folder gets removed when the module is removed // const string onRemoveScriptBody = @" Microsoft.PowerShell.Management\Remove-Item ` -LiteralPath $temporaryModulePath ` -Force ` -Recurse ` -ErrorAction SilentlyContinue if ($previousOnRemoveScript -ne $null) { & $previousOnRemoveScript $args } "; ScriptBlock onRemoveScriptBlock = this.Context.Engine.ParseScriptBlock(onRemoveScriptBody, false); onRemoveScriptBlock = onRemoveScriptBlock.GetNewClosure(); // create a separate scope for variables set below onRemoveScriptBlock.Module.SessionState.PSVariable.Set("temporaryModulePath", temporaryModuleDirectory); onRemoveScriptBlock.Module.SessionState.PSVariable.Set("previousOnRemoveScript", moduleInfo.OnRemove); moduleInfo.OnRemove = onRemoveScriptBlock; // // Some processing common for local and remote modules // AddModuleToModuleTables( this.Context, this.TargetSessionState.Internal, moduleInfo); if (BasePassThru) { WriteObject(moduleInfo); } return moduleInfo; } catch { if (Directory.Exists(temporaryModuleDirectory)) { Directory.Delete(temporaryModuleDirectory, recursive: true); } throw; } finally { if (moduleInfo == null) { if (Directory.Exists(temporaryModuleDirectory)) { Directory.Delete(temporaryModuleDirectory, recursive: true); } } } } catch (Exception e) { ErrorRecord errorRecord = RemoteDiscoveryHelper.GetErrorRecordForProcessingOfCimModule(e, remoteCimModule.ModuleName); this.WriteError(errorRecord); return null; } }
private void ImportModule_RemotelyViaCimSession( ImportModuleOptions importModuleOptions, string[] moduleNames, CimSession cimSession, Uri resourceUri, string cimNamespace) { // // find all remote PS-CIM modules // IEnumerable<RemoteDiscoveryHelper.CimModule> remoteModules = RemoteDiscoveryHelper.GetCimModules( cimSession, resourceUri, cimNamespace, moduleNames, false /* onlyManifests */, this, this.CancellationToken).ToList(); IEnumerable<RemoteDiscoveryHelper.CimModule> remotePsCimModules = remoteModules.Where(cimModule => cimModule.IsPsCimModule); IEnumerable<string> remotePsrpModuleNames = remoteModules.Where(cimModule => !cimModule.IsPsCimModule).Select(cimModule => cimModule.ModuleName); foreach (string psrpModuleName in remotePsrpModuleNames) { string errorMessage = string.Format( CultureInfo.InvariantCulture, Modules.PsModuleOverCimSessionError, psrpModuleName); ErrorRecord errorRecord = new ErrorRecord( new ArgumentException(errorMessage), "PsModuleOverCimSessionError", ErrorCategory.InvalidArgument, psrpModuleName); this.WriteError(errorRecord); } // // report an error if some modules were not found // IEnumerable<string> allFoundModuleNames = remoteModules.Select(cimModule => cimModule.ModuleName).ToList(); foreach (string requestedModuleName in moduleNames) { var wildcardPattern = WildcardPattern.Get(requestedModuleName, WildcardOptions.IgnoreCase | WildcardOptions.CultureInvariant); bool requestedModuleWasFound = allFoundModuleNames.Any(foundModuleName => wildcardPattern.IsMatch(foundModuleName)); if (!requestedModuleWasFound) { string message = StringUtil.Format(Modules.ModuleNotFound, requestedModuleName); FileNotFoundException fnf = new FileNotFoundException(message); ErrorRecord er = new ErrorRecord(fnf, "Modules_ModuleNotFound", ErrorCategory.ResourceUnavailable, requestedModuleName); WriteError(er); } } // // import the PS-CIM modules // foreach (RemoteDiscoveryHelper.CimModule remoteCimModule in remotePsCimModules) { ImportModule_RemotelyViaCimModuleData(importModuleOptions, remoteCimModule, cimSession); } }
private PSModuleInfo ConvertCimModuleInfoToPSModuleInfo(RemoteDiscoveryHelper.CimModule cimModule, string computerName) { try { bool containedErrors = false; if (cimModule.MainManifest == null) { return GetModuleInfoForRemoteModuleWithoutManifest(cimModule); } string temporaryModuleManifestPath = Path.Combine( RemoteDiscoveryHelper.GetModulePath(cimModule.ModuleName, null, computerName, this.Context.CurrentRunspace), Path.GetFileName(cimModule.ModuleName)); Hashtable mainData = null; if (!containedErrors) { mainData = RemoteDiscoveryHelper.ConvertCimModuleFileToManifestHashtable( cimModule.MainManifest, temporaryModuleManifestPath, this, ref containedErrors); if (mainData == null) { return GetModuleInfoForRemoteModuleWithoutManifest(cimModule); } } if (!containedErrors) { mainData = RemoteDiscoveryHelper.RewriteManifest(mainData); } Hashtable localizedData = mainData; // TODO/FIXME - this needs full path support from the provider PSModuleInfo moduleInfo = null; if (!containedErrors) { ImportModuleOptions throwAwayOptions = new ImportModuleOptions(); moduleInfo = LoadModuleManifest( temporaryModuleManifestPath, null, //scriptInfo mainData, localizedData, 0 /* - don't write errors, don't load elements, don't return null on first error */, this.BaseMinimumVersion, this.BaseMaximumVersion, this.BaseRequiredVersion, this.BaseGuid, ref throwAwayOptions, ref containedErrors); } if ((moduleInfo == null) || containedErrors) { moduleInfo = GetModuleInfoForRemoteModuleWithoutManifest(cimModule); } return moduleInfo; } catch (Exception e) { ErrorRecord errorRecord = RemoteDiscoveryHelper.GetErrorRecordForProcessingOfCimModule(e, cimModule.ModuleName); this.WriteError(errorRecord); return null; } }