Пример #1
0
        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;
            }
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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;
        }
Пример #4
0
        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;
        }
Пример #5
0
        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);
                    }
                }
            }
        }
Пример #6
0
        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;
        }
Пример #7
0
        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);
            }
        }
Пример #8
0
        /// <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");
            }
        }
Пример #9
0
        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;
            }
        }
Пример #10
0
        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);
            }
        }
Пример #11
0
        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;
            }
        }