mirror of
https://github.com/aphrody-labs/PowerShell.git
synced 2026-10-17 12:45:47 +00:00
Move files from psl-monad submodule to super-project
This commit uses psl-monad branch source-depot 7209cb9 And corresponds to [SD:688741]
This commit is contained in:
1 parent
136e0eecea
commit
60b3b304f2
1182 files changed
+723058
No files matched your search
@@ -0,0 +1,495 @@
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Management.Automation;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Management.Automation.Runspaces;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Microsoft.Management.Infrastructure;
|
||||
using Dbg = System.Management.Automation.Diagnostics;
|
||||
|
||||
//
|
||||
// Now define the set of commands for manipulating modules.
|
||||
//
|
||||
namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements a cmdlet that gets the list of loaded modules...
|
||||
/// </summary>
|
||||
[Cmdlet("Get", "Module", DefaultParameterSetName = ParameterSet_Loaded,
|
||||
HelpUri = "http://go.microsoft.com/fwlink/?LinkID=141552")]
|
||||
[OutputType(typeof (PSModuleInfo))]
|
||||
public sealed class GetModuleCommand : ModuleCmdletBase, IDisposable
|
||||
{
|
||||
#region Cmdlet parameters
|
||||
|
||||
private const string ParameterSet_Loaded = "Loaded";
|
||||
private const string ParameterSet_AvailableLocally = "Available";
|
||||
private const string ParameterSet_AvailableInPsrpSession = "PsSession";
|
||||
private const string ParameterSet_AvailableInCimSession = "CimSession";
|
||||
|
||||
/// <summary>
|
||||
/// This parameter specifies the current pipeline object
|
||||
/// </summary>
|
||||
[Parameter(ParameterSetName = ParameterSet_Loaded, ValueFromPipeline = true, Position = 0)]
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableLocally, ValueFromPipeline = true, Position = 0)]
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableInPsrpSession, ValueFromPipeline = true, Position = 0)]
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableInCimSession, ValueFromPipeline = true, Position = 0)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays",
|
||||
Justification = "Cmdlets use arrays for parameters.")]
|
||||
public string[] Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This parameter specifies the current pipeline object
|
||||
/// </summary>
|
||||
[Parameter(ParameterSetName = ParameterSet_Loaded, ValueFromPipelineByPropertyName = true)]
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableLocally, ValueFromPipelineByPropertyName = true)]
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableInPsrpSession, ValueFromPipelineByPropertyName = true)]
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableInCimSession, ValueFromPipelineByPropertyName = true)]
|
||||
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays",
|
||||
Justification = "Cmdlets use arrays for parameters.")]
|
||||
public ModuleSpecification[] FullyQualifiedName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If specified, all loaded modules should be returne, otherwise only the visible
|
||||
/// modules should be returned.
|
||||
/// </summary>
|
||||
[Parameter(ParameterSetName = ParameterSet_Loaded)]
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableLocally)]
|
||||
public SwitchParameter All { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If specified, then Get-Module will return the set of available modules...
|
||||
/// </summary>
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableLocally, Mandatory = true)]
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableInPsrpSession)]
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableInCimSession)]
|
||||
public SwitchParameter ListAvailable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If specified, then Get-Module will return the set of available modules which supports the specified PowerShell edition...
|
||||
/// </summary>
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableLocally)]
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableInPsrpSession)]
|
||||
[ValidateSet("Desktop", "Core")]
|
||||
public string PSEdition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If specified, then Get-Module refreshes the internal cmdlet analysis cache
|
||||
/// </summary>
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableLocally)]
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableInPsrpSession)]
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableInCimSession)]
|
||||
public SwitchParameter Refresh { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If specified, then Get-Module will attempt to discover PowerShell modules on a remote computer using the specified session
|
||||
/// </summary>
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableInPsrpSession, Mandatory = true)]
|
||||
[ValidateNotNull]
|
||||
public PSSession PSSession { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If specified, then Get-Module will attempt to discover PS-CIM modules on a remote computer using the specified session
|
||||
/// </summary>
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableInCimSession, Mandatory = true)]
|
||||
[ValidateNotNull]
|
||||
public CimSession CimSession { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// For interoperability with 3rd party CIM servers, user can specify custom resource URI
|
||||
/// </summary>
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableInCimSession, Mandatory = false)]
|
||||
[ValidateNotNull]
|
||||
public Uri CimResourceUri { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// For interoperability with 3rd party CIM servers, user can specify custom namespace
|
||||
/// </summary>
|
||||
[Parameter(ParameterSetName = ParameterSet_AvailableInCimSession, Mandatory = false)]
|
||||
[ValidateNotNullOrEmpty]
|
||||
public string CimNamespace { get; set; }
|
||||
|
||||
#endregion Cmdlet parameters
|
||||
|
||||
#region Remote discovery
|
||||
|
||||
|
||||
private IEnumerable<PSModuleInfo> GetAvailableViaPsrpSessionCore(string[] moduleNames, Runspace remoteRunspace)
|
||||
{
|
||||
Dbg.Assert(remoteRunspace != null, "Caller should verify remoteRunspace != null");
|
||||
|
||||
using (var powerShell = System.Management.Automation.PowerShell.Create())
|
||||
{
|
||||
powerShell.Runspace = remoteRunspace;
|
||||
powerShell.AddCommand("Get-Module");
|
||||
powerShell.AddParameter("ListAvailable", true);
|
||||
|
||||
if (Refresh.IsPresent)
|
||||
{
|
||||
powerShell.AddParameter("Refresh", true);
|
||||
}
|
||||
|
||||
if (moduleNames != null)
|
||||
{
|
||||
powerShell.AddParameter("Name", moduleNames);
|
||||
}
|
||||
|
||||
string errorMessageTemplate = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
Modules.RemoteDiscoveryRemotePsrpCommandFailed,
|
||||
"Get-Module");
|
||||
foreach (
|
||||
PSObject outputObject in
|
||||
RemoteDiscoveryHelper.InvokePowerShell(powerShell, this.CancellationToken, this,
|
||||
errorMessageTemplate))
|
||||
{
|
||||
PSModuleInfo moduleInfo = RemoteDiscoveryHelper.RehydratePSModuleInfo(outputObject);
|
||||
yield return moduleInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private PSModuleInfo GetModuleInfoForRemoteModuleWithoutManifest(RemoteDiscoveryHelper.CimModule cimModule)
|
||||
{
|
||||
return new PSModuleInfo(cimModule.ModuleName, null, null);
|
||||
}
|
||||
|
||||
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 IEnumerable<PSModuleInfo> GetAvailableViaCimSessionCore(IEnumerable<string> moduleNames,
|
||||
CimSession cimSession, Uri resourceUri,
|
||||
string cimNamespace)
|
||||
{
|
||||
IEnumerable<RemoteDiscoveryHelper.CimModule> remoteModules = RemoteDiscoveryHelper.GetCimModules(
|
||||
cimSession,
|
||||
resourceUri,
|
||||
cimNamespace,
|
||||
moduleNames,
|
||||
true /* onlyManifests */,
|
||||
this,
|
||||
this.CancellationToken);
|
||||
|
||||
IEnumerable<PSModuleInfo> remoteModuleInfos = remoteModules
|
||||
.Select(cimModule => this.ConvertCimModuleInfoToPSModuleInfo(cimModule, cimSession.ComputerName))
|
||||
.Where(moduleInfo => moduleInfo != null);
|
||||
|
||||
return remoteModuleInfos;
|
||||
}
|
||||
|
||||
#endregion Remote discovery
|
||||
|
||||
#region Cancellation support
|
||||
|
||||
private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
private CancellationToken CancellationToken
|
||||
{
|
||||
get { return this._cancellationTokenSource.Token; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When overridden in the derived class, interrupts currently
|
||||
/// running code within the command. It should interrupt BeginProcessing,
|
||||
/// ProcessRecord, and EndProcessing.
|
||||
/// Default implementation in the base class just returns.
|
||||
/// </summary>
|
||||
protected override void StopProcessing()
|
||||
{
|
||||
this._cancellationTokenSource.Cancel();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Releases resources associated with this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
this.Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases resources associated with this object
|
||||
/// </summary>
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
this._cancellationTokenSource.Dispose();
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
private bool _disposed;
|
||||
|
||||
#endregion
|
||||
|
||||
private void AssertListAvailableMode()
|
||||
{
|
||||
if (!this.ListAvailable.IsPresent)
|
||||
{
|
||||
string errorMessage = Modules.RemoteDiscoveryWorksOnlyInListAvailableMode;
|
||||
ArgumentException argumentException = new ArgumentException(errorMessage);
|
||||
ErrorRecord errorRecord = new ErrorRecord(
|
||||
argumentException,
|
||||
"RemoteDiscoveryWorksOnlyInListAvailableMode",
|
||||
ErrorCategory.InvalidArgument,
|
||||
null);
|
||||
this.ThrowTerminatingError(errorRecord);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write out the specified modules...
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
// Name and FullyQualifiedName should not be specified at the same time.
|
||||
// Throw out terminating error if this is the case.
|
||||
if ((Name != null) && (FullyQualifiedName != null))
|
||||
{
|
||||
string errMsg = StringUtil.Format(SessionStateStrings.GetContent_TailAndHeadCannotCoexist, "Name", "FullyQualifiedName");
|
||||
ErrorRecord error = new ErrorRecord(new InvalidOperationException(errMsg), "NameAndFullyQualifiedNameCannotBeSpecifiedTogether", ErrorCategory.InvalidOperation, null);
|
||||
ThrowTerminatingError(error);
|
||||
}
|
||||
|
||||
var strNames = new List<string>();
|
||||
if (Name != null)
|
||||
{
|
||||
strNames.AddRange(Name);
|
||||
}
|
||||
|
||||
var moduleSpecTable = new Dictionary<string, ModuleSpecification>(StringComparer.OrdinalIgnoreCase);
|
||||
if (FullyQualifiedName != null)
|
||||
{
|
||||
moduleSpecTable = FullyQualifiedName.ToDictionary(moduleSpecification => moduleSpecification.Name, StringComparer.OrdinalIgnoreCase);
|
||||
strNames.AddRange(FullyQualifiedName.Select(spec => spec.Name));
|
||||
}
|
||||
|
||||
string[] names = strNames.Count > 0 ? strNames.ToArray() : null;
|
||||
|
||||
if (ParameterSetName.Equals(ParameterSet_Loaded, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
AssertNameDoesNotResolveToAPath(names,
|
||||
Modules.ModuleDiscoveryForLoadedModulesWorksOnlyForUnQualifiedNames,
|
||||
"ModuleDiscoveryForLoadedModulesWorksOnlyForUnQualifiedNames");
|
||||
GetLoadedModules(names, moduleSpecTable, this.All);
|
||||
}
|
||||
else if (ParameterSetName.Equals(ParameterSet_AvailableLocally, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (ListAvailable.IsPresent)
|
||||
{
|
||||
GetAvailableLocallyModules(names, moduleSpecTable, this.All);
|
||||
}
|
||||
else
|
||||
{
|
||||
AssertNameDoesNotResolveToAPath(names,
|
||||
Modules.ModuleDiscoveryForLoadedModulesWorksOnlyForUnQualifiedNames,
|
||||
"ModuleDiscoveryForLoadedModulesWorksOnlyForUnQualifiedNames");
|
||||
GetLoadedModules(names, moduleSpecTable, this.All);
|
||||
}
|
||||
}
|
||||
else if (ParameterSetName.Equals(ParameterSet_AvailableInPsrpSession, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
AssertListAvailableMode();
|
||||
AssertNameDoesNotResolveToAPath(names,
|
||||
Modules.RemoteDiscoveryWorksOnlyForUnQualifiedNames,
|
||||
"RemoteDiscoveryWorksOnlyForUnQualifiedNames");
|
||||
|
||||
GetAvailableViaPsrpSession(names, moduleSpecTable, this.PSSession);
|
||||
}
|
||||
else if (ParameterSetName.Equals(ParameterSet_AvailableInCimSession, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
AssertListAvailableMode();
|
||||
AssertNameDoesNotResolveToAPath(names,
|
||||
Modules.RemoteDiscoveryWorksOnlyForUnQualifiedNames,
|
||||
"RemoteDiscoveryWorksOnlyForUnQualifiedNames");
|
||||
|
||||
GetAvailableViaCimSession(names, moduleSpecTable, this.CimSession,
|
||||
this.CimResourceUri, this.CimNamespace);
|
||||
}
|
||||
else
|
||||
{
|
||||
Dbg.Assert(false, "Unrecognized parameter set");
|
||||
}
|
||||
}
|
||||
|
||||
private void AssertNameDoesNotResolveToAPath(string[] names, string stringFormat, string resourceId)
|
||||
{
|
||||
if (names != null)
|
||||
{
|
||||
foreach (var n in names)
|
||||
{
|
||||
if (n.IndexOf(StringLiterals.DefaultPathSeparator) != -1 || n.IndexOf(StringLiterals.AlternatePathSeparator) != -1)
|
||||
{
|
||||
string errorMessage = StringUtil.Format(stringFormat, n);
|
||||
var argumentException = new ArgumentException(errorMessage);
|
||||
var errorRecord = new ErrorRecord(
|
||||
argumentException,
|
||||
resourceId,
|
||||
ErrorCategory.InvalidArgument,
|
||||
n);
|
||||
this.ThrowTerminatingError(errorRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine whether a module info matches a given module specification table and specified PSEditon value.
|
||||
/// </summary>
|
||||
/// <param name="moduleInfo"></param>
|
||||
/// <param name="moduleSpecTable"></param>
|
||||
/// <param name="edition"></param>
|
||||
/// <returns></returns>
|
||||
private static bool ModuleMatch(PSModuleInfo moduleInfo, IDictionary<string, ModuleSpecification> moduleSpecTable, string edition)
|
||||
{
|
||||
ModuleSpecification moduleSpecification;
|
||||
return (String.IsNullOrEmpty(edition) || moduleInfo.CompatiblePSEditions.Contains(edition, StringComparer.OrdinalIgnoreCase)) &&
|
||||
(!moduleSpecTable.TryGetValue(moduleInfo.Name, out moduleSpecification) || ModuleIntrinsics.IsModuleMatchingModuleSpec(moduleInfo, moduleSpecification));
|
||||
}
|
||||
|
||||
private void GetAvailableViaCimSession(IEnumerable<string> names, IDictionary<string, ModuleSpecification> moduleSpecTable,
|
||||
CimSession cimSession, Uri resourceUri, string cimNamespace)
|
||||
{
|
||||
var remoteModules = GetAvailableViaCimSessionCore(names, cimSession, resourceUri, cimNamespace);
|
||||
|
||||
foreach (var remoteModule in remoteModules.Where(remoteModule => ModuleMatch(remoteModule, moduleSpecTable, PSEdition))
|
||||
)
|
||||
{
|
||||
RemoteDiscoveryHelper.AssociatePSModuleInfoWithSession(remoteModule, cimSession, resourceUri,
|
||||
cimNamespace);
|
||||
this.WriteObject(remoteModule);
|
||||
}
|
||||
}
|
||||
|
||||
private void GetAvailableViaPsrpSession(string[] names, IDictionary<string, ModuleSpecification> moduleSpecTable, PSSession session)
|
||||
{
|
||||
var remoteModules = GetAvailableViaPsrpSessionCore(names, session.Runspace);
|
||||
|
||||
foreach (var remoteModule in remoteModules.Where(remoteModule => ModuleMatch(remoteModule, moduleSpecTable, PSEdition))
|
||||
)
|
||||
{
|
||||
RemoteDiscoveryHelper.AssociatePSModuleInfoWithSession(remoteModule, session);
|
||||
this.WriteObject(remoteModule);
|
||||
}
|
||||
}
|
||||
|
||||
private void GetAvailableLocallyModules(string[] names, IDictionary<string, ModuleSpecification> moduleSpecTable, bool all)
|
||||
{
|
||||
var refresh = Refresh.IsPresent;
|
||||
var modules = GetModule(names, all, refresh);
|
||||
|
||||
foreach (
|
||||
var psModule in
|
||||
modules.Where(module => ModuleMatch(module, moduleSpecTable, PSEdition)).Select(module => new PSObject(module))
|
||||
)
|
||||
{
|
||||
psModule.TypeNames.Insert(0, "ModuleInfoGrouping");
|
||||
WriteObject(psModule);
|
||||
}
|
||||
}
|
||||
|
||||
private void GetLoadedModules(string[] names, IDictionary<string, ModuleSpecification> moduleSpecTable, bool all)
|
||||
{
|
||||
var modulesToWrite = Context.Modules.GetModules(names, all);
|
||||
|
||||
foreach (
|
||||
var moduleInfo in
|
||||
modulesToWrite.Where(moduleInfo => ModuleMatch(moduleInfo, moduleSpecTable, PSEdition))
|
||||
)
|
||||
{
|
||||
WriteObject(moduleInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // Microsoft.PowerShell.Commands
|
||||
|
||||
Reference in new issue
Block a user