private int _numberRemoved = 0; // Maintains a count of the number of modules removed... /// <summary> /// Remove the specified modules. Modules can be specified either through a ModuleInfo or a name. /// </summary> protected override void ProcessRecord() { // This dictionary has the list of modules to be removed. // Key - Module specified as a parameter to Remove-Module // Values - List of all modules that need to be removed for this key (includes all nested modules of this module) Dictionary <PSModuleInfo, List <PSModuleInfo> > modulesToRemove = new Dictionary <PSModuleInfo, List <PSModuleInfo> >(); foreach (var m in Context.Modules.GetModules(_name, false)) { modulesToRemove.Add(m, new List <PSModuleInfo> { m }); } if (FullyQualifiedName != null) { foreach (var m in Context.Modules.GetModules(FullyQualifiedName, false)) { modulesToRemove.Add(m, new List <PSModuleInfo> { m }); } } foreach (var m in _moduleInfo) { modulesToRemove.Add(m, new List <PSModuleInfo> { m }); } // Add any of the child modules of a manifests to the list of modules to remove... Dictionary <PSModuleInfo, List <PSModuleInfo> > nestedModules = new Dictionary <PSModuleInfo, List <PSModuleInfo> >(); foreach (var entry in modulesToRemove) { var module = entry.Key; if (module.NestedModules != null && module.NestedModules.Count > 0) { List <PSModuleInfo> nestedModulesWithNoCircularReference = new List <PSModuleInfo>(); GetAllNestedModules(module, ref nestedModulesWithNoCircularReference); nestedModules.Add(module, nestedModulesWithNoCircularReference); } } // dont add duplicates to our original modulesToRemove list..so that the // evaluation loop below will not duplicate in case of WriteError and WriteWarning. // A global list of modules to be removed is maintained for this purpose HashSet <PSModuleInfo> globalListOfModules = new HashSet <PSModuleInfo>(new PSModuleInfoComparer()); if (nestedModules.Count > 0) { foreach (var entry in nestedModules) { List <PSModuleInfo> values = null; if (modulesToRemove.TryGetValue(entry.Key, out values)) { foreach (var module in entry.Value) { if (!globalListOfModules.Contains(module)) { values.Add(module); globalListOfModules.Add(module); } } } } } // Check the list of modules to remove and exclude those that cannot or should not be removed Dictionary <PSModuleInfo, List <PSModuleInfo> > actualModulesToRemove = new Dictionary <PSModuleInfo, List <PSModuleInfo> >(); // We want to remove the modules starting from the nested modules // If we start from the parent module, the nested modules do not get removed and are left orphaned in the parent modules's sessionstate. foreach (var entry in modulesToRemove) { List <PSModuleInfo> moduleList = new List <PSModuleInfo>(); for (int i = entry.Value.Count - 1; i >= 0; i--) { PSModuleInfo module = entry.Value[i]; // See if the module is constant... if (module.AccessMode == ModuleAccessMode.Constant) { string message = StringUtil.Format(Modules.ModuleIsConstant, module.Name); InvalidOperationException moduleNotRemoved = new InvalidOperationException(message); ErrorRecord er = new ErrorRecord(moduleNotRemoved, "Modules_ModuleIsConstant", ErrorCategory.PermissionDenied, module); WriteError(er); continue; } // See if the module is readonly... if (module.AccessMode == ModuleAccessMode.ReadOnly && !BaseForce) { string message = StringUtil.Format(Modules.ModuleIsReadOnly, module.Name); if (InitialSessionState.IsConstantEngineModule(module.Name)) { WriteWarning(message); } else { InvalidOperationException moduleNotRemoved = new InvalidOperationException(message); ErrorRecord er = new ErrorRecord(moduleNotRemoved, "Modules_ModuleIsReadOnly", ErrorCategory.PermissionDenied, module); WriteError(er); } continue; } if (!ShouldProcess(StringUtil.Format(Modules.ConfirmRemoveModule, module.Name, module.Path))) { continue; } // If this module provides the current session drive, then we cannot remove it. // Abort this command since we don't want to do a partial removal of a module manifest. if (ModuleProvidesCurrentSessionDrive(module)) { if (InitialSessionState.IsEngineModule(module.Name)) { if (!BaseForce) { string message = StringUtil.Format(Modules.CoreModuleCannotBeRemoved, module.Name); this.WriteWarning(message); } continue; } // Specify the overall module name if there is only one. // Otherwise specify the particular module name. string moduleName = (_name.Length == 1) ? _name[0] : module.Name; PSInvalidOperationException invalidOperation = PSTraceSource.NewInvalidOperationException( Modules.ModuleDriveInUse, moduleName); throw (invalidOperation); } // Add module to remove list. moduleList.Add(module); } actualModulesToRemove[entry.Key] = moduleList; } // Now remove the modules, first checking the RequiredModules dependencies Dictionary <PSModuleInfo, List <PSModuleInfo> > requiredDependencies = GetRequiredDependencies(); foreach (var entry in actualModulesToRemove) { foreach (var module in entry.Value) { if (!BaseForce) { List <PSModuleInfo> requiredBy = null; if (requiredDependencies.TryGetValue(module, out requiredBy)) { for (int i = requiredBy.Count - 1; i >= 0; i--) { if (actualModulesToRemove.ContainsKey(requiredBy[i])) { requiredBy.RemoveAt(i); } } if (requiredBy.Count > 0) { string message = StringUtil.Format(Modules.ModuleIsRequired, module.Name, requiredBy[0].Name); InvalidOperationException moduleNotRemoved = new InvalidOperationException(message); ErrorRecord er = new ErrorRecord(moduleNotRemoved, "Modules_ModuleIsRequired", ErrorCategory.PermissionDenied, module); WriteError(er); continue; } } } _numberRemoved++; this.RemoveModule(module, entry.Key.Name); } } }
protected override void ProcessRecord() { Dictionary <PSModuleInfo, List <PSModuleInfo> > dictionary = new Dictionary <PSModuleInfo, List <PSModuleInfo> >(); foreach (PSModuleInfo info in base.Context.Modules.GetModules(this._name, false)) { dictionary.Add(info, new List <PSModuleInfo> { info }); } foreach (PSModuleInfo info2 in this._moduleInfo) { dictionary.Add(info2, new List <PSModuleInfo> { info2 }); } Dictionary <PSModuleInfo, List <PSModuleInfo> > dictionary2 = new Dictionary <PSModuleInfo, List <PSModuleInfo> >(); foreach (KeyValuePair <PSModuleInfo, List <PSModuleInfo> > pair in dictionary) { PSModuleInfo key = pair.Key; if ((key.NestedModules != null) && (key.NestedModules.Count > 0)) { List <PSModuleInfo> nestedModulesWithNoCircularReference = new List <PSModuleInfo>(); this.GetAllNestedModules(key, ref nestedModulesWithNoCircularReference); dictionary2.Add(key, nestedModulesWithNoCircularReference); } } HashSet <PSModuleInfo> set = new HashSet <PSModuleInfo>(new PSModuleInfoComparer()); if (dictionary2.Count > 0) { foreach (KeyValuePair <PSModuleInfo, List <PSModuleInfo> > pair2 in dictionary2) { List <PSModuleInfo> list4 = null; if (dictionary.TryGetValue(pair2.Key, out list4)) { foreach (PSModuleInfo info4 in pair2.Value) { if (!set.Contains(info4)) { list4.Add(info4); set.Add(info4); } } } } } Dictionary <PSModuleInfo, List <PSModuleInfo> > dictionary3 = new Dictionary <PSModuleInfo, List <PSModuleInfo> >(); foreach (KeyValuePair <PSModuleInfo, List <PSModuleInfo> > pair3 in dictionary) { List <PSModuleInfo> list5 = new List <PSModuleInfo>(); for (int i = pair3.Value.Count - 1; i >= 0; i--) { PSModuleInfo targetObject = pair3.Value[i]; if (targetObject.AccessMode == ModuleAccessMode.Constant) { InvalidOperationException exception = new InvalidOperationException(StringUtil.Format(Modules.ModuleIsConstant, targetObject.Name)); ErrorRecord errorRecord = new ErrorRecord(exception, "Modules_ModuleIsConstant", ErrorCategory.PermissionDenied, targetObject); base.WriteError(errorRecord); } else if ((targetObject.AccessMode == ModuleAccessMode.ReadOnly) && !base.BaseForce) { string text = StringUtil.Format(Modules.ModuleIsReadOnly, targetObject.Name); if (InitialSessionState.IsConstantEngineModule(targetObject.Name)) { base.WriteWarning(text); } else { InvalidOperationException exception2 = new InvalidOperationException(text); ErrorRecord record2 = new ErrorRecord(exception2, "Modules_ModuleIsReadOnly", ErrorCategory.PermissionDenied, targetObject); base.WriteError(record2); } } else if (base.ShouldProcess(StringUtil.Format(Modules.ConfirmRemoveModule, targetObject.Name, targetObject.Path))) { if (this.ModuleProvidesCurrentSessionDrive(targetObject)) { if (!InitialSessionState.IsEngineModule(targetObject.Name)) { string str4 = (this._name.Length == 1) ? this._name[0] : targetObject.Name; throw PSTraceSource.NewInvalidOperationException("Modules", "ModuleDriveInUse", new object[] { str4 }); } if (!base.BaseForce) { string str3 = StringUtil.Format(Modules.CoreModuleCannotBeRemoved, targetObject.Name); base.WriteWarning(str3); } } else { list5.Add(targetObject); } } } dictionary3[pair3.Key] = list5; } Dictionary <PSModuleInfo, List <PSModuleInfo> > requiredDependencies = this.GetRequiredDependencies(); foreach (KeyValuePair <PSModuleInfo, List <PSModuleInfo> > pair4 in dictionary3) { foreach (PSModuleInfo info6 in pair4.Value) { if (!base.BaseForce) { List <PSModuleInfo> list6 = null; if (requiredDependencies.TryGetValue(info6, out list6)) { for (int j = list6.Count - 1; j >= 0; j--) { if (dictionary3.ContainsKey(list6[j])) { list6.RemoveAt(j); } } if (list6.Count > 0) { InvalidOperationException exception4 = new InvalidOperationException(StringUtil.Format(Modules.ModuleIsRequired, info6.Name, list6[0].Name)); ErrorRecord record3 = new ErrorRecord(exception4, "Modules_ModuleIsRequired", ErrorCategory.PermissionDenied, info6); base.WriteError(record3); continue; } } } this._numberRemoved++; base.RemoveModule(info6, pair4.Key.Name); } } }