From 8ee6d6ca4313b7122fcc18215018da603a43ffa0 Mon Sep 17 00:00:00 2001 From: PowerShell Team Date: Thu, 28 Apr 2016 13:41:25 -0700 Subject: [PATCH 1/2] Update files from Source Depot changeset [SD:715912] Corresponds to 77eda782aa78ba8b7a36c51ee619629ce6c990f2 in psl-monad. --- .../commands/management/CIMHelper.cs | 15 - .../management/GetComputerInfoCommand.cs | 124 ++- .../commands/management/Process.cs | 2 +- .../commands/management/Service.cs | 2 + .../commands/utility/AddType.cs | 13 +- .../utility/ImplicitRemotingCommands.cs | 2 +- .../commands/utility/SetDateCommand.cs | 1 + .../resources/UtilityCommonStrings.resx | 3 + .../host/msh/ConsoleControl.cs | 26 - .../host/msh/ConsoleHost.cs | 2 +- .../host/msh/ManagedEntrance.cs | 29 + .../host/msh/StartTranscriptCmdlet.cs | 4 +- .../host/msh/StopTranscriptCmdlet.cs | 2 +- .../Commands/SetLocalUserCommand.cs | 9 - .../LocalAccounts/Exceptions.cs | 6 +- .../LocalAccounts/Extensions.cs | 18 +- .../LocalAccounts/Native.cs | 36 +- .../LocalAccounts/NtStatus.cs | 13 +- .../LocalAccounts/Sam.cs | 77 +- .../LocalAccounts/SamApi.cs | 60 -- .../LocalAccounts/StringUtil.cs | 8 + .../security/CertificateProvider.cs | 1 + .../security/SignatureCommands.cs | 3 +- .../security/Utils.cs | 1 + .../Microsoft.PowerShell.Utility.psm1 | 231 +++--- src/Modules/PSDiagnostics/PSDiagnostics.psm1 | Bin 23126 -> 23642 bytes src/Modules/PSGet/PSGet.Resource.psd1 | Bin 74948 -> 78998 bytes src/Modules/PSGet/PSModule.psm1 | 718 ++++++++++++------ .../CoreCLR/CorePsExtensions.cs | 21 +- .../DotNetTypes_format_ps1xml.cs | 22 +- .../engine/COM/ComTypeInfo.cs | 2 + .../engine/ComInterop/ComBinderHelpers.cs | 2 +- .../engine/ComInterop/IDispatchComObject.cs | 14 + .../CommandCompletion/CompletionAnalysis.cs | 2 +- .../engine/ErrorPackage.cs | 9 +- .../engine/InitialSessionState.cs | 7 +- .../engine/Modules/AnalysisCache.cs | 12 + .../engine/Modules/ModuleCmdletBase.cs | 7 +- .../engine/Modules/ModuleIntrinsics.cs | 43 +- .../engine/Modules/ModuleUtils.cs | 20 +- .../Modules/NewModuleManifestCommand.cs | 4 +- .../engine/NativeCommandProcessor.cs | 2 + .../engine/Utils.cs | 1 + .../engine/hostifaces/LocalConnection.cs | 2 +- .../engine/hostifaces/MshHostUserInterface.cs | 41 +- .../engine/parser/SemanticChecks.cs | 15 +- .../engine/parser/TypeResolver.cs | 14 +- .../engine/parser/ast.cs | 19 +- .../remoting/client/remoterunspaceinfo.cs | 18 - .../remoting/commands/ConnectPSSession.cs | 11 - .../remoting/commands/DisconnectPSSession.cs | 11 - .../remoting/commands/InvokeCommandCommand.cs | 22 - .../NewPSSessionConfigurationOptionCommand.cs | 18 +- .../remoting/commands/PSRemotingCmdlet.cs | 191 +---- .../remoting/commands/PushRunspaceCommand.cs | 37 +- .../engine/remoting/commands/StartJob.cs | 11 - .../remoting/commands/getrunspacecommand.cs | 9 - .../remoting/commands/newrunspacecommand.cs | 35 +- .../commands/removerunspacecommand.cs | 17 - .../remoting/common/RunspaceConnectionInfo.cs | 315 +++----- .../remoting/common/remotingexceptions.cs | 2 - .../remoting/fanin/WSManPluginFacade.cs | 21 + .../engine/runtime/Binding/Binders.cs | 12 +- .../engine/runtime/Operations/ClassOps.cs | 130 +++- .../engine/runtime/Operations/MiscOps.cs | 125 --- .../help/HelpFileHelpProvider.cs | 18 +- .../resources/Modules.resx | 9 +- .../resources/RemotingErrorIdStrings.resx | 6 - .../security/Authenticode.cs | 6 + .../security/SecureStringHelper.cs | 1 + .../security/SecuritySupport.cs | 2 + .../security/nativeMethods.cs | 8 + .../utils/ClrFacade.cs | 10 + .../utils/PsUtils.cs | 2 +- 74 files changed, 1376 insertions(+), 1336 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/CIMHelper.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/CIMHelper.cs index 48ee46bfd..28a392ae0 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/CIMHelper.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/CIMHelper.cs @@ -244,21 +244,6 @@ namespace Extensions internal static class CIMExtensions { - /// - /// An "overload" of the - /// .QueryInstances - /// method that takes only the query string as a parameter - /// - /// The CimSession to be queried - /// A string containing the query to be run - /// - /// An IEnumerable interface that can be used to enumerate the instances - /// - internal static IEnumerable QueryInstances(this CimSession session, string query) - { - return session.QueryInstances(CIMHelper.DefaultNamespace, CIMHelper.DefaultQueryDialect, query); - } - /// /// An "overload" of the /// .QueryInstances diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs index afb201a2b..b8bda4f65 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs @@ -9,6 +9,7 @@ using System.Runtime.InteropServices; using System.Reflection; using System.Linq.Expressions; using System.Management.Automation; +using System.Diagnostics.CodeAnalysis; using Microsoft.Management.Infrastructure; using Microsoft.Win32; @@ -22,7 +23,8 @@ namespace Microsoft.PowerShell.Commands /// The Get=ComputerInfo cmdlet gathers and reports information /// about a computer. /// - [Cmdlet(VerbsCommon.Get, "ComputerInfo")] + [Cmdlet(VerbsCommon.Get, "ComputerInfo", + HelpUri = "http://go.microsoft.com/fwlink/?LinkId=799466")] [Alias("gin")] public class GetComputerInfoCommand : PSCmdlet { @@ -114,6 +116,7 @@ namespace Microsoft.PowerShell.Commands [Parameter(Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public string[] Property { get; set; } #endregion Parameters @@ -1290,6 +1293,7 @@ namespace Microsoft.PowerShell.Commands } } #pragma warning disable 649 // fields and properties in these class are assigned dynamically + [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Justification = "Class is instantiated directly from a CIM instance")] internal class WmiBaseBoard { public string Caption; @@ -1322,6 +1326,7 @@ namespace Microsoft.PowerShell.Commands public float? Width; } + [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Justification = "Class is instantiated directly from a CIM instance")] internal class WmiBios : WmiClassBase { public UInt16[] BiosCharacteristics; @@ -1356,6 +1361,7 @@ namespace Microsoft.PowerShell.Commands public string Version; } + [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Justification = "Class is instantiated directly from a CIM instance")] internal class WmiComputerSystem { public UInt16? AdminPasswordStatus; @@ -1438,6 +1444,7 @@ namespace Microsoft.PowerShell.Commands } } + [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Justification = "Class is instantiated directly from a CIM instance")] internal class WmiDeviceGuard { public UInt32[] AvailableSecurityProperties; @@ -1511,6 +1518,7 @@ namespace Microsoft.PowerShell.Commands } } + [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Justification = "Class is instantiated directly from a CIM instance")] internal class WmiKeyboard { public UInt16? Availability; @@ -1537,12 +1545,14 @@ namespace Microsoft.PowerShell.Commands public string SystemName; } + [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Justification = "Class is instantiated directly from a CIM instance")] internal class WMiLogicalMemory { //TODO: fill this in!!! public UInt32? TotalPhysicalMemory; } + [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Justification = "Class is instantiated directly from a CIM instance")] internal class WmiMsftNetAdapter { public string Caption; @@ -1630,6 +1640,7 @@ namespace Microsoft.PowerShell.Commands public bool? AdminLocked; } + [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Justification = "Class is instantiated directly from a CIM instance")] internal class WmiNetworkAdapter { public string AdapterType; @@ -1673,6 +1684,7 @@ namespace Microsoft.PowerShell.Commands public DateTime? TimeOfLastReset; } + [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Justification = "Class is instantiated directly from a CIM instance")] internal class WmiNetworkAdapterConfiguration { public bool? ArpAlwaysSourceRoute; @@ -1738,6 +1750,7 @@ namespace Microsoft.PowerShell.Commands public string WINSSecondaryServer; } + [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Justification = "Class is instantiated directly from a CIM instance")] internal class WmiOperatingSystem : WmiClassBase { #region Fields @@ -1849,6 +1862,7 @@ namespace Microsoft.PowerShell.Commands #endregion Private Methods } + [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Justification = "Class is instantiated directly from a CIM instance")] internal class WmiPageFileUsage { public UInt32? AllocatedBaseSize; @@ -1862,6 +1876,7 @@ namespace Microsoft.PowerShell.Commands public bool? TempPageFile; } + [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Justification = "Class is instantiated directly from a CIM instance")] internal class WmiProcessor { public UInt16? AddressWidth; @@ -1950,27 +1965,32 @@ namespace Microsoft.PowerShell.Commands /// /// Array of required security properties /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public DeviceGuardHardwareSecure[] RequiredSecurityProperties { get; internal set; } /// /// Array of available security properties /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public DeviceGuardHardwareSecure[] AvailableSecurityProperties { get; internal set; } /// /// Indicates which security services have been configured /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public DeviceGuardSoftwareSecure[] SecurityServicesConfigured { get; internal set; } /// /// Indicates which security services are running /// - public DeviceGuardSoftwareSecure[] SecurityServicesRunning; + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] + public DeviceGuardSoftwareSecure[] SecurityServicesRunning { get; internal set; } /// /// Indicates the status of the Device Guard Code Integrity policy /// - public DeviceGuardConfigCodeIntegrityStatus? CodeIntegrityPolicyEnforcementStatus; + public DeviceGuardConfigCodeIntegrityStatus? CodeIntegrityPolicyEnforcementStatus { get; internal set; } + /// /// Indicates the status of the Device Guard user mode Code Integrity policy /// - public DeviceGuardConfigCodeIntegrityStatus? UserModeCodeIntegrityPolicyEnforcementStatus; + public DeviceGuardConfigCodeIntegrityStatus? UserModeCodeIntegrityPolicyEnforcementStatus { get; internal set; } } /// @@ -1981,19 +2001,42 @@ namespace Microsoft.PowerShell.Commands /// /// Unique identifier associated with a particular update. /// - public string HotFixID { get; internal set; } + public string HotFixID + { + get; + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Class is instantiated directly from a CIM instance")] + internal set; + } + /// /// Description of the update /// - public string Description { get; internal set; } + public string Description + { + get; + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Class is instantiated directly from a CIM instance")] + internal set; + } + /// /// String containing the date that the update was installed /// - public string InstalledOn { get; internal set; } + public string InstalledOn + { + get; + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Class is instantiated directly from a CIM instance")] + internal set; + } + /// /// Additional comments that relate to the update /// - public string FixComments { get; internal set; } + public string FixComments + { + get; + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Class is instantiated directly from a CIM instance")] + internal set; + } } /// @@ -2026,6 +2069,7 @@ namespace Microsoft.PowerShell.Commands /// /// Array of all of the IP addresses associated with the current network adapter. /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public string[] IPAddresses { get; internal set; } } @@ -2185,6 +2229,7 @@ namespace Microsoft.PowerShell.Commands /// Array of BIOS characteristics supported by the system as defined by /// the System Management BIOS Reference Specification /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public UInt16[] BiosCharacteristics { get; internal set; } /// @@ -2192,6 +2237,7 @@ namespace Microsoft.PowerShell.Commands /// there can be several version strings that are stored in the registry /// and represent the system BIOS information /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public string[] BiosBIOSVersion { get; internal set; } /// @@ -2266,6 +2312,7 @@ namespace Microsoft.PowerShell.Commands /// /// Array of names of available BIOS-installable languages /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public string[] BiosListOfLanguages { get; internal set; } /// @@ -2395,6 +2442,7 @@ namespace Microsoft.PowerShell.Commands /// /// Status and Additional Data fields that identify the boot status /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public UInt16[] CsBootStatus { get; internal set; } /// @@ -2520,6 +2568,7 @@ namespace Microsoft.PowerShell.Commands /// An array of objects describing any /// network adapters on the system. /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public NetworkAdapter[] CsNetworkAdapters { get; internal set; } /// @@ -2547,6 +2596,7 @@ namespace Microsoft.PowerShell.Commands /// /// Array of objects describing each processor on the system. /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public Processor[] CsProcessors { get; internal set; } /// @@ -2554,6 +2604,7 @@ namespace Microsoft.PowerShell.Commands /// For example, an OEM defines the part numbers for system reference /// documents, manufacturer contact information, and so on /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public string[] CsOEMStringArray { get; internal set; } /// @@ -2583,6 +2634,7 @@ namespace Microsoft.PowerShell.Commands /// /// Array of the specific power-related capabilities of a logical device /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public PowerManagementCapabilities[] CsPowerManagementCapabilities { get; internal set; } /// @@ -2645,6 +2697,7 @@ namespace Microsoft.PowerShell.Commands /// Array that specifies the roles of a system in the information /// technology environment /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public string[] CsRoles { get; internal set; } /// @@ -2655,6 +2708,7 @@ namespace Microsoft.PowerShell.Commands /// /// Array of the support contact information for the Windows operating system /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public string[] CsSupportContactDescription { get; internal set; } /// @@ -2755,6 +2809,7 @@ namespace Microsoft.PowerShell.Commands /// any Quick-Fix Enginnering patches (Hot Fixes) applied to the operating /// system /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public HotFix[] OsHotFixes { get; internal set; } /// @@ -2946,6 +3001,7 @@ namespace Microsoft.PowerShell.Commands /// /// Array of fiel paths to the operating system's paging files /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public string[] OsPagingFiles { get; internal set; } /// @@ -2978,6 +3034,7 @@ namespace Microsoft.PowerShell.Commands /// Array of Multilingual User Interface Pack (MUI Pack) languages installed /// on the computer /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public string[] OsMuiLanguages { get; internal set; } /// @@ -3015,6 +3072,7 @@ namespace Microsoft.PowerShell.Commands /// Array of objects indicating installed /// and licensed product additions to the operating system /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public OSProductSuite[] OsProductSuites { get; internal set; } /// @@ -3073,6 +3131,7 @@ namespace Microsoft.PowerShell.Commands /// /// Product suites available on the operating system /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public OSProductSuite[] OsSuites { get; internal set; } /// @@ -3142,21 +3201,25 @@ namespace Microsoft.PowerShell.Commands /// /// Required Device Guard security properties /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public DeviceGuardHardwareSecure[] DeviceGuardRequiredSecurityProperties { get; internal set; } /// /// Available Device Guard security properties /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public DeviceGuardHardwareSecure[] DeviceGuardAvailableSecurityProperties { get; internal set; } /// /// Configured Device Guard security services /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public DeviceGuardSoftwareSecure[] DeviceGuardSecurityServicesConfigured { get; internal set; } /// /// Running Device Guard security services /// + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public DeviceGuardSoftwareSecure[] DeviceGuardSecurityServicesRunning { get; internal set; } /// @@ -3203,12 +3266,13 @@ namespace Microsoft.PowerShell.Commands /// Actions related to the BootOptionOn* properties of the Win32_ComputerSystem /// CIM class /// + [SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue", Justification = "The underlying MOF definition does not contain a zero value. The converter method will handle it appropriately.")] public enum BootOptionAction { - /// - /// This value is reserved - /// - Reserved = 0, + // + // This value is reserved + // + //Reserved = 0, /// /// Boot into operating system @@ -3229,6 +3293,7 @@ namespace Microsoft.PowerShell.Commands /// /// Indicates the state of a system element /// + [SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue", Justification = "The underlying MOF definition does not contain a zero value. The converter method will handle it appropriately.")] public enum SystemElementState { /// @@ -3306,6 +3371,7 @@ namespace Microsoft.PowerShell.Commands /// /// Specifies a CPU's availability and status /// + [SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue", Justification = "The underlying MOF definition does not contain a zero value. The converter method will handle it appropriately.")] public enum CpuAvailability { /// @@ -3418,6 +3484,7 @@ namespace Microsoft.PowerShell.Commands /// /// Specifies that current status of the processor /// + [SuppressMessage("Microsoft.Design", "CA1027:MarkEnumsWithFlags", Justification = "The underlying MOF definition is not a bit field.")] public enum CpuStatus { /// @@ -3445,15 +3512,15 @@ namespace Microsoft.PowerShell.Commands /// Idle = 4, - /// - /// This value is reserved - /// - Reserved_5 = 5, + // + // This value is reserved + // + //Reserved_5 = 5, - /// - /// This value is reserved - /// - Reserved_6 = 6, + // + // This value is reserved + // + //Reserved_6 = 6, /// /// CPU is in another state @@ -3540,6 +3607,7 @@ namespace Microsoft.PowerShell.Commands /// /// Device Guard hardware security properties /// + [SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue", Justification = "The underlying MOF definition does not contain a zero value. The converter method will handle it appropriately.")] public enum DeviceGuardHardwareSecure { /// @@ -3566,6 +3634,7 @@ namespace Microsoft.PowerShell.Commands /// /// Device Guard software security properties /// + [SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue", Justification = "The underlying MOF definition does not contain a zero value. The converter method will handle it appropriately.")] public enum DeviceGuardSoftwareSecure { /// @@ -3814,6 +3883,8 @@ namespace Microsoft.PowerShell.Commands /// /// Indicates installed and licensed system product additions to the operating system /// + [SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue", Justification = "The underlying MOF definition does not contain a zero value. The converter method will handle it appropriately.")] + [FlagsAttribute] public enum OSProductSuite { /// @@ -4696,6 +4767,7 @@ namespace Microsoft.PowerShell.Commands /// /// Specifies the primary function of a processor /// + [SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue", Justification = "The underlying MOF definition does not contain a zero value. The converter method will handle it appropriately.")] public enum ProcessorType { /// @@ -4732,6 +4804,7 @@ namespace Microsoft.PowerShell.Commands /// /// Specifies a computer's reset capability /// + [SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue", Justification = "The underlying MOF definition does not contain a zero value. The converter method will handle it appropriately.")] public enum ResetCapability { /// @@ -4763,12 +4836,13 @@ namespace Microsoft.PowerShell.Commands /// /// Specifies the kind of event that causes a computer to power up /// + [SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue", Justification = "The underlying MOF definition does not contain a zero value. The converter method will handle it appropriately.")] public enum WakeUpType { - /// - /// This value is reserved - /// - Reserved = 0, + // + // This value is reserved + // + //Reserved = 0, /// /// An event other than specified in this enumeration @@ -4927,7 +5001,7 @@ namespace Microsoft.PowerShell.Commands /// /// State of a software element /// - public enum SoftwareElementState : UInt16 + public enum SoftwareElementState { /// /// Software element is deployable diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs index 2b7211b0e..6efe7c118 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs @@ -2249,7 +2249,7 @@ namespace Microsoft.PowerShell.Commands // Wait for the job object to finish jobObject.WaitOne(waithandle); } - else + else if (!process.HasExited) { // WinBlue: 27537 Start-Process -Wait doesn't work in a remote session on Windows 7 or lower. process.Exited += new EventHandler(myProcess_Exited); diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs index d15a7c2fa..c155a5dad 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs @@ -1677,6 +1677,7 @@ namespace Microsoft.PowerShell.Commands /// /// /// + [ArchitectureSensitive] protected override void ProcessRecord() { @@ -2064,6 +2065,7 @@ namespace Microsoft.PowerShell.Commands /// /// Create the service /// + [ArchitectureSensitive] protected override void BeginProcessing() { Diagnostics.Assert(!String.IsNullOrEmpty(Name), diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs index 929ee0e16..94eb297aa 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs @@ -347,7 +347,7 @@ namespace Microsoft.PowerShell.Commands string activeExtension = null; foreach (string path in resolvedPaths) { - string currentExtension = System.IO.Path.GetExtension(path).ToUpper(); + string currentExtension = System.IO.Path.GetExtension(path).ToUpperInvariant(); switch (currentExtension) { @@ -1063,10 +1063,20 @@ namespace Microsoft.PowerShell.Commands private static PortableExecutableReference ObjectDeclaredAssemblyReference = MetadataReference.CreateFromFile(ClrFacade.GetAssemblies(typeof(object).FullName).First().Location); + // CoreCLR RC2 bits don't have SecureString. We are using a separate assembly with SecureString implementation. + // This fact is an implementation detail and should not require the user to specify one more assembly, + // if they want to use SecureString in Add-Type -TypeDefinition. + // So this assembly should be in the default assemblies list to provide the best experience. + // + // TODO: This reference should be removed, if we take CoreCLR version that has SecureString implementation. + private static PortableExecutableReference SecureStringAssemblyReference = + MetadataReference.CreateFromFile(typeof(System.Security.SecureString).GetTypeInfo().Assembly.Location); + private static MetadataReference[] defaultAssemblies = new MetadataReference[] { ObjectImplementationAssemblyReference, ObjectDeclaredAssemblyReference, + SecureStringAssemblyReference, MetadataReference.CreateFromFile(typeof(PSObject).GetTypeInfo().Assembly.Location) }; @@ -1210,6 +1220,7 @@ namespace Microsoft.PowerShell.Commands var tempReferences = ReferencedAssemblies.Select(a => MetadataReference.CreateFromFile(ResolveReferencedAssembly(a))).ToList(); tempReferences.Add(ObjectImplementationAssemblyReference); tempReferences.Add(ObjectDeclaredAssemblyReference); + tempReferences.Add(SecureStringAssemblyReference); references = tempReferences.ToArray(); } diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImplicitRemotingCommands.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImplicitRemotingCommands.cs index 115f44d69..670e09f97 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImplicitRemotingCommands.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ImplicitRemotingCommands.cs @@ -2526,7 +2526,7 @@ function Get-PSImplicitRemotingSession ) "; - // index 0 - "-ContainerId " (ContainerId is used instead of ContainerName due to its uniqueness) + // index 0 - "-ContainerId " // index 1 - "-RunAsAdministrator" or empty string // index 2 - "-ConfigurationName " or empty string private const string NewContainerRunspaceTemplate = @" diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetDateCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetDateCommand.cs index 553c2b300..cf5868ce2 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetDateCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetDateCommand.cs @@ -83,6 +83,7 @@ namespace Microsoft.PowerShell.Commands /// /// set the date /// + [ArchitectureSensitive] protected override void ProcessRecord() { DateTime dateToUse; diff --git a/src/Microsoft.PowerShell.Commands.Utility/resources/UtilityCommonStrings.resx b/src/Microsoft.PowerShell.Commands.Utility/resources/UtilityCommonStrings.resx index 35d1be950..71192de24 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/resources/UtilityCommonStrings.resx +++ b/src/Microsoft.PowerShell.Commands.Utility/resources/UtilityCommonStrings.resx @@ -171,4 +171,7 @@ The file '{0}' could not be parsed as a PowerShell Data File. + + '{0}' is not supported in this system. + \ No newline at end of file diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs index 1943a91b2..0a7705332 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleControl.cs @@ -623,29 +623,6 @@ namespace Microsoft.PowerShell return _outputHandle.Value; } - internal enum StandardHandleId : uint - { - // From winnt.h - // #define STD_INPUT_HANDLE ((DWORD)-10) - // #define STD_OUTPUT_HANDLE ((DWORD)-11) - // #define STD_ERROR_HANDLE ((DWORD)-12) - - Input = 0xFFFFFFF6, - Output = 0xFFFFFFF5, - Error = 0xFFFFFFF4 - } - - internal static NakedWin32Handle GetStdHandle(StandardHandleId handleId) - { - unchecked - { - // Suppress the PreFAST warning about not using Marshal.GetLastWin32Error() to - // get the error code. -#pragma warning disable 56523 - return NativeMethods.GetStdHandle((DWORD)handleId); - } - } - #endregion #region Mode @@ -3492,9 +3469,6 @@ namespace Microsoft.PowerShell [DllImport(PinvokeDllNames.GetLargestConsoleWindowSizeDllName, SetLastError = true, CharSet = CharSet.Unicode)] internal static extern COORD GetLargestConsoleWindowSize(NakedWin32Handle consoleOutput); - [DllImport(PinvokeDllNames.GetStdHandleDllName, SetLastError = true, CharSet = CharSet.Unicode)] - internal static extern NakedWin32Handle GetStdHandle(DWORD handleId); - [DllImport(PinvokeDllNames.ReadConsoleDllName, SetLastError = true, CharSet = CharSet.Unicode)] internal static extern bool ReadConsole ( diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs index 6148fbb3d..aae5e7261 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs @@ -1421,7 +1421,7 @@ namespace Microsoft.PowerShell if (ExitCode == ExitCodeInitFailure) { break; } - if (!noExit && !ui.ReadFromStdin) + if (!noExit && (!ui.ReadFromStdin || Console.In.Peek() == -1)) { // Wait for runspace to open, init, and run init script before // setting ShouldEndSession, to allow debugger to work. diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ManagedEntrance.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ManagedEntrance.cs index 5f516948c..48174d1c2 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ManagedEntrance.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ManagedEntrance.cs @@ -4,6 +4,7 @@ Copyright (c) Microsoft Corporation. All rights reserved. using System; using System.Threading; +using System.Reflection; using System.Management.Automation; using System.Management.Automation.Internal; using System.Management.Automation.Runspaces; @@ -34,6 +35,13 @@ namespace Microsoft.PowerShell public int Start(string consoleFilePath, string[] args) #endif { +#if !CORECLR + // For long-path support, Full .NET requires some AppContext switches; + // (for CoreCLR this is Not needed, because CoreCLR supports long paths by default) + // internally in .NET they are cached once retrieved and are typically hit very early during an application run; + // so per .NET team's recommendation, we are setting them as soon as we enter managed code. + EnableLongPathsInDotNetIfAvailable(); +#endif System.Management.Automation.Runspaces.EarlyStartup.Init(); // Set ETW activity Id @@ -152,6 +160,27 @@ namespace Microsoft.PowerShell #endif } } + +#if !CORECLR + private static void EnableLongPathsInDotNetIfAvailable() + { + // We build against CLR4.5 so we can run on Win7/Win8, but we want to use apis added to CLR 4.6, so we use reflection + try + { + Type appContextType = Type.GetType("System.AppContext"); // type is in mscorlib, so it is sufficient to supply the type name qualified by its namespace + + object[] blockLongPathsSwitch = new object[] { "Switch.System.IO.BlockLongPaths", false }; + object[] useLegacyPathHandlingSwitch = new object[] { "Switch.System.IO.UseLegacyPathHandling", false }; + + appContextType.InvokeMember("SetSwitch", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, blockLongPathsSwitch); + appContextType.InvokeMember("SetSwitch", BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, useLegacyPathHandlingSwitch); + } + catch + { + // If there are any exceptions (e.g. we are running on CLR prior to 4.6.2), we won't be able to use long paths + } + } +#endif } } diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/StartTranscriptCmdlet.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/StartTranscriptCmdlet.cs index c6c2c77a7..53e5127ba 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/StartTranscriptCmdlet.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/StartTranscriptCmdlet.cs @@ -233,7 +233,7 @@ namespace Microsoft.PowerShell.Commands System.Management.Automation.Remoting.PSSenderInfo psSenderInfo = this.SessionState.PSVariable.GetValue("PSSenderInfo") as System.Management.Automation.Remoting.PSSenderInfo; - Host.UI.StartTranscribing(effectiveFilePath, psSenderInfo, IncludeInvocationHeader.ToBool()); + Host.UI.StartTranscribing(effectiveFilePath, psSenderInfo, IncludeInvocationHeader.ToBool(), this.Context.CurrentRunspace.InstanceId); // ch.StartTranscribing(effectiveFilePath, Append); @@ -249,7 +249,7 @@ namespace Microsoft.PowerShell.Commands { try { - Host.UI.StopTranscribing(); + Host.UI.StopTranscribing(this.Context.CurrentRunspace.InstanceId); } catch { diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/StopTranscriptCmdlet.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/StopTranscriptCmdlet.cs index f9340f912..5b376eb1d 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/StopTranscriptCmdlet.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/StopTranscriptCmdlet.cs @@ -35,7 +35,7 @@ namespace Microsoft.PowerShell.Commands { try { - string outFilename = Host.UI.StopTranscribing(); + string outFilename = Host.UI.StopTranscribing(this.Context.CurrentRunspace.InstanceId); if (outFilename != null) { PSObject outputObject = new PSObject( diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/SetLocalUserCommand.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/SetLocalUserCommand.cs index 098c43f63..2cc7a2289 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/SetLocalUserCommand.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Commands/SetLocalUserCommand.cs @@ -294,15 +294,6 @@ namespace Microsoft.PowerShell.Commands #endregion Cmdlet Overrides #region Private Methods - private LocalUser GetUser() - { - if (InputObject != null) - return InputObject; - - return SID != null ? sam.GetLocalUser(SID) - : sam.GetLocalUser(Name); - } - private bool CheckShouldProcess(string target) { return ShouldProcess(target, Strings.ActionSetUser); diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Exceptions.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Exceptions.cs index 4bf120de1..7893dd603 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Exceptions.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Exceptions.cs @@ -267,7 +267,11 @@ namespace Microsoft.PowerShell.Commands /// public class InvalidParametersException : LocalAccountsException { - internal InvalidParametersException(string message) + /// + /// Creates InvalidParametersException using the specified message. + /// + /// + public InvalidParametersException(string message) : base(message, null, ErrorCategory.InvalidArgument) { } diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Extensions.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Extensions.cs index 68a378219..2d43f187c 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Extensions.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Extensions.cs @@ -30,7 +30,7 @@ namespace System.Management.Automation.SecurityAccountsManager.Extensions bool allowSidConstants = false) { if (!allowSidConstants) - if (!(s.Length > 2 && s.StartsWith("S-") && Char.IsDigit(s[2]))) + if (!(s.Length > 2 && s.StartsWith("S-", StringComparison.Ordinal) && Char.IsDigit(s[2]))) return null; SecurityIdentifier sid = null; @@ -144,21 +144,7 @@ namespace System.Management.Automation.SecurityAccountsManager.Extensions } internal static class SecureStringExtensions - { - private static Regex pwRegex = new Regex(@"^[^\x00-\x1F""/\\\[\]:;\|=,+\*?<>@]{0,127}$", - RegexOptions.Compiled | RegexOptions.CultureInvariant); - - internal static bool IsValidPassword(this SecureString str) - { - return str.Length == 0 || pwRegex.IsMatch(str.AsString()); - } - - internal static void ValidatePassword(this SecureString str) - { - if (!str.IsValidPassword()) - throw new InvalidPasswordException(); - } - + { /// /// Extension method to extract clear text from a /// object. diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Native.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Native.cs index a84837fe0..a70a71e08 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Native.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Native.cs @@ -149,37 +149,7 @@ namespace System.Management.Automation.SecurityAccountsManager.Native public IntPtr SecurityQualityOfService; private IntPtr objectName; - - public OBJECT_ATTRIBUTES(string name, uint attrs) - { - Length = 0; - RootDirectory = IntPtr.Zero; - objectName = IntPtr.Zero; - Attributes = attrs; - SecurityDescriptor = IntPtr.Zero; - SecurityQualityOfService = IntPtr.Zero; - - Length = ClrFacade.SizeOf(); - ObjectName = new UNICODE_STRING(name); - } - - public UNICODE_STRING ObjectName - { - get - { - return ClrFacade.PtrToStructure(objectName); - } - - set - { - bool fDeleteOld = objectName != IntPtr.Zero; - - if (!fDeleteOld) - objectName = Marshal.AllocHGlobal(Marshal.SizeOf(value)); - - Marshal.StructureToPtr(value, objectName, fDeleteOld); - } - } + public UNICODE_STRING ObjectName; public void Dispose() { @@ -463,8 +433,6 @@ namespace System.Management.Automation.SecurityAccountsManager.Native ref uint domainNameLength, out SID_NAME_USE peUse); - [DllImport(PInvokeDllNames.GetComputerNameDllName, CharSet=CharSet.Unicode, SetLastError=true)] - internal static extern bool GetComputerName(StringBuilder name, ref uint size); [DllImport(PInvokeDllNames.GetSecurityDescriptorDaclDllName, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -484,7 +452,7 @@ namespace System.Management.Automation.SecurityAccountsManager.Native [MarshalAs(UnmanagedType.Bool)] bool bDaclDefaulted); - [DllImport(PInvokeDllNames.FormatMessageDllName, SetLastError = true)] + [DllImport(PInvokeDllNames.FormatMessageDllName, CharSet = CharSet.Unicode, SetLastError = true)] internal static extern uint FormatMessage(uint dwFlags, IntPtr lpSource, uint dwMessageId, diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/NtStatus.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/NtStatus.cs index b22a543eb..cdf7c1330 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/NtStatus.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/NtStatus.cs @@ -1,4 +1,6 @@  +using System.Diagnostics.CodeAnalysis; + namespace System.Management.Automation.SecurityAccountsManager.Native { internal static class NtStatus @@ -451,6 +453,7 @@ namespace System.Management.Automation.SecurityAccountsManager.Native return Severity(ntstatus) == STATUS_SEVERITY_ERROR; } + /// /// Determine if an NTSTATUS value indicates a Warning /// @@ -458,6 +461,7 @@ namespace System.Management.Automation.SecurityAccountsManager.Native /// /// True if the NTSTATUS value indicates a warning, false otherwise. /// + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public static bool IsWarning(UInt32 ntstatus) { return Severity(ntstatus) == STATUS_SEVERITY_WARNING; @@ -470,11 +474,12 @@ namespace System.Management.Automation.SecurityAccountsManager.Native /// /// True if the NTSTATUS value indicates that it is informational, false otherwise. /// + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public static bool IsInformational(UInt32 ntstatus) { return Severity(ntstatus) == STATUS_SEVERITY_INFORMATIONAL; } - + /// /// Return the Severity part of an NTSTATUS value @@ -488,6 +493,7 @@ namespace System.Management.Automation.SecurityAccountsManager.Native return ntstatus >> 30; } + /// /// Return the Facility part of an NSTATUS value /// @@ -495,11 +501,14 @@ namespace System.Management.Automation.SecurityAccountsManager.Native /// /// The value of the Facility portion of an NTSTATUS value. /// + + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public static uint Facility(UInt32 ntstatus) { return (ntstatus >> 16) & 0x0FFF; } + /// /// Return the Code part of an NTSTATUS value /// @@ -507,10 +516,12 @@ namespace System.Management.Automation.SecurityAccountsManager.Native /// /// The value of the Code portion of an NTSTATUS value. /// + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public static uint Code(UInt32 ntstatus) { return ntstatus & 0xFFFF; } + #endregion Public Methods } } diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Sam.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Sam.cs index 21992d791..874ae6627 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Sam.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/Sam.cs @@ -11,6 +11,9 @@ using System.Management.Automation.SecurityAccountsManager.Native.NtSam; using System.Text; using Microsoft.PowerShell.LocalAccounts; +using System.Diagnostics.CodeAnalysis; + +[module: SuppressMessage("Microsoft.Design", "CA1014:MarkAssembliesWithClsCompliant")] namespace System.Management.Automation.SecurityAccountsManager { @@ -262,6 +265,7 @@ namespace System.Management.Automation.SecurityAccountsManager /// /// Gets a string containing the type of operation under way. /// + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public string OperationName { get { return operation.ToString(); } @@ -271,6 +275,7 @@ namespace System.Management.Automation.SecurityAccountsManager /// Gets a string containing the type of object ("User" or "Group") /// being used. /// + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] public string TypeNamne { get { return type.ToString(); } @@ -1083,31 +1088,6 @@ namespace System.Management.Automation.SecurityAccountsManager } } - /// - /// Find a named group and return a object - /// representing the group. - /// - /// Name of the group to search for. - /// - /// A SamRidEnumeration object representing the group. - /// - /// - /// Thrown when the specified group is not found. - /// - /// - /// This method saves some time and effort over the GetGroup method - /// because it does not have to open a group to populate a full Group - /// object. - /// - private SamRidEnumeration GetGroupSre(string groupName) - { - foreach (var sre in EnumerateGroups()) - if (sre.Name.Equals(groupName, StringComparison.CurrentCultureIgnoreCase)) - return sre; - - throw new GroupNotFoundException(groupName, context.target); - } - /// /// Find a group by SID and return a object /// representing the group. @@ -1134,31 +1114,6 @@ namespace System.Management.Automation.SecurityAccountsManager throw new GroupNotFoundException(sid.ToString(), sid); } - /// - /// Find a named user and return a object - /// representing the user. - /// - /// Name of the user to search for. - /// - /// A SamRidEnumeration object representing the user. - /// - /// - /// Thrown when the specified user is not found. - /// - /// - /// This method saves some time and effort over the GetUser method - /// because it does not have to open a group to populate a full LocalUser - /// object. - /// - private SamRidEnumeration GetUserSre(string userName) - { - foreach (var sre in EnumerateGroups()) - if (sre.Name.Equals(userName, StringComparison.CurrentCultureIgnoreCase)) - return sre; - - throw new GroupNotFoundException(userName, userName); - } - /// /// Find a user by SID and return a object /// representing the user. @@ -1205,14 +1160,12 @@ namespace System.Management.Automation.SecurityAccountsManager do { - status = SamApi.SamEnumerateUsersInDomain2(domainHandle, - ref context, - 0, - SamApi.SAM_USER_ENUMERATION_FILTER_LOCAL, - //0, // non-filtered - out buffer, - 1, - out countReturned); + status = SamApi.SamEnumerateUsersInDomain(domainHandle, + ref context, + 0, + out buffer, + 1, + out countReturned); if (status == NtStatus.STATUS_MORE_ENTRIES && countReturned == 1) { @@ -1350,6 +1303,8 @@ namespace System.Management.Automation.SecurityAccountsManager status = SamApi.SamDeleteAlias(aliasHandle); ThrowOnFailure(status); + + aliasHandle = IntPtr.Zero; // The handle is freed internally if SamDeleteAlias succeeds } finally { @@ -1829,6 +1784,8 @@ namespace System.Management.Automation.SecurityAccountsManager status = SamApi.SamDeleteUser(userHandle); ThrowOnFailure(status); + + userHandle = IntPtr.Zero; // The handle is freed internally if SamDeleteUser succeeds } finally { @@ -2677,7 +2634,7 @@ namespace System.Management.Automation.SecurityAccountsManager try { - SamApi.SamRidToSid(domainHandle, rid, out sidBytes); + status = SamApi.SamRidToSid(domainHandle, rid, out sidBytes); if (status == NtStatus.STATUS_NOT_FOUND) throw new InternalException(status, @@ -2808,7 +2765,7 @@ namespace System.Management.Automation.SecurityAccountsManager // Ideally , accountname should be processed to hold only accout name (without domain) // as we are keeping the domain in 'DomainName' variable. - int index = accountName.IndexOf("\\"); + int index = accountName.IndexOf("\\", StringComparison.CurrentCultureIgnoreCase); if (index > -1) { accountName = accountName.Substring(index + 1); diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/SamApi.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/SamApi.cs index 680a28962..b8e14b748 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/SamApi.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/SamApi.cs @@ -407,60 +407,16 @@ namespace System.Management.Automation.SecurityAccountsManager.Native.NtSam internal static extern UInt32 SamAddMemberToAlias(IntPtr aliasHandle, byte[] memberId); // PSID - [DllImport("samlib.dll")] - internal static extern UInt32 SamAddMultipleMembersToAlias(IntPtr aliasHandle, - IntPtr memberIds, // PSID - UInt32 memberCount); - [DllImport("samlib.dll")] internal static extern UInt32 SamRemoveMemberFromAlias(IntPtr aliasHandle, byte[] memberId); // PSID - [DllImport("samlib.dll")] - internal static extern UInt32 SamRemoveMultipleMembersFromAlias(IntPtr aliasHandle, - IntPtr memberIds, // PSID - UInt32 memberCount); - [DllImport("samlib.dll")] internal static extern UInt32 SamGetMembersInAlias(IntPtr aliasHandle, out IntPtr memberIds, // PSID ** out UInt32 memberCount); #endregion Alias Functions - #region Group Functions - [DllImport("samlib.dll")] - internal static extern UInt32 SamEnumerateGroupsInDomain(IntPtr domainHandle, - ref UInt32 enumerationContext, - out IntPtr buffer, - UInt32 preferredMaximumLength, - out UInt32 countReturned); - - [DllImport("samlib.dll")] - internal static extern UInt32 SamCreateGroupInDomain(IntPtr domainHandle, - ref UNICODE_STRING accountName, - UInt32 desiredAccess, - out IntPtr groupHandle, - out UInt32 relativeId); - - - [DllImport("samlib.dll")] - internal static extern UInt32 SamOpenGroup(IntPtr domainHandle, - UInt32 desiredAccess, - UInt32 groupId, - out IntPtr groupHandle); - - [DllImport("samlib.dll")] - internal static extern UInt32 SamQueryInformationGroup(IntPtr groupHandle, - GROUP_INFORMATION_CLASS groupInformationClass, - out IntPtr buffer); - - - [DllImport("samlib.dll")] - internal static extern UInt32 SamSetInformationGroup(IntPtr groupHandle, - GROUP_INFORMATION_CLASS groupInformationClass, - IntPtr buffer); - #endregion Group Functions - #region User Functions [DllImport("samlib.dll")] internal static extern UInt32 SamOpenUser(IntPtr domainHandle, @@ -479,22 +435,6 @@ namespace System.Management.Automation.SecurityAccountsManager.Native.NtSam UInt32 preferredMaximumLength, out UInt32 countReturned); - [DllImport("samlib.dll")] - internal static extern UInt32 SamEnumerateUsersInDomain2(IntPtr domainHandle, - ref UInt32 enumerationContext, - UInt32 userAccountControl, - UInt32 filter, - out IntPtr buffer, - UInt32 preferredMaximumLength, - out UInt32 countReturned); - - [DllImport("samlib.dll")] - internal static extern UInt32 SamCreateUserInDomain(IntPtr domainHandle, - ref UNICODE_STRING accountName, - UInt32 desiredAccess, - out IntPtr userHandle, - out UInt32 relativeId); - [DllImport("samlib.dll")] internal static extern UInt32 SamCreateUser2InDomain(IntPtr domainHandle, ref UNICODE_STRING accountName, diff --git a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/StringUtil.cs b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/StringUtil.cs index b1c653c93..afc20f126 100644 --- a/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/StringUtil.cs +++ b/src/Microsoft.PowerShell.LocalAccounts/LocalAccounts/StringUtil.cs @@ -8,6 +8,14 @@ namespace System.Management.Automation.SecurityAccountsManager /// internal class StringUtil { + /// + /// Private constructor to precent auto-generation of a default constructor with greater accessability. + /// + private StringUtil() + { + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal static string Format(string str) { return string.Format(CultureInfo.CurrentCulture, str); diff --git a/src/Microsoft.PowerShell.Security/security/CertificateProvider.cs b/src/Microsoft.PowerShell.Security/security/CertificateProvider.cs index c095c3942..f1c993950 100644 --- a/src/Microsoft.PowerShell.Security/security/CertificateProvider.cs +++ b/src/Microsoft.PowerShell.Security/security/CertificateProvider.cs @@ -3843,6 +3843,7 @@ namespace Microsoft.PowerShell.Commands /// /// get a list of store names at the specified location /// + [ArchitectureSensitive] internal static List GetStoreNamesAtLocation(StoreLocation location) { Security.NativeMethods.CertStoreFlags locationFlag = diff --git a/src/Microsoft.PowerShell.Security/security/SignatureCommands.cs b/src/Microsoft.PowerShell.Security/security/SignatureCommands.cs index 750457fdf..c9f05a235 100644 --- a/src/Microsoft.PowerShell.Security/security/SignatureCommands.cs +++ b/src/Microsoft.PowerShell.Security/security/SignatureCommands.cs @@ -83,6 +83,7 @@ namespace Microsoft.PowerShell.Commands /// digital signature. /// [Parameter(Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "ByContent")] + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public string[] SourcePathOrExtension { get @@ -622,4 +623,4 @@ namespace Microsoft.PowerShell.Commands return SigningOption.AddFullCertificateChainExceptRoot; } } -} \ No newline at end of file +} diff --git a/src/Microsoft.PowerShell.Security/security/Utils.cs b/src/Microsoft.PowerShell.Security/security/Utils.cs index fd14b42df..966e9ad4e 100644 --- a/src/Microsoft.PowerShell.Security/security/Utils.cs +++ b/src/Microsoft.PowerShell.Security/security/Utils.cs @@ -131,6 +131,7 @@ namespace Microsoft.PowerShell /// /// /// + [ArchitectureSensitive] internal static string GetStringFromSecureString(SecureString ss) { IntPtr p = Marshal.SecureStringToGlobalAllocUnicode(ss); diff --git a/src/Modules/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psm1 b/src/Modules/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psm1 index 85eaf1533..2328d1dc9 100644 --- a/src/Modules/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psm1 +++ b/src/Modules/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psm1 @@ -572,7 +572,7 @@ function ConvertFrom-SddlString [CmdletBinding(HelpUri = "http://go.microsoft.com/fwlink/?LinkId=623636")] param( ## The string representing the security descriptor in SDDL syntax - [Parameter(Mandatory, Position = 0)] + [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)] [String] $Sddl, ## The type of rights that this SDDL string represents, if any. @@ -584,126 +584,157 @@ function ConvertFrom-SddlString $Type ) - ## Translates a SID into a NT Account - function ConvertTo-NtAccount + Begin { - param($Sid) - - if($Sid) + # On CoreCLR CryptoKeyRights and ActiveDirectoryRights are not supported. + if ($PSEdition -eq "Core" -and ($Type -eq "CryptoKeyRights" -or $Type -eq "ActiveDirectoryRights")) { - $securityIdentifier = [System.Security.Principal.SecurityIdentifier] $Sid - - try + $errorId = "TypeNotSupported" + $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidArgument + $errorMessage = [Microsoft.PowerShell.Commands.UtilityResources]::TypeNotSupported -f $Type + $exception = [System.ArgumentException]::New($errorMessage) + $errorRecord = [System.Management.Automation.ErrorRecord]::New($exception, $errorId, $errorCategory, $null) + $PSCmdlet.ThrowTerminatingError($errorRecord) + } + + ## Translates a SID into a NT Account + function ConvertTo-NtAccount + { + param($Sid) + + if($Sid) { - $ntAccount = $securityIdentifier.Translate([System.Security.Principal.NTAccount]).ToString() - } - catch{} - - $ntAccount - } - } - - ## Gets the access rights that apply to an access mask, preferring right types - ## of 'Type' if specified. - function Get-AccessRights - { - param($AccessMask, $Type) - - ## All the types of access rights understood by .NET - $rightTypes = [Ordered] @{ - "FileSystemRights" = [System.Security.AccessControl.FileSystemRights] - "RegistryRights" = [System.Security.AccessControl.RegistryRights] - "ActiveDirectoryRights" = [System.DirectoryServices.ActiveDirectoryRights] - "MutexRights" = [System.Security.AccessControl.MutexRights] - "SemaphoreRights" = [System.Security.AccessControl.SemaphoreRights] - "CryptoKeyRights" = [System.Security.AccessControl.CryptoKeyRights] - "EventWaitHandleRights" = [System.Security.AccessControl.EventWaitHandleRights] - } - $typesToExamine = $rightTypes.Values + $securityIdentifier = [System.Security.Principal.SecurityIdentifier] $Sid - ## If they know the access mask represents a certain type, prefer its names - ## (i.e.: CreateLink for the registry over CreateDirectories for the filesystem) - if($Type) - { - $typesToExamine = @($rightTypes[$Type]) + $typesToExamine + try + { + $ntAccount = $securityIdentifier.Translate([System.Security.Principal.NTAccount]).ToString() + } + catch{} + + $ntAccount + } } + + ## Gets the access rights that apply to an access mask, preferring right types + ## of 'Type' if specified. + function Get-AccessRights + { + param($AccessMask, $Type) + + if ($PSEdition -eq "Core") + { + ## All the types of access rights understood by .NET Core + $rightTypes = [Ordered] @{ + "FileSystemRights" = [System.Security.AccessControl.FileSystemRights] + "RegistryRights" = [System.Security.AccessControl.RegistryRights] + "MutexRights" = [System.Security.AccessControl.MutexRights] + "SemaphoreRights" = [System.Security.AccessControl.SemaphoreRights] + "EventWaitHandleRights" = [System.Security.AccessControl.EventWaitHandleRights] + } + } + else + { + ## All the types of access rights understood by .NET + $rightTypes = [Ordered] @{ + "FileSystemRights" = [System.Security.AccessControl.FileSystemRights] + "RegistryRights" = [System.Security.AccessControl.RegistryRights] + "ActiveDirectoryRights" = [System.DirectoryServices.ActiveDirectoryRights] + "MutexRights" = [System.Security.AccessControl.MutexRights] + "SemaphoreRights" = [System.Security.AccessControl.SemaphoreRights] + "CryptoKeyRights" = [System.Security.AccessControl.CryptoKeyRights] + "EventWaitHandleRights" = [System.Security.AccessControl.EventWaitHandleRights] + } + } + $typesToExamine = $rightTypes.Values + + ## If they know the access mask represents a certain type, prefer its names + ## (i.e.: CreateLink for the registry over CreateDirectories for the filesystem) + if($Type) + { + $typesToExamine = @($rightTypes[$Type]) + $typesToExamine + } - ## Stores the access types we've found that apply - $foundAccess = @() + ## Stores the access types we've found that apply + $foundAccess = @() - ## Store the access types we've already seen, so that we don't report access - ## flags that are essentially duplicate. Many of the access values in the different - ## enumerations have the same value but with different names. - $foundValues = @{} + ## Store the access types we've already seen, so that we don't report access + ## flags that are essentially duplicate. Many of the access values in the different + ## enumerations have the same value but with different names. + $foundValues = @{} - ## Go through the entries in the different right types, and see if they apply to the - ## provided access mask. If they do, then add that to the result. - foreach($rightType in $typesToExamine) - { - foreach($accessFlag in [Enum]::GetNames($rightType)) + ## Go through the entries in the different right types, and see if they apply to the + ## provided access mask. If they do, then add that to the result. + foreach($rightType in $typesToExamine) { - $longKeyValue = [long] $rightType::$accessFlag - if(-not $foundValues.ContainsKey($longKeyValue)) + foreach($accessFlag in [Enum]::GetNames($rightType)) { - $foundValues[$longKeyValue] = $true - if(($AccessMask -band $longKeyValue) -eq ($longKeyValue)) + $longKeyValue = [long] $rightType::$accessFlag + if(-not $foundValues.ContainsKey($longKeyValue)) { - $foundAccess += $accessFlag + $foundValues[$longKeyValue] = $true + if(($AccessMask -band $longKeyValue) -eq ($longKeyValue)) + { + $foundAccess += $accessFlag + } } } } + + $foundAccess | Sort-Object } - $foundAccess | Sort-Object + ## Converts an ACE into a string representation + function ConvertTo-AceString + { + param( + [Parameter(ValueFromPipeline)] + $Ace, + $Type + ) + + process + { + foreach($aceEntry in $Ace) + { + $AceString = (ConvertTo-NtAccount $aceEntry.SecurityIdentifier) + ": " + $aceEntry.AceQualifier + if($aceEntry.AceFlags -ne "None") + { + $AceString += " " + $aceEntry.AceFlags + } + + if($aceEntry.AccessMask) + { + $foundAccess = Get-AccessRights $aceEntry.AccessMask $Type + + if($foundAccess) + { + $AceString += " ({0})" -f ($foundAccess -join ", ") + } + } + + $AceString + } + } + } } - ## Converts an ACE into a string representation - function ConvertTo-AceString + Process { - param( - [Parameter(ValueFromPipeline)] - $Ace, - $Type - ) + $rawSecurityDescriptor = [Security.AccessControl.CommonSecurityDescriptor]::new($false,$false,$Sddl) - process - { - foreach($aceEntry in $Ace) - { - $AceString = (ConvertTo-NtAccount $aceEntry.SecurityIdentifier) + ": " + $aceEntry.AceQualifier - if($aceEntry.AceFlags -ne "None") - { - $AceString += " " + $aceEntry.AceFlags - } + $owner = ConvertTo-NtAccount $rawSecurityDescriptor.Owner + $group = ConvertTo-NtAccount $rawSecurityDescriptor.Group + $discretionaryAcl = ConvertTo-AceString $rawSecurityDescriptor.DiscretionaryAcl $Type + $systemAcl = ConvertTo-AceString $rawSecurityDescriptor.SystemAcl $Type - if($aceEntry.AccessMask) - { - $foundAccess = Get-AccessRights $aceEntry.AccessMask $Type - - if($foundAccess) - { - $AceString += " ({0})" -f ($foundAccess -join ", ") - } - } - - $AceString - } + [PSCustomObject] @{ + Owner = $owner + Group = $group + DiscretionaryAcl = @($discretionaryAcl) + SystemAcl = @($systemAcl) + RawDescriptor = $rawSecurityDescriptor } } - - $rawSecurityDescriptor = [Security.AccessControl.CommonSecurityDescriptor]::new($false,$false,$Sddl) - - $owner = ConvertTo-NtAccount $rawSecurityDescriptor.Owner - $group = ConvertTo-NtAccount $rawSecurityDescriptor.Group - $discretionaryAcl = ConvertTo-AceString $rawSecurityDescriptor.DiscretionaryAcl $Type - $systemAcl = ConvertTo-AceString $rawSecurityDescriptor.SystemAcl $Type - - [PSCustomObject] @{ - Owner = $owner - Group = $group - DiscretionaryAcl = @($discretionaryAcl) - SystemAcl = @($systemAcl) - RawDescriptor = $rawSecurityDescriptor - } -} +} \ No newline at end of file diff --git a/src/Modules/PSDiagnostics/PSDiagnostics.psm1 b/src/Modules/PSDiagnostics/PSDiagnostics.psm1 index 7df91bb795a53b3e59bd6880bff00297124c978f..bc893f13db11cb01d070e736661007ced98cc6a1 100644 GIT binary patch delta 383 zcmZvYK}y455QSgBg#_G)2bfj`yRe=?+!j|ZQg=mDEykoakt!m+g7BZBf*|NZJcKK8 z;c5Klw~7l1lbO8t{`bGh$8+-el04pLvlXQpX(-c{HZ)ePT*n{{RjE{02lO5_g_)r0 zpxtJ^ptp4dGvTWZ?p~&wMK@;CI<==uG_ES~Ep!d$Zl-Dm^bORA#yoD3d>U2{&diRgj<`43O?>>*kHk$wTQ*hnh? delta 18 acmcb$gYnuH#to|?CZCGb*nBRkg%JQ;!wC-n diff --git a/src/Modules/PSGet/PSGet.Resource.psd1 b/src/Modules/PSGet/PSGet.Resource.psd1 index 60cd290d6b1b3bcea6c9af9f5f315143f07f3472..6dfd08222a2a507b315dee74819f83970a894f7c 100644 GIT binary patch delta 1739 zcmcgtT}V@582-LI;#{Y>m~(mNwzFx9^s~%U^_H_;E85dAAq8jImgW4)}Cg;-{Vi9z?2WJt84)x@>4H}y&JJKaig;QEqCdov3}Al6seiX~3q6io z3xM9>7eb@Jlx__;X{1V~!2)TchJ1&CQD9YZD@Gt2!)pBd6EE_g^-$A{Y*yqrB8v)k zP%7r6y8{-)Uq;PUMdTfqZj3pXpFn8QmfwerAXE?LJvr-u29mGb6$>lY zW}5Jn<~D)o3EErZ?)k5j=}f(YtXI;SNK9ITzblr>47@AYDYllK#wl7X6b7Eb1@big ztLf=$4~$R;DjKzuW*c0z<+CMY`^<;Q?M7-%Px^VKJKbBcp(BRC zGdin3^>QC=sJA=BP7{MrZ4833&h@VWzT4DGiEEvC0o@=@|#J9N?r(M?z3rgN` t=z}GEWnKDX(+{O~7-i^WrWWBWJ~4A!HCy@fyO;cmn~pCk)Nhw@`3L=)v+V!? delta 36 ucmV+<0NekT=>){d1hDo # When new module has some commands, no clobber error if # - AllowClobber is specified, or # - Installing to the same module base, or # - Update operation - if($CurrentModuleInfo.ExportedCommands.Keys -and + if($CurrentModuleInfo.ExportedCommands.Keys.Count -and -not $AllowClobber -and - -not $IsUpdateOperation -and - ($InstalledModuleInfo -and -not $InstalledModuleInfo.ModuleBase.StartsWith($InstallLocation, [System.StringComparison]::OrdinalIgnoreCase))) + -not $IsUpdateOperation) { - # Throw an error if there is a command with the same name. - # Get-Command loads the module if a command is already available. - $AvailableCommand = Microsoft.PowerShell.Core\Get-Command -Name $CurrentModuleInfo.ExportedCommands.Values.Name ` - -ErrorAction SilentlyContinue ` - -WarningAction SilentlyContinue | - Microsoft.PowerShell.Utility\Select-Object -First 1 -ErrorAction SilentlyContinue - if($AvailableCommand) + # Remove the version folder on 5.0 to get the actual module base folder without version + if(Test-ModuleSxSVersionSupport) { - $message = $LocalizedData.ModuleCommandAlreadyAvailable -f ($AvailableCommand.Name, $CurrentModuleInfo.Name) - ThrowError -ExceptionName 'System.InvalidOperationException' ` - -ExceptionMessage $message ` - -ErrorId 'CommandAlreadyAvailable' ` - -CallerPSCmdlet $PSCmdlet ` - -ErrorCategory InvalidOperation + $InstallLocation = Microsoft.PowerShell.Management\Split-Path -Path $InstallLocation + } - return $false + $InstalledModuleInfo = Test-ModuleInstalled -Name $CurrentModuleInfo.Name + if(-not $InstalledModuleInfo -or -not $InstalledModuleInfo.ModuleBase.StartsWith($InstallLocation, [System.StringComparison]::OrdinalIgnoreCase)) + { + # Throw an error if there is a command with the same name from a different source. + # Get-Command loads the module if a command is already available. + # To avoid that, appending '*' at the end for each name then comparing the results. + $CommandNames = $CurrentModuleInfo.ExportedCommands.Values.Name + $CommandNamesWithWildcards = $CommandNames | Microsoft.PowerShell.Core\Foreach-Object { "$_*" } + + $AvailableCommand = Microsoft.PowerShell.Core\Get-Command -Name $CommandNamesWithWildcards ` + -ErrorAction SilentlyContinue ` + -WarningAction SilentlyContinue | + Microsoft.PowerShell.Core\Where-Object { ($CommandNames -contains $_.Name) -and + ($_.Source -ne $CurrentModuleInfo.Name) } | + Microsoft.PowerShell.Utility\Select-Object -First 1 -ErrorAction SilentlyContinue + if($AvailableCommand) + { + $message = $LocalizedData.ModuleCommandAlreadyAvailable -f ($AvailableCommand.Name, $CurrentModuleInfo.Name) + ThrowError -ExceptionName 'System.InvalidOperationException' ` + -ExceptionMessage $message ` + -ErrorId 'CommandAlreadyAvailable' ` + -CallerPSCmdlet $PSCmdlet ` + -ErrorCategory InvalidOperation + + return $false + } } } return $true } -function ValidateAndGet-CatalogSigningIssuer +function ValidateAndGet-AuthenticodeSignature { [CmdletBinding()] Param ( [Parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] - [string] - $ModuleBasePath, - - [Parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] - [string] - $ModuleName, - - [Parameter()] - [Switch] - $IsLocal + [PSModuleInfo] + $ModuleInfo ) + $ModuleDetails = $null + $AuthenticodeSignature = $null + + $ModuleName = $ModuleInfo.Name + $ModuleBasePath = $ModuleInfo.ModuleBase $CatalogFileName = "$ModuleName.cat" $CatalogFilePath = Microsoft.PowerShell.Management\Join-Path -Path $ModuleBasePath -ChildPath $CatalogFileName - $AuthenticodeSignature = $null - if(Microsoft.PowerShell.Management\Test-Path -Path $CatalogFilePath -PathType Leaf) { $message = $LocalizedData.CatalogFileFound -f ($CatalogFileName, $ModuleName) @@ -13720,72 +13871,72 @@ function ValidateAndGet-CatalogSigningIssuer $AuthenticodeSignature = Microsoft.PowerShell.Security\Get-AuthenticodeSignature -FilePath $CatalogFilePath - if(-not $IsLocal) + if(-not $AuthenticodeSignature -or ($AuthenticodeSignature.Status -ne "Valid")) { - if(-not $AuthenticodeSignature -or ($AuthenticodeSignature.Status -ne "Valid")) - { - $message = $LocalizedData.InvalidModuleAuthenticodeSignature -f ($ModuleName, $CatalogFileName) - ThrowError -ExceptionName 'System.InvalidOperationException' ` - -ExceptionMessage $message ` - -ErrorId 'InvalidAuthenticodeSignature' ` - -CallerPSCmdlet $PSCmdlet ` - -ErrorCategory InvalidOperation + $message = $LocalizedData.InvalidModuleAuthenticodeSignature -f ($ModuleName, $CatalogFileName) + ThrowError -ExceptionName 'System.InvalidOperationException' ` + -ExceptionMessage $message ` + -ErrorId 'InvalidAuthenticodeSignature' ` + -CallerPSCmdlet $PSCmdlet ` + -ErrorCategory InvalidOperation + return + } + + Write-Verbose -Message ($LocalizedData.ValidAuthenticodeSignature -f @($CatalogFileName, $ModuleName)) + + if(Get-Command -Name Test-FileCatalog -Module Microsoft.PowerShell.Security -ErrorAction SilentlyContinue) + { + Write-Verbose -Message ($LocalizedData.ValidatingCatalogSignature -f @($ModuleName, $CatalogFileName)) + + # Skip the PSGetModuleInfo.xml and ModuleName.cat files in the catalog validation + $TestFileCatalogResult = Microsoft.PowerShell.Security\Test-FileCatalog -Path $ModuleBasePath ` + -CatalogFilePath $CatalogFilePath ` + -FilesToSkip $script:PSGetItemInfoFileName,'*.cat' ` + -Detailed ` + -ErrorAction SilentlyContinue + if(-not $TestFileCatalogResult -or + ($TestFileCatalogResult.Status -ne "Valid") -or + ($TestFileCatalogResult.Signature.Status -ne "Valid")) + { + $message = $LocalizedData.InvalidCatalogSignature -f ($ModuleName, $CatalogFileName) + ThrowError -ExceptionName 'System.InvalidOperationException' ` + -ExceptionMessage $message ` + -ErrorId 'InvalidCatalogSignature' ` + -CallerPSCmdlet $PSCmdlet ` + -ErrorCategory InvalidOperation return } - - Write-Verbose -Message ($LocalizedData.ValidAuthenticodeSignature -f @($CatalogFileName, $ModuleName)) - - if(Get-Command -Name Test-FileCatalog -Module Microsoft.PowerShell.Security -ErrorAction SilentlyContinue) + else { - Write-Verbose -Message ($LocalizedData.ValidatingCatalogSignature -f @($ModuleName, $CatalogFileName)) - - # Skip the PSGetModuleInfo.xml and ModuleName.cat files in the catalog validation - $TestFileCatalogResult = Microsoft.PowerShell.Security\Test-FileCatalog -Path $ModuleBasePath ` - -CatalogFilePath $CatalogFilePath ` - -FilesToSkip $script:PSGetItemInfoFileName ` - -Detailed - if(-not $TestFileCatalogResult -or - ($TestFileCatalogResult.Status -ne "Valid") -or - ($TestFileCatalogResult.Signature.Status -ne "Valid")) - { - $message = $LocalizedData.InvalidCatalogSignature -f ($ModuleName, $CatalogFileName) - ThrowError -ExceptionName 'System.InvalidOperationException' ` - -ExceptionMessage $message ` - -ErrorId 'InvalidCatalogSignature' ` - -CallerPSCmdlet $PSCmdlet ` - -ErrorCategory InvalidOperation - return - } - else - { - Write-Verbose -Message ($LocalizedData.ValidCatalogSignature -f @($CatalogFileName, $ModuleName)) - } + Write-Verbose -Message ($LocalizedData.ValidCatalogSignature -f @($CatalogFileName, $ModuleName)) } } } else { - if($IsLocal) - { - Write-Verbose -Message ($LocalizedData.CatalogFileNotFoundInAvailableModule -f ($CatalogFileName, $ModuleName)) - } - else - { - Write-Verbose -Message ($LocalizedData.CatalogFileNotFoundInNewModule -f ($CatalogFileName, $ModuleName)) - } + Write-Verbose -Message ($LocalizedData.CatalogFileNotFoundInNewModule -f ($CatalogFileName, $ModuleName)) } if($AuthenticodeSignature) { - return Get-AuthentcodeIssuer -AuthenticodeSignature $AuthenticodeSignature + $ModuleDetails = @{} + $ModuleDetails['AuthenticodeSignature'] = $AuthenticodeSignature + $ModuleDetails['Version'] = $ModuleInfo.Version + $ModuleDetails['ModuleBase']=$ModuleInfo.ModuleBase + $ModuleDetails['IsMicrosoftCertificate'] = Test-MicrosoftCertificate -AuthenticodeSignature $AuthenticodeSignature + $ModuleDetails['Publisher'] = Get-AuthenticodePublisher -AuthenticodeSignature $AuthenticodeSignature + + $message = $LocalizedData.NewModuleVersionDetailsForPublisherValidation -f ($ModuleInfo.Name, $ModuleInfo.Version, $ModuleDetails.Publisher, $ModuleDetails.IsMicrosoftCertificate) + Write-Debug $message } + + return $ModuleDetails } -function Get-AuthentcodeIssuer +function Get-AuthenticodePublisher { [CmdletBinding()] - [OutputType([bool])] Param ( [Parameter(Mandatory=$true)] @@ -13793,8 +13944,7 @@ function Get-AuthentcodeIssuer $AuthenticodeSignature ) - if(($AuthenticodeSignature.Status -eq "Valid") -and - $AuthenticodeSignature.SignerCertificate) + if($AuthenticodeSignature.SignerCertificate) { $chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain $null = $chain.Build($AuthenticodeSignature.SignerCertificate) @@ -13819,6 +13969,121 @@ function Get-AuthentcodeIssuer } } +function Get-InstalledModuleAuthenticodeSignature +{ + [CmdletBinding()] + Param( + [Parameter(Mandatory=$true)] + [PSModuleInfo] + $InstalledModuleInfo, + + [Parameter(Mandatory=$true)] + [string] + $InstallLocation + ) + + $ModuleName = $InstalledModuleInfo.Name + + # Priority order for getting the published details of the installed module: + # 1. Latest version under the $InstallLocation + # 2. Latest available version in $PSModulePath + # 3. $InstalledModuleInfo + $AvailableModules = Microsoft.PowerShell.Core\Get-Module -ListAvailable ` + -Name $ModuleName ` + -ErrorAction SilentlyContinue ` + -WarningAction SilentlyContinue ` + -Verbose:$false | + Microsoft.PowerShell.Utility\Sort-Object -Property Version -Descending + + # Remove the version folder on 5.0 to get the actual module base folder without version + if(Test-ModuleSxSVersionSupport) + { + $InstallLocation = Microsoft.PowerShell.Management\Split-Path -Path $InstallLocation + } + + $SourceModule = $AvailableModules | Microsoft.PowerShell.Core\Where-Object { + $_.ModuleBase.StartsWith($InstallLocation, [System.StringComparison]::OrdinalIgnoreCase) + } | Microsoft.PowerShell.Utility\Select-Object -First 1 + + if(-not $SourceModule) + { + $SourceModule = $AvailableModules | Microsoft.PowerShell.Utility\Select-Object -First 1 + } + else + { + $SourceModule = $InstalledModuleInfo + } + + $SignedFilePath = $SourceModule.Path + + $CatalogFileName = "$ModuleName.cat" + $CatalogFilePath = Microsoft.PowerShell.Management\Join-Path -Path $SourceModule.ModuleBase -ChildPath $CatalogFileName + + if(Microsoft.PowerShell.Management\Test-Path -Path $CatalogFilePath -PathType Leaf) + { + $message = $LocalizedData.CatalogFileFound -f ($CatalogFileName, $ModuleName) + Write-Debug -Message $message + + $SignedFilePath = $CatalogFilePath + } + else + { + Write-Debug -Message ($LocalizedData.CatalogFileNotFoundInAvailableModule -f ($CatalogFileName, $ModuleName)) + } + + $message = "Using the previously-installed module '{0}' with version '{1}' under '{2}' for getting the publisher details." -f ($SourceModule.Name, $SourceModule.Version, $SourceModule.ModuleBase) + Write-Debug -Message $message + + $message = "Using the '{0}' file for getting the authenticode signature." -f ($SignedFilePath) + Write-Debug -Message $message + + $AuthenticodeSignature = Microsoft.PowerShell.Security\Get-AuthenticodeSignature -FilePath $SignedFilePath + $ModuleDetails = $null + + if($AuthenticodeSignature) + { + $ModuleDetails = @{} + $ModuleDetails['AuthenticodeSignature'] = $AuthenticodeSignature + $ModuleDetails['Version'] = $SourceModule.Version + $ModuleDetails['ModuleBase']=$SourceModule.ModuleBase + $ModuleDetails['IsMicrosoftCertificate'] = Test-MicrosoftCertificate -AuthenticodeSignature $AuthenticodeSignature + $ModuleDetails['Publisher'] = Get-AuthenticodePublisher -AuthenticodeSignature $AuthenticodeSignature + + $message = $LocalizedData.SourceModuleDetailsForPublisherValidation -f ($ModuleName, $SourceModule.Version, $SourceModule.ModuleBase, $ModuleDetails.Publisher, $ModuleDetails.IsMicrosoftCertificate) + Write-Debug $message + } + + return $ModuleDetails +} + +function Test-MicrosoftCertificate +{ + [CmdletBinding()] + param( + [Parameter(Mandatory=$true)] + [System.Management.Automation.Signature] + $AuthenticodeSignature + ) + + if($AuthenticodeSignature.SignerCertificate) + { + try + { + $X509Chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain + $null = $X509Chain.Build($AuthenticodeSignature.SignerCertificate) + } + catch + { + return $false + } + + $SafeX509ChainHandle = [Microsoft.PowerShell.Commands.PowerShellGet.Win32Helpers]::CertDuplicateCertificateChain($X509Chain.ChainContext) + return [Microsoft.PowerShell.Commands.PowerShellGet.Win32Helpers]::IsMicrosoftCertificate($SafeX509ChainHandle) + } + + return $false +} + function Test-ValidManifestModule { [CmdletBinding()] @@ -13835,6 +14100,10 @@ function Test-ValidManifestModule [string] $InstallLocation, + [Parameter()] + [Switch] + $SkipPublisherCheck, + [Parameter()] [Switch] $AllowClobber, @@ -13865,8 +14134,19 @@ function Test-ValidManifestModule { $ValidationResult = Validate-ModuleAuthenticodeSignature -CurrentModuleInfo $PSModuleInfo ` -InstallLocation $InstallLocation ` - -AllowClobber:$AllowClobber ` - -IsUpdateOperation:$IsUpdateOperation + -SkipPublisherCheck:$SkipPublisherCheck + + if($ValidationResult) + { + # Checking for the possible command clobbering. + $ValidationResult = Validate-ModuleCommandAlreadyAvailable -CurrentModuleInfo $PSModuleInfo ` + -InstallLocation $InstallLocation ` + -AllowClobber:$AllowClobber ` + -IsUpdateOperation:$IsUpdateOperation + + + } + if(-not $ValidationResult) { $PSModuleInfo = $null diff --git a/src/System.Management.Automation/CoreCLR/CorePsExtensions.cs b/src/System.Management.Automation/CoreCLR/CorePsExtensions.cs index 0c6ae0caa..5674327cd 100644 --- a/src/System.Management.Automation/CoreCLR/CorePsExtensions.cs +++ b/src/System.Management.Automation/CoreCLR/CorePsExtensions.cs @@ -1620,7 +1620,7 @@ namespace System.Management.Automation namespace Microsoft.PowerShell.CoreCLR { - using System; + using System.IO; using System.Management.Automation; /// @@ -1629,18 +1629,23 @@ namespace Microsoft.PowerShell.CoreCLR public static class AssemblyExtensions { /// - /// Loads an assembly given its file path. + /// Load an assembly given its file path. /// - /// The path of the file that contains the manifest of the assembly. + /// The path of the file that contains the manifest of the assembly. /// The loaded assembly. - public static Assembly LoadFrom(string assemblyFile) + public static Assembly LoadFrom(string assemblyPath) { - if (string.IsNullOrEmpty(assemblyFile)) - { - throw new ArgumentNullException("assemblyFile"); + return ClrFacade.LoadFrom(assemblyPath); } - return ClrFacade.LoadFrom(assemblyFile); + /// + /// Load an assembly given its byte stream + /// + /// The byte stream of assembly + /// The loaded assembly + public static Assembly LoadFrom(Stream assembly) + { + return ClrFacade.LoadFrom(assembly); } } } diff --git a/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DefaultFormatters/DotNetTypes_format_ps1xml.cs b/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DefaultFormatters/DotNetTypes_format_ps1xml.cs index 6a10c27d6..273169bac 100644 --- a/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DefaultFormatters/DotNetTypes_format_ps1xml.cs +++ b/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DefaultFormatters/DotNetTypes_format_ps1xml.cs @@ -537,8 +537,7 @@ namespace System.Management.Automation.Runspaces .AddHeader(Alignment.Right, label: "NPM(K)", width: 7) .AddHeader(Alignment.Right, label: "PM(K)", width: 8) .AddHeader(Alignment.Right, label: "WS(K)", width: 10) - .AddHeader(Alignment.Right, label: "VM(M)", width: 5) - .AddHeader(Alignment.Right, label: "CPU(s)", width: 8) + .AddHeader(Alignment.Right, label: "CPU(s)", width: 10) .AddHeader(Alignment.Right, width: 6) .AddHeader(Alignment.Right, width: 3) .AddHeader() @@ -547,13 +546,7 @@ namespace System.Management.Automation.Runspaces .AddScriptBlockColumn("[long]($_.NPM / 1024)") .AddScriptBlockColumn("[long]($_.PM / 1024)") .AddScriptBlockColumn("[long]($_.WS / 1024)") - .AddScriptBlockColumn("[long]($_.VM / 1048576)") - .AddScriptBlockColumn(@" -if ($_.CPU -ne $()) -{ - $_.CPU.ToString(""N"") -} - ") + .AddScriptBlockColumn(@"if ($_.CPU -ne $()) { $_.CPU.ToString(""N"") }") .AddPropertyColumn("Id") .AddPropertyColumn("SI") .AddPropertyColumn("ProcessName") @@ -600,21 +593,14 @@ if ($_.CPU -ne $()) TableControl.Create() .AddHeader(Alignment.Right, label: "Handles", width: 7) .AddHeader(Alignment.Right, label: "WS(K)", width: 10) - .AddHeader(Alignment.Right, label: "VM(M)", width: 5) .AddHeader(Alignment.Right, label: "CPU(s)", width: 8) .AddHeader(Alignment.Right, width: 6) - .AddHeader(width: 17) + .AddHeader(width: 22) .AddHeader() .StartRowDefinition() .AddPropertyColumn("HandleCount") .AddScriptBlockColumn("[long]($_.WS / 1024)") - .AddScriptBlockColumn("[long]($_.VM / 1048576)") - .AddScriptBlockColumn(@" - if ($_.CPU -ne $()) - { - $_.CPU.ToString(""N"") - } - ") + .AddScriptBlockColumn(@"if ($_.CPU -ne $()) { $_.CPU.ToString(""N"") }") .AddPropertyColumn("Id") .AddPropertyColumn("UserName") .AddPropertyColumn("ProcessName") diff --git a/src/System.Management.Automation/engine/COM/ComTypeInfo.cs b/src/System.Management.Automation/engine/COM/ComTypeInfo.cs index 9dc261b40..ab9bb3998 100644 --- a/src/System.Management.Automation/engine/COM/ComTypeInfo.cs +++ b/src/System.Management.Automation/engine/COM/ComTypeInfo.cs @@ -196,6 +196,7 @@ namespace System.Management.Automation /// /// reference to ITypeInfo from which to get TypeAttr /// + [ArchitectureSensitive] internal static COM.TYPEATTR GetTypeAttr(COM.ITypeInfo typeinfo) { IntPtr pTypeAttr; @@ -211,6 +212,7 @@ namespace System.Management.Automation /// /// /// + [ArchitectureSensitive] internal static COM.FUNCDESC GetFuncDesc(COM.ITypeInfo typeinfo, int index) { IntPtr pFuncDesc; diff --git a/src/System.Management.Automation/engine/ComInterop/ComBinderHelpers.cs b/src/System.Management.Automation/engine/ComInterop/ComBinderHelpers.cs index f5a1ca3ae..bac37e919 100644 --- a/src/System.Management.Automation/engine/ComInterop/ComBinderHelpers.cs +++ b/src/System.Management.Automation/engine/ComInterop/ComBinderHelpers.cs @@ -103,7 +103,7 @@ namespace System.Management.Automation.ComInterop { i.ToString(CultureInfo.InvariantCulture), method.Name, temps, - initTemps), curArgument.Restrictions, curArgument.Value); + initTemps), curArgument.Restrictions); } else { diff --git a/src/System.Management.Automation/engine/ComInterop/IDispatchComObject.cs b/src/System.Management.Automation/engine/ComInterop/IDispatchComObject.cs index 7b41bfc59..438433704 100644 --- a/src/System.Management.Automation/engine/ComInterop/IDispatchComObject.cs +++ b/src/System.Management.Automation/engine/ComInterop/IDispatchComObject.cs @@ -508,6 +508,20 @@ namespace System.Management.Automation.ComInterop { } } + if (typeAttr.typekind == ComTypes.TYPEKIND.TKIND_INTERFACE) + { + //We have typeinfo for custom interface. Get typeinfo for Dispatch interface. + typeInfo = ComTypeInfo.GetDispatchTypeInfoFromCustomInterfaceTypeInfo(typeInfo); + typeAttr = ComRuntimeHelpers.GetTypeAttrForTypeInfo(typeInfo); + } + + if (typeAttr.typekind == ComTypes.TYPEKIND.TKIND_COCLASS) + { + //We have typeinfo for the COClass. Find the default interface and get typeinfo for default interface. + typeInfo = ComTypeInfo.GetDispatchTypeInfoFromCoClassTypeInfo(typeInfo); + typeAttr = ComRuntimeHelpers.GetTypeAttrForTypeInfo(typeInfo); + } + ComTypeDesc typeDesc = ComTypeDesc.FromITypeInfo(typeInfo, typeAttr); ComMethodDesc getItem = null; diff --git a/src/System.Management.Automation/engine/CommandCompletion/CompletionAnalysis.cs b/src/System.Management.Automation/engine/CommandCompletion/CompletionAnalysis.cs index 24ceecc55..581e02489 100644 --- a/src/System.Management.Automation/engine/CommandCompletion/CompletionAnalysis.cs +++ b/src/System.Management.Automation/engine/CommandCompletion/CompletionAnalysis.cs @@ -1068,7 +1068,7 @@ namespace System.Management.Automation var configAst = Ast.GetAncestorAst(keywordAst); if (configAst != null) { - var namedBlockAst = keywordAst.Parent as NamedBlockAst; + var namedBlockAst = Ast.GetAncestorAst(keywordAst); if (namedBlockAst != null) { List allResources = new List(); diff --git a/src/System.Management.Automation/engine/ErrorPackage.cs b/src/System.Management.Automation/engine/ErrorPackage.cs index bc2aae41f..b93356738 100644 --- a/src/System.Management.Automation/engine/ErrorPackage.cs +++ b/src/System.Management.Automation/engine/ErrorPackage.cs @@ -1297,9 +1297,6 @@ namespace System.Management.Automation //Get Target object object targetObject = RemotingDecoder.GetPropertyValue(serializedErrorRecord, "TargetObject"); - //Get InvocationInfo - PSObject invocationInfo = RemotingDecoder.GetPropertyValue(serializedErrorRecord, "InvocationInfo"); - string exceptionMessage = null; if (serializedException != null) { @@ -1324,6 +1321,12 @@ namespace System.Management.Automation string errorCategory_TargetType = RemotingDecoder.GetPropertyValue(serializedErrorRecord, "ErrorCategory_TargetType"); string errorCategory_Message = RemotingDecoder.GetPropertyValue(serializedErrorRecord, "ErrorCategory_Message"); + //Get InvocationInfo (optional property) + PSObject invocationInfo = Microsoft.PowerShell.DeserializingTypeConverter.GetPropertyValue( + serializedErrorRecord, + "InvocationInfo", + Microsoft.PowerShell.DeserializingTypeConverter.RehydrationFlags.MissingPropertyOk); + //Get Error Detail (these note properties are optional, so can't right now use RemotingDecoder...) string errorDetails_Message = GetNoteValue(serializedErrorRecord, "ErrorDetails_Message") as string; diff --git a/src/System.Management.Automation/engine/InitialSessionState.cs b/src/System.Management.Automation/engine/InitialSessionState.cs index a4a129de7..aa818bea1 100644 --- a/src/System.Management.Automation/engine/InitialSessionState.cs +++ b/src/System.Management.Automation/engine/InitialSessionState.cs @@ -5474,7 +5474,12 @@ end internal const string DefaultMoreFunctionText = @" param([string[]]$paths) -$OutputEncoding = [System.Console]::OutputEncoding +# Nano needs to use Unicode, but Windows and Linux need the default +$OutputEncoding = if ($IsWindows -and $IsCore) { + [System.Text.Encoding]::Unicode +} else { + [System.Console]::OutputEncoding +} # Respect PAGER, use more on Windows, and use less on Linux if (Test-Path env:PAGER) { diff --git a/src/System.Management.Automation/engine/Modules/AnalysisCache.cs b/src/System.Management.Automation/engine/Modules/AnalysisCache.cs index af4acc2bf..09189ed04 100644 --- a/src/System.Management.Automation/engine/Modules/AnalysisCache.cs +++ b/src/System.Management.Automation/engine/Modules/AnalysisCache.cs @@ -7,6 +7,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Management.Automation.Internal; using System.Management.Automation.Language; using System.Management.Automation.Runspaces; using System.Text; @@ -104,6 +105,17 @@ namespace System.Management.Automation var moduleManifestProperties = PsUtils.GetModuleManifestProperties(modulePath, PsUtils.FastModuleManifestAnalysisPropertyNames); if (moduleManifestProperties != null) { + Version version; + if (ModuleUtils.IsModuleInVersionSubdirectory(modulePath, out version)) + { + var versionInManifest = LanguagePrimitives.ConvertTo(moduleManifestProperties["ModuleVersion"]); + if (version != versionInManifest) + { + ModuleIntrinsics.Tracer.WriteLine("ModuleVersion in manifest does not match versioned module directory, skipping module: {0}", modulePath); + return null; + } + } + result = new ConcurrentDictionary(3, moduleManifestProperties.Count, StringComparer.OrdinalIgnoreCase); var sawWildcard = false; diff --git a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs index 6e40156b3..f60a5ff75 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs @@ -1190,10 +1190,15 @@ namespace Microsoft.PowerShell.Commands if (module != null) { + Version directoryVersion; + if (!ModuleUtils.IsModuleInVersionSubdirectory(file, out directoryVersion) + || directoryVersion == module.Version) + { availableModules.Add(module); } } } + } ClearAnalysisCaches(); @@ -4982,7 +4987,7 @@ namespace Microsoft.PowerShell.Commands /// internal string GetAbsolutePath(string moduleBase, string path) { - if (!IsRooted(path) && (path.Contains('/') || path.Contains('\\')) && !path.Contains('$')) + if (!IsRooted(path) && (path.Contains('/') || path.Contains('\\'))) { return Path.Combine(moduleBase, path); } diff --git a/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs b/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs index 66f9e5ede..f6b08d4be 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleIntrinsics.cs @@ -797,6 +797,15 @@ namespace System.Management.Automation int psHomePosition = PathContainsSubstring(currentProcessModulePath, psHomeModulePath); // index of $PSHome\Modules in currentProcessModulePath if (psHomePosition >= 0) // if $PSHome\Modules IS found - insert location before $PSHome\Modules { +#if !CORECLR + // for bug 6678623, if we are running wow64 process (x86 32-bit process on 64-bit (amd64) OS), then ensure that exists in currentProcessModulePath / return value + if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess) + { + string userModulePath = GetPersonalModulePath(); + currentProcessModulePath = AddToPath(currentProcessModulePath, userModulePath, psHomePosition); + psHomePosition = PathContainsSubstring(currentProcessModulePath, psHomeModulePath); + } +#endif return AddToPath(currentProcessModulePath, programFilesModulePath, psHomePosition); } // if $PSHome\Modules NOT found = = 'PSModulePath has been constrained by a user to create a sand boxed environment without including System Modules' @@ -905,27 +914,27 @@ namespace System.Management.Automation /// /// Get the current module path setting. - /// - /// 'preferSystemModulePath' should only be used for internal functions - by default, - /// user modules should be able to override system modules. /// + /// + /// Include The system wide module path ($PSHOME\Modules) even if it's not in PSModulePath. + /// In V3-V5, we prepended this path during module auto-discovery which incorrectly preferred + /// $PSHOME\Modules over user installed modules that might have a command that overrides + /// a product-supplied command. + /// For 5.1, we append $PSHOME\Modules in this case to avoid the rare case where PSModulePath + /// does not contain the path, but a script depends on previous behavior. + /// Note that appending is still a potential breaking change, but necessary to update in-box + /// modules long term - e.g. when open sourcing a module and installing from the gallery. + /// + /// /// The module path as an array of strings - internal static IEnumerable GetModulePath(bool preferSystemModulePath, ExecutionContext context) + internal static IEnumerable GetModulePath(bool includeSystemModulePath, ExecutionContext context) { string modulePathString = Environment.GetEnvironmentVariable("PSMODULEPATH") ?? SetModulePath(); HashSet processedPathSet = new HashSet(StringComparer.OrdinalIgnoreCase); - // If we should prefer the system-wide module path, prepend that to what gets returned. - if (preferSystemModulePath) + if (!string.IsNullOrWhiteSpace(modulePathString)) { - yield return ProcessOneModulePath(context, GetSystemwideModulePath(), processedPathSet); - } - - // If the path is just whitespace, return an empty collection. - if (string.IsNullOrWhiteSpace(modulePathString)) - yield break; - foreach (string envPath in modulePathString.Split(Utils.Separators.Semicolon, StringSplitOptions.RemoveEmptyEntries)) { var processedPath = ProcessOneModulePath(context, envPath, processedPathSet); @@ -934,6 +943,14 @@ namespace System.Management.Automation } } + if (includeSystemModulePath) + { + var processedPath = ProcessOneModulePath(context, GetSystemwideModulePath(), processedPathSet); + if (processedPath != null) + yield return processedPath; + } + } + static private string ProcessOneModulePath(ExecutionContext context, string envPath, HashSet processedPathSet) { string trimmedenvPath = envPath.Trim(); diff --git a/src/System.Management.Automation/engine/Modules/ModuleUtils.cs b/src/System.Management.Automation/engine/Modules/ModuleUtils.cs index 949b97903..41a316005 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleUtils.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleUtils.cs @@ -226,12 +226,8 @@ namespace System.Management.Automation.Internal string manifestPath = qualifiedPathWithVersion + StringLiterals.PowerShellDataFileExtension; if (File.Exists(manifestPath)) { - var isValidModuleVersion = version.Equals(ModuleIntrinsics.GetManifestModuleVersion(manifestPath)); - if (isValidModuleVersion) - { - isModuleDirectory = true; - yield return manifestPath; - } + isModuleDirectory = true; + yield return manifestPath; } } @@ -309,6 +305,18 @@ namespace System.Management.Automation.Internal } } + internal static bool IsModuleInVersionSubdirectory(string modulePath, out Version version) + { + version = null; + var folderName = Path.GetDirectoryName(modulePath); + if (folderName != null) + { + folderName = Path.GetFileName(folderName); + return Version.TryParse(folderName, out version); + } + return false; + } + /// /// Gets a list of matching commands /// diff --git a/src/System.Management.Automation/engine/Modules/NewModuleManifestCommand.cs b/src/System.Management.Automation/engine/Modules/NewModuleManifestCommand.cs index 5f33b3473..b6fd09895 100644 --- a/src/System.Management.Automation/engine/Modules/NewModuleManifestCommand.cs +++ b/src/System.Management.Automation/engine/Modules/NewModuleManifestCommand.cs @@ -978,9 +978,9 @@ namespace Microsoft.PowerShell.Commands BuildModuleManifest(result, "PowerShellHostVersion", Modules.PowerShellHostVersion, _PowerShellHostVersion != null && !string.IsNullOrEmpty(_PowerShellHostVersion.ToString()), () => QuoteName(_PowerShellHostVersion), streamWriter); - BuildModuleManifest(result, "DotNetFrameworkVersion", Modules.DotNetFrameworkVersion, _DotNetFrameworkVersion != null && !string.IsNullOrEmpty(_DotNetFrameworkVersion.ToString()), () => QuoteName(_DotNetFrameworkVersion), streamWriter); + BuildModuleManifest(result, "DotNetFrameworkVersion", StringUtil.Format(Modules.DotNetFrameworkVersion, Modules.PrerequisiteForDesktopEditionOnly), _DotNetFrameworkVersion != null && !string.IsNullOrEmpty(_DotNetFrameworkVersion.ToString()), () => QuoteName(_DotNetFrameworkVersion), streamWriter); - BuildModuleManifest(result, "CLRVersion", Modules.CLRVersion, _ClrVersion != null && !string.IsNullOrEmpty(_ClrVersion.ToString()), () => QuoteName(_ClrVersion), streamWriter); + BuildModuleManifest(result, "CLRVersion", StringUtil.Format(Modules.CLRVersion, Modules.PrerequisiteForDesktopEditionOnly), _ClrVersion != null && !string.IsNullOrEmpty(_ClrVersion.ToString()), () => QuoteName(_ClrVersion), streamWriter); BuildModuleManifest(result, "ProcessorArchitecture", Modules.ProcessorArchitecture, _processorArchitecture.HasValue, () => QuoteName(_processorArchitecture), streamWriter); diff --git a/src/System.Management.Automation/engine/NativeCommandProcessor.cs b/src/System.Management.Automation/engine/NativeCommandProcessor.cs index 286d4ab19..fb025bce9 100644 --- a/src/System.Management.Automation/engine/NativeCommandProcessor.cs +++ b/src/System.Management.Automation/engine/NativeCommandProcessor.cs @@ -848,6 +848,7 @@ namespace System.Management.Automation /// /// /// + [ArchitectureSensitive] static bool IsWindowsApplication(string fileName) { #if CORECLR @@ -1250,6 +1251,7 @@ namespace System.Management.Automation private static extern IntPtr FindExecutableW( string fileName, string directoryPath, StringBuilder pathFound); + [ArchitectureSensitive] private static string FindExecutable(string filename) { // Preallocate a diff --git a/src/System.Management.Automation/engine/Utils.cs b/src/System.Management.Automation/engine/Utils.cs index ac23e8014..366265513 100644 --- a/src/System.Management.Automation/engine/Utils.cs +++ b/src/System.Management.Automation/engine/Utils.cs @@ -164,6 +164,7 @@ namespace System.Management.Automation } } + [ArchitectureSensitive] internal static string GetStringFromSecureString(SecureString ss) { IntPtr p = IntPtr.Zero; diff --git a/src/System.Management.Automation/engine/hostifaces/LocalConnection.cs b/src/System.Management.Automation/engine/hostifaces/LocalConnection.cs index 25ec05acc..175d1b81e 100644 --- a/src/System.Management.Automation/engine/hostifaces/LocalConnection.cs +++ b/src/System.Management.Automation/engine/hostifaces/LocalConnection.cs @@ -878,7 +878,7 @@ namespace System.Management.Automation.Runspaces PSHostUserInterface host = executionContext.EngineHostInterface.UI; if (host != null) { - host.StopAllTranscribing(); + host.StopAllTranscribing(executionContext.CurrentRunspace.InstanceId); } } } diff --git a/src/System.Management.Automation/engine/hostifaces/MshHostUserInterface.cs b/src/System.Management.Automation/engine/hostifaces/MshHostUserInterface.cs index f64753422..3103aacce 100644 --- a/src/System.Management.Automation/engine/hostifaces/MshHostUserInterface.cs +++ b/src/System.Management.Automation/engine/hostifaces/MshHostUserInterface.cs @@ -420,12 +420,13 @@ namespace System.Management.Automation.Host } } - internal void StartTranscribing(string path, System.Management.Automation.Remoting.PSSenderInfo senderInfo, bool includeInvocationHeader) - { + internal void StartTranscribing(string path, System.Management.Automation.Remoting.PSSenderInfo senderInfo, bool includeInvocationHeader, Guid runspaceInstanceId) + { TranscriptionOption transcript = new TranscriptionOption(); transcript.Path = path; transcript.IncludeInvocationHeader = includeInvocationHeader; - TranscriptionData.Transcripts.Add(transcript); + transcript.RunspaceInstanceId = runspaceInstanceId; + TranscriptionData.Transcripts.Add(transcript); LogTranscriptHeader(senderInfo, transcript); } @@ -476,7 +477,7 @@ namespace System.Management.Automation.Host TranscribeCommandComplete(null); } - internal string StopTranscribing() + internal string StopTranscribing(Guid runspaceInstanceId) { if (TranscriptionData.Transcripts.Count == 0) { @@ -484,11 +485,17 @@ namespace System.Management.Automation.Host } TranscriptionOption stoppedTranscript = TranscriptionData.Transcripts[TranscriptionData.Transcripts.Count - 1]; - LogTranscriptFooter(stoppedTranscript); - stoppedTranscript.Dispose(); - TranscriptionData.Transcripts.Remove(stoppedTranscript); - - return stoppedTranscript.Path; + + if (stoppedTranscript.RunspaceInstanceId == runspaceInstanceId) + { + LogTranscriptFooter(stoppedTranscript); + stoppedTranscript.Dispose(); + TranscriptionData.Transcripts.Remove(stoppedTranscript); + + return stoppedTranscript.Path; + } + + return null; } private void LogTranscriptFooter(TranscriptionOption stoppedTranscript) @@ -514,13 +521,13 @@ namespace System.Management.Automation.Host } } - internal void StopAllTranscribing() + internal void StopAllTranscribing(Guid runspaceInstanceId) { TranscribeCommandComplete(null); - - while (TranscriptionData.Transcripts.Count > 0) + + foreach(var transcription in TranscriptionData.Transcripts) { - StopTranscribing(); + StopTranscribing(runspaceInstanceId); } lock (TranscriptionData) @@ -999,7 +1006,7 @@ namespace System.Management.Automation.Host internal TranscriptionOption SystemTranscript { get; set; } internal string CommandBeingIgnored { get; set; } internal bool IsHelperCommand { get; set; } - internal string PromptText { get; set; } + internal string PromptText { get; set; } } @@ -1059,6 +1066,12 @@ namespace System.Management.Automation.Host /// internal Encoding Encoding { get; private set; } + /// + /// RunspaceInstanceId of the transcription session. + /// This is used to choose which transcriptions are closed when runspace is disposed. + /// + internal Guid RunspaceInstanceId { get; set; } + /// /// Logs buffered content to disk. We use this instead of File.AppendAllLines /// so that we don't need to pay seek penalties all the time, and so that we diff --git a/src/System.Management.Automation/engine/parser/SemanticChecks.cs b/src/System.Management.Automation/engine/parser/SemanticChecks.cs index 26af1acb7..7feafc345 100644 --- a/src/System.Management.Automation/engine/parser/SemanticChecks.cs +++ b/src/System.Management.Automation/engine/parser/SemanticChecks.cs @@ -11,9 +11,8 @@ using System.Runtime.CompilerServices; using System.Reflection; using System.Text; using Microsoft.PowerShell; -#if !CORECLR // Configuration Keyword Not Supported On CSS using Microsoft.PowerShell.DesiredStateConfiguration.Internal; -#endif + namespace System.Management.Automation.Language { @@ -1091,8 +1090,6 @@ namespace System.Management.Automation.Language return AstVisitAction.Continue; } -#if !CORECLR // Configuration Keyword Not Supported On CSS - public override AstVisitAction VisitScriptBlockExpression(ScriptBlockExpressionAst scriptBlockExpressionAst) { ConfigurationDefinitionAst configAst = Ast.GetAncestorAst(scriptBlockExpressionAst); @@ -1172,7 +1169,7 @@ namespace System.Management.Automation.Language } return AstVisitAction.Continue; - } + } public override AstVisitAction VisitConfigurationDefinition(ConfigurationDefinitionAst configurationDefinitionAst) { @@ -1197,7 +1194,6 @@ namespace System.Management.Automation.Language return AstVisitAction.Continue; } - public override AstVisitAction VisitDynamicKeywordStatement(DynamicKeywordStatementAst dynamicKeywordStatementAst) { ////////////////////////////////////////////////////////////////////////////////// @@ -1269,7 +1265,7 @@ namespace System.Management.Automation.Language return AstVisitAction.Continue; } -#endif //!CORECLR + public override AstVisitAction VisitPropertyMember(PropertyMemberAst propertyMemberAst) { @@ -1299,7 +1295,10 @@ namespace System.Management.Automation.Language } _scopeStack.Pop(); scriptBlockAst.PostParseChecksPerformed = true; - scriptBlockAst.HadErrors = _parser.ErrorList.Count > 0; + // at this moment, we could use different parser for the initial syntax check + // and this _parser for semantic check. + // that's why '|=' instead of just '='. + scriptBlockAst.HadErrors |= _parser.ErrorList.Count > 0; } else if (ast is MemberAst) { diff --git a/src/System.Management.Automation/engine/parser/TypeResolver.cs b/src/System.Management.Automation/engine/parser/TypeResolver.cs index fd240585c..ae934df9f 100644 --- a/src/System.Management.Automation/engine/parser/TypeResolver.cs +++ b/src/System.Management.Automation/engine/parser/TypeResolver.cs @@ -261,7 +261,7 @@ namespace System.Management.Automation.Language // - Assemblies added by 'using assembly'. // For this case, we REPORT ambiguity, since user explicitly specifies the set of assemblies. // * All other loaded assemblies (excluding dynamic assemblies created for PS defined types). - // On FullCLR, IGNORE ambiguity. It mimics PS v4. There are two reasons: + // IGNORE ambiguity. It mimics PS v4. There are two reasons: // 1) If we report ambiguity, we need to fix our caching logic accordingly. // Consider this code // Add-Type 'public class Q {}' # ok @@ -280,7 +280,8 @@ namespace System.Management.Automation.Language // So [NuGet.VisualStudio.IVsPackageInstallerServices] can be resolved to several different assemblies and it's ok. // * User defined type accelerators (rare - interface was never public) // - // If nothing is found, we search again, this time applying any 'using namespace ...' declarations including the implicit 'using namespace System'. We must search all using aliases and REPORT an error if there is an ambiguity. + // If nothing is found, we search again, this time applying any 'using namespace ...' declarations including the implicit 'using namespace System'. + // We must search all using aliases and REPORT an error if there is an ambiguity. var assemList = assemblies ?? ClrFacade.GetAssemblies(typeResolutionState, typeName); @@ -301,15 +302,10 @@ namespace System.Management.Automation.Language return typeName._typeDefinitionAst.Type; } -#if CORECLR - bool reportAmbigousException = true; -#else - bool reportAmbigousException = false; -#endif result = ResolveTypeNameWorker(typeName, currentScope, typeResolutionState.assemblies, typeResolutionState, /* reportAmbigousException */ true, out exception); if (exception == null && result == null) { - result = ResolveTypeNameWorker(typeName, currentScope, assemList, typeResolutionState, reportAmbigousException, out exception); + result = ResolveTypeNameWorker(typeName, currentScope, assemList, typeResolutionState, /* reportAmbigousException */ false, out exception); } if (result != null) @@ -337,7 +333,7 @@ namespace System.Management.Automation.Language var newResult = ResolveTypeNameWorker(newTypeName, currentScope, typeResolutionState.assemblies, typeResolutionState, /* reportAmbigousException */ true, out exception); if (exception == null && newResult == null) { - newResult = ResolveTypeNameWorker(newTypeName, currentScope, assemList, typeResolutionState, reportAmbigousException, out exception); + newResult = ResolveTypeNameWorker(newTypeName, currentScope, assemList, typeResolutionState, /* reportAmbigousException */ false, out exception); } if (exception != null) diff --git a/src/System.Management.Automation/engine/parser/ast.cs b/src/System.Management.Automation/engine/parser/ast.cs index eef44d6e1..5b88ae2d4 100644 --- a/src/System.Management.Automation/engine/parser/ast.cs +++ b/src/System.Management.Automation/engine/parser/ast.cs @@ -1131,12 +1131,17 @@ namespace System.Management.Automation.Language if (!PostParseChecksPerformed) { Parser parser = new Parser(); - PerformPostParseChecks(parser); + // we call PerformPostParseChecks on root ScriptBlockAst, to obey contract of SymbolResolver. + // It needs to be run from the top of the tree. + // It's ok to report an error from a different part of AST in this case. + var root = GetRootScriptBlockAst(); + root.PerformPostParseChecks(parser); if (parser.ErrorList.Any()) { throw new ParseException(parser.ErrorList.ToArray()); } } + if (HadErrors) { throw new PSInvalidOperationException(); @@ -1145,6 +1150,18 @@ namespace System.Management.Automation.Language return new ScriptBlock(this, isFilter: false); } + private ScriptBlockAst GetRootScriptBlockAst() + { + ScriptBlockAst rootScriptBlockAst = this; + ScriptBlockAst parent; + while ((parent = Ast.GetAncestorAst(rootScriptBlockAst.Parent)) != null) + { + rootScriptBlockAst = parent; + } + + return rootScriptBlockAst; + } + /// /// Copy the ScriptBlockAst instance /// diff --git a/src/System.Management.Automation/engine/remoting/client/remoterunspaceinfo.cs b/src/System.Management.Automation/engine/remoting/client/remoterunspaceinfo.cs index 7ef34003d..5fe2bd85f 100644 --- a/src/System.Management.Automation/engine/remoting/client/remoterunspaceinfo.cs +++ b/src/System.Management.Automation/engine/remoting/client/remoterunspaceinfo.cs @@ -85,24 +85,6 @@ namespace System.Management.Automation.Runspaces } } - /// - /// Name of the container target - /// - public String ContainerName - { - get - { - if (ComputerType == TargetMachineType.Container) - { - return remoteRunspace.ConnectionInfo.ComputerName; - } - else - { - return string.Empty; - } - } - } - /// /// Id of the container target /// diff --git a/src/System.Management.Automation/engine/remoting/commands/ConnectPSSession.cs b/src/System.Management.Automation/engine/remoting/commands/ConnectPSSession.cs index e46929fb5..8243626a3 100644 --- a/src/System.Management.Automation/engine/remoting/commands/ConnectPSSession.cs +++ b/src/System.Management.Automation/engine/remoting/commands/ConnectPSSession.cs @@ -360,17 +360,6 @@ namespace Microsoft.PowerShell.Commands } } - /// - /// Overriding to suppress this parameter - /// - public override string[] ContainerName - { - get - { - return null; - } - } - /// /// Overriding to suppress this parameter /// diff --git a/src/System.Management.Automation/engine/remoting/commands/DisconnectPSSession.cs b/src/System.Management.Automation/engine/remoting/commands/DisconnectPSSession.cs index 559403a9d..a4ae14610 100644 --- a/src/System.Management.Automation/engine/remoting/commands/DisconnectPSSession.cs +++ b/src/System.Management.Automation/engine/remoting/commands/DisconnectPSSession.cs @@ -143,17 +143,6 @@ namespace Microsoft.PowerShell.Commands } } - /// - /// Overriding to suppress this parameter - /// - public override string[] ContainerName - { - get - { - return null; - } - } - /// /// Overriding to suppress this parameter /// diff --git a/src/System.Management.Automation/engine/remoting/commands/InvokeCommandCommand.cs b/src/System.Management.Automation/engine/remoting/commands/InvokeCommandCommand.cs index 207c035b9..afe3e474a 100644 --- a/src/System.Management.Automation/engine/remoting/commands/InvokeCommandCommand.cs +++ b/src/System.Management.Automation/engine/remoting/commands/InvokeCommandCommand.cs @@ -281,16 +281,12 @@ namespace Microsoft.PowerShell.Commands ParameterSetName = InvokeCommandCommand.FilePathUriParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = InvokeCommandCommand.ContainerIdParameterSet)] - [Parameter(ValueFromPipelineByPropertyName = true, - ParameterSetName = InvokeCommandCommand.ContainerNameParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = InvokeCommandCommand.VMIdParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = InvokeCommandCommand.VMNameParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = InvokeCommandCommand.FilePathContainerIdParameterSet)] - [Parameter(ValueFromPipelineByPropertyName = true, - ParameterSetName = InvokeCommandCommand.FilePathContainerNameParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = InvokeCommandCommand.FilePathVMIdParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, @@ -343,11 +339,9 @@ namespace Microsoft.PowerShell.Commands [Parameter(ParameterSetName = InvokeCommandCommand.VMIdParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.VMNameParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.ContainerIdParameterSet)] - [Parameter(ParameterSetName = InvokeCommandCommand.ContainerNameParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.FilePathVMIdParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.FilePathVMNameParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.FilePathContainerIdParameterSet)] - [Parameter(ParameterSetName = InvokeCommandCommand.FilePathContainerNameParameterSet)] public override Int32 ThrottleLimit { set @@ -394,11 +388,9 @@ namespace Microsoft.PowerShell.Commands [Parameter(ParameterSetName = InvokeCommandCommand.VMIdParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.VMNameParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.ContainerIdParameterSet)] - [Parameter(ParameterSetName = InvokeCommandCommand.ContainerNameParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.FilePathVMIdParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.FilePathVMNameParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.FilePathContainerIdParameterSet)] - [Parameter(ParameterSetName = InvokeCommandCommand.FilePathContainerNameParameterSet)] public SwitchParameter AsJob { get @@ -453,11 +445,9 @@ namespace Microsoft.PowerShell.Commands [Parameter(ParameterSetName = InvokeCommandCommand.VMIdParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.VMNameParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.ContainerIdParameterSet)] - [Parameter(ParameterSetName = InvokeCommandCommand.ContainerNameParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.FilePathVMIdParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.FilePathVMNameParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.FilePathContainerIdParameterSet)] - [Parameter(ParameterSetName = InvokeCommandCommand.FilePathContainerNameParameterSet)] [Alias("HCN")] public SwitchParameter HideComputerName { @@ -476,9 +466,7 @@ namespace Microsoft.PowerShell.Commands [Parameter(ParameterSetName = InvokeCommandCommand.FilePathSessionParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.FilePathUriParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.ContainerIdParameterSet)] - [Parameter(ParameterSetName = InvokeCommandCommand.ContainerNameParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.FilePathContainerIdParameterSet)] - [Parameter(ParameterSetName = InvokeCommandCommand.FilePathContainerNameParameterSet)] public String JobName { get @@ -522,9 +510,6 @@ namespace Microsoft.PowerShell.Commands [Parameter(Position = 1, Mandatory = true, ParameterSetName = InvokeCommandCommand.ContainerIdParameterSet)] - [Parameter(Position = 1, - Mandatory = true, - ParameterSetName = InvokeCommandCommand.ContainerNameParameterSet)] [ValidateNotNull] [Alias("Command")] public override ScriptBlock ScriptBlock @@ -568,9 +553,6 @@ namespace Microsoft.PowerShell.Commands [Parameter(Position = 1, Mandatory = true, ParameterSetName = FilePathContainerIdParameterSet)] - [Parameter(Position = 1, - Mandatory = true, - ParameterSetName = FilePathContainerNameParameterSet)] [ValidateNotNull] [Alias("PSPath")] public override string FilePath @@ -666,8 +648,6 @@ namespace Microsoft.PowerShell.Commands /// [Parameter(ParameterSetName = InvokeCommandCommand.ContainerIdParameterSet)] [Parameter(ParameterSetName = InvokeCommandCommand.FilePathContainerIdParameterSet)] - [Parameter(ParameterSetName = InvokeCommandCommand.ContainerNameParameterSet)] - [Parameter(ParameterSetName = InvokeCommandCommand.FilePathContainerNameParameterSet)] public override SwitchParameter RunAsAdministrator { get { return base.RunAsAdministrator; } @@ -938,11 +918,9 @@ namespace Microsoft.PowerShell.Commands case InvokeCommandCommand.VMIdParameterSet: case InvokeCommandCommand.VMNameParameterSet: case InvokeCommandCommand.ContainerIdParameterSet: - case InvokeCommandCommand.ContainerNameParameterSet: case InvokeCommandCommand.FilePathVMIdParameterSet: case InvokeCommandCommand.FilePathVMNameParameterSet: case InvokeCommandCommand.FilePathContainerIdParameterSet: - case InvokeCommandCommand.FilePathContainerNameParameterSet: { if (ResolvedComputerNames.Length != 0 && Operations.Count > 0) { diff --git a/src/System.Management.Automation/engine/remoting/commands/NewPSSessionConfigurationOptionCommand.cs b/src/System.Management.Automation/engine/remoting/commands/NewPSSessionConfigurationOptionCommand.cs index 6bc09b8b9..a7272f60a 100644 --- a/src/System.Management.Automation/engine/remoting/commands/NewPSSessionConfigurationOptionCommand.cs +++ b/src/System.Management.Automation/engine/remoting/commands/NewPSSessionConfigurationOptionCommand.cs @@ -30,7 +30,7 @@ namespace Microsoft.PowerShell.Commands private int? _processIdleTimeoutSec = null; internal const string AttribMaxIdleTimeout = "MaxIdleTimeoutms"; - internal static readonly int? DefaultMaxIdleTimeout = 43200; // 12 hours in seconds + internal static readonly int? DefaultMaxIdleTimeout = int.MaxValue; private int? _maxIdleTimeoutSec = null; internal const string AttribIdleTimeout = "IdleTimeoutms"; @@ -38,27 +38,27 @@ namespace Microsoft.PowerShell.Commands private int? _idleTimeoutSec = null; private const string AttribMaxConcurrentUsers = "MaxConcurrentUsers"; - internal static readonly int? DefaultMaxConcurrentUsers = 5; + internal static readonly int? DefaultMaxConcurrentUsers = int.MaxValue; private int? maxConcurrentUsers = null; private const string AttribMaxProcessesPerSession = "MaxProcessesPerShell"; - internal static readonly int? DefaultMaxProcessesPerSession = 15; + internal static readonly int? DefaultMaxProcessesPerSession = int.MaxValue; private int? maxProcessesPerSession = null; private const string AttribMaxMemoryPerSessionMB = "MaxMemoryPerShellMB"; - internal static readonly int? DefaultMaxMemoryPerSessionMB = 1024; + internal static readonly int? DefaultMaxMemoryPerSessionMB = int.MaxValue; private int? maxMemoryPerSessionMB = null; private const string AttribMaxSessions = "MaxShells"; - internal static readonly int? DefaultMaxSessions = 25; + internal static readonly int? DefaultMaxSessions = int.MaxValue; private int? maxSessions = null; private const string AttribMaxSessionsPerUser = "MaxShellsPerUser"; - internal static readonly int? DefaultMaxSessionsPerUser = 25; + internal static readonly int? DefaultMaxSessionsPerUser = int.MaxValue; private int? maxSessionsPerUser = null; private const string AttribMaxConcurrentCommandsPerSession = "MaxConcurrentCommandsPerShell"; - internal static readonly int? DefaultMaxConcurrentCommandsPerSession = 1000; + internal static readonly int? DefaultMaxConcurrentCommandsPerSession = int.MaxValue; private int? maxConcurrentCommandsPerSession = null; /// @@ -350,7 +350,9 @@ namespace Microsoft.PowerShell.Commands } if (_maxIdleTimeoutSec.HasValue) { - sb.Append(string.Format(CultureInfo.InvariantCulture, Token, AttribMaxIdleTimeout, 1000 * _maxIdleTimeoutSec)); + // Special case max int value for unbounded default. + sb.Append(string.Format(CultureInfo.InvariantCulture, Token, AttribMaxIdleTimeout, + (_maxIdleTimeoutSec == int.MaxValue) ? _maxIdleTimeoutSec : (1000 * _maxIdleTimeoutSec))); } return sb.Length > 0 diff --git a/src/System.Management.Automation/engine/remoting/commands/PSRemotingCmdlet.cs b/src/System.Management.Automation/engine/remoting/commands/PSRemotingCmdlet.cs index 85d8de925..d2e4c5c10 100644 --- a/src/System.Management.Automation/engine/remoting/commands/PSRemotingCmdlet.cs +++ b/src/System.Management.Automation/engine/remoting/commands/PSRemotingCmdlet.cs @@ -167,11 +167,6 @@ namespace Microsoft.PowerShell.Commands /// protected const string ContainerIdParameterSet = "ContainerId"; - /// - /// Container name parameter set - /// - protected const string ContainerNameParameterSet = "ContainerName"; - /// /// VM guid parameter set /// @@ -601,28 +596,6 @@ namespace Microsoft.PowerShell.Commands } private string[] containerId; - /// - /// Name of target container. - /// - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", - Justification = "This is by spec.")] - [Parameter(Mandatory = true, - ValueFromPipelineByPropertyName = true, - ParameterSetName = PSRemotingBaseCmdlet.ContainerNameParameterSet)] - [ValidateNotNullOrEmpty] - public virtual string[] ContainerName - { - get - { - return containerName; - } - set - { - containerName = value; - } - } - private string[] containerName; - /// /// When set, PowerShell process inside container will be launched with /// high privileged account. @@ -630,7 +603,6 @@ namespace Microsoft.PowerShell.Commands /// with low privileged account. /// [Parameter(ParameterSetName = PSRemotingBaseCmdlet.ContainerIdParameterSet)] - [Parameter(ParameterSetName = PSRemotingBaseCmdlet.ContainerNameParameterSet)] public virtual SwitchParameter RunAsAdministrator { get @@ -723,7 +695,6 @@ namespace Microsoft.PowerShell.Commands [Parameter(ParameterSetName = PSRemotingBaseCmdlet.SessionParameterSet)] [Parameter(ParameterSetName = PSRemotingBaseCmdlet.UriParameterSet)] [Parameter(ParameterSetName = PSRemotingBaseCmdlet.ContainerIdParameterSet)] - [Parameter(ParameterSetName = PSRemotingBaseCmdlet.ContainerNameParameterSet)] [Parameter(ParameterSetName = PSRemotingBaseCmdlet.VMIdParameterSet)] [Parameter(ParameterSetName = PSRemotingBaseCmdlet.VMNameParameterSet)] public virtual Int32 ThrottleLimit @@ -1031,11 +1002,6 @@ namespace Microsoft.PowerShell.Commands /// protected const string FilePathContainerIdParameterSet = "FilePathContainerId"; - /// - /// Container name file path parameter set. - /// - protected const string FilePathContainerNameParameterSet = "FilePathContainerName"; - #endregion #region Parameters @@ -1225,25 +1191,6 @@ namespace Microsoft.PowerShell.Commands } private string[] containerId; - /// - /// Name of target container. - /// - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", - Justification = "This is by spec.")] - [Parameter(Mandatory = true, - ValueFromPipelineByPropertyName = true, - ParameterSetName = InvokeCommandCommand.ContainerNameParameterSet)] - [Parameter(Mandatory = true, - ValueFromPipelineByPropertyName = true, - ParameterSetName = InvokeCommandCommand.FilePathContainerNameParameterSet)] - [ValidateNotNullOrEmpty] - public override string[] ContainerName - { - get { return containerName; } - set { containerName = value; } - } - private string[] containerName; - /// /// For WSMan session: /// If this parameter is not specified then the value specified in @@ -1263,16 +1210,12 @@ namespace Microsoft.PowerShell.Commands ParameterSetName = InvokeCommandCommand.FilePathUriParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = InvokeCommandCommand.ContainerIdParameterSet)] - [Parameter(ValueFromPipelineByPropertyName = true, - ParameterSetName = InvokeCommandCommand.ContainerNameParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = InvokeCommandCommand.VMIdParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = InvokeCommandCommand.VMNameParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = InvokeCommandCommand.FilePathContainerIdParameterSet)] - [Parameter(ValueFromPipelineByPropertyName = true, - ParameterSetName = InvokeCommandCommand.FilePathContainerNameParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = InvokeCommandCommand.FilePathVMIdParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, @@ -1664,26 +1607,13 @@ namespace Microsoft.PowerShell.Commands /// protected virtual void CreateHelpersForSpecifiedContainerSession() { - string[] inputArray; - bool isContainerIdSet = false; List resolvedNameList = new List(); + + Dbg.Assert((ParameterSetName == PSExecutionCmdlet.ContainerIdParameterSet) || + (ParameterSetName == PSExecutionCmdlet.FilePathContainerIdParameterSet), + "Expected ParameterSetName == ContainerId or FilePathContainerId"); - if ((ParameterSetName == PSExecutionCmdlet.ContainerIdParameterSet) || - (ParameterSetName == PSExecutionCmdlet.FilePathContainerIdParameterSet)) - { - inputArray = ContainerId; - isContainerIdSet = true; - } - else - { - Dbg.Assert((ParameterSetName == PSExecutionCmdlet.ContainerNameParameterSet) || - (ParameterSetName == PSExecutionCmdlet.FilePathContainerNameParameterSet), - "Expected ParameterSetName == ContainerId, ContainerName, FilePathContainerId or FilePathContainerName"); - - inputArray = ContainerName; - } - - foreach (var input in inputArray) + foreach (var input in ContainerId) { // // Create helper objects for container ID or name. @@ -1697,14 +1627,7 @@ namespace Microsoft.PowerShell.Commands // Hyper-V container uses Hype-V socket as transport. // Windows Server container uses named pipe as transport. // - if (isContainerIdSet) - { - connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoById(input, RunAsAdministrator.IsPresent, this.ConfigurationName); - } - else - { - connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoByName(input, RunAsAdministrator.IsPresent, this.ConfigurationName); - } + connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfo(input, RunAsAdministrator.IsPresent, this.ConfigurationName); resolvedNameList.Add(connectionInfo.ComputerName); @@ -1975,11 +1898,9 @@ namespace Microsoft.PowerShell.Commands if ((ParameterSetName == PSExecutionCmdlet.VMIdParameterSet) || (ParameterSetName == PSExecutionCmdlet.VMNameParameterSet) || (ParameterSetName == PSExecutionCmdlet.ContainerIdParameterSet) || - (ParameterSetName == PSExecutionCmdlet.ContainerNameParameterSet) || (ParameterSetName == PSExecutionCmdlet.FilePathVMIdParameterSet) || (ParameterSetName == PSExecutionCmdlet.FilePathVMNameParameterSet) || - (ParameterSetName == PSExecutionCmdlet.FilePathContainerIdParameterSet) || - (ParameterSetName == PSExecutionCmdlet.FilePathContainerNameParameterSet)) + (ParameterSetName == PSExecutionCmdlet.FilePathContainerIdParameterSet)) { SkipWinRMCheck = true; } @@ -2031,9 +1952,7 @@ namespace Microsoft.PowerShell.Commands break; case PSExecutionCmdlet.ContainerIdParameterSet: - case PSExecutionCmdlet.ContainerNameParameterSet: case PSExecutionCmdlet.FilePathContainerIdParameterSet: - case PSExecutionCmdlet.FilePathContainerNameParameterSet: { CreateHelpersForSpecifiedContainerSession(); } @@ -2360,11 +2279,6 @@ private string GetConvertedScript(out List newParameterNames, out List protected const string ContainerIdInstanceIdParameterSet = "ContainerIdInstanceId"; - /// - /// ContainerNameInstanceId parameter set: container name + session instance id - /// - protected const string ContainerNameInstanceIdParameterSet = "ContainerNameInstanceId"; - /// /// VMIdInstanceId parameter set: vm id + session instance id /// @@ -2483,25 +2397,6 @@ private string GetConvertedScript(out List newParameterNames, out List - /// Name of target container. - /// - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", - Justification = "This is by spec.")] - [Parameter(Mandatory = true, - ValueFromPipelineByPropertyName = true, - ParameterSetName = PSRunspaceCmdlet.ContainerNameParameterSet)] - [Parameter(Mandatory = true, - ValueFromPipelineByPropertyName = true, - ParameterSetName = PSRunspaceCmdlet.ContainerNameInstanceIdParameterSet)] - [ValidateNotNullOrEmpty] - public virtual string[] ContainerName - { - get { return containerName; } - set { containerName = value; } - } - private string[] containerName; - /// /// Guid of target virtual machine. /// @@ -2606,25 +2501,13 @@ private string GetConvertedScript(out List newParameterNames, out List newParameterNames, out List newParameterNames, out List - /// Gets the matching runspaces by container name, vm name or container id with optional session name + /// Gets the matching runspaces by vm name or container id with optional session name /// /// if true write the object down the pipeline /// Runspace state filter value. /// Runspace configuration name filter value. /// if true the target is a container instead of virtual machine - /// if true the input is container id /// list of matching runspaces - private Dictionary GetMatchingRunspacesByContainerVMNameContainerId(bool writeobject, + private Dictionary GetMatchingRunspacesByVMNameContainerId(bool writeobject, SessionFilterState filterState, String configurationName, - bool isContainer, - bool useContainerId) + bool isContainer) { String[] inputNames; TargetMachineType computerType; - bool supportWildChar = false; + bool supportWildChar; String[] sessionNames = { "*" }; WildcardPattern configurationNamePattern = String.IsNullOrEmpty(configurationName) ? null : WildcardPattern.Get(configurationName, WildcardOptions.IgnoreCase); Dictionary matches = new Dictionary(); List remoteRunspaceInfos = this.RunspaceRepository.Runspaces; - // container name and vm name support wild characters, while container id does not. + // vm name support wild characters, while container id does not. // vm id does not apply in this method, which does not support wild characters either. if (isContainer) { - if (useContainerId) - { - inputNames = ContainerId; - } - else - { - inputNames = ContainerName; - supportWildChar = true; - } - + inputNames = ContainerId; computerType = TargetMachineType.Container; + supportWildChar = false; } else { @@ -2973,7 +2846,7 @@ private string GetConvertedScript(out List newParameterNames, out List(session => (supportWildChar ? inputNamePattern.IsMatch(isContainer ? session.ContainerName : session.VMName) + .Where(session => (supportWildChar ? inputNamePattern.IsMatch(session.VMName) : inputName.Equals(session.ContainerId)) && ((sessionNamePattern == null) ? true : sessionNamePattern.IsMatch(session.Name)) && QueryRunspaces.TestRunspaceState(session.Runspace, filterState) && @@ -2989,43 +2862,33 @@ private string GetConvertedScript(out List newParameterNames, out List - /// Gets the matching runspaces by container name, vm name or container id with session instanceid + /// Gets the matching runspaces by vm name or container id with session instanceid /// /// if true write the object down the pipeline /// Runspace state filter value. /// Runspace configuration name filter value. /// if true the target is a container instead of virtual machine - /// if true the input is container id /// list of matching runspaces - private Dictionary GetMatchingRunspacesByContainerVMNameContainerIdSessionInstanceId(bool writeobject, + private Dictionary GetMatchingRunspacesByVMNameContainerIdSessionInstanceId(bool writeobject, SessionFilterState filterState, String configurationName, - bool isContainer, - bool useContainerId) + bool isContainer) { String[] inputNames; TargetMachineType computerType; - bool supportWildChar = false; + bool supportWildChar; WildcardPattern configurationNamePattern = String.IsNullOrEmpty(configurationName) ? null : WildcardPattern.Get(configurationName, WildcardOptions.IgnoreCase); Dictionary matches = new Dictionary(); List remoteRunspaceInfos = this.RunspaceRepository.Runspaces; - // container name and vm name support wild characters, while container id does not. + // vm name support wild characters, while container id does not. // vm id does not apply in this method, which does not support wild characters either. if (isContainer) { - if (useContainerId) - { - inputNames = ContainerId; - } - else - { - inputNames = ContainerName; - supportWildChar = true; - } - + inputNames = ContainerId; computerType = TargetMachineType.Container; + supportWildChar = false; } else { @@ -3041,7 +2904,7 @@ private string GetConvertedScript(out List newParameterNames, out List(session => (supportWildChar ? inputNamePattern.IsMatch(isContainer ? session.ContainerName : session.VMName) + .Where(session => (supportWildChar ? inputNamePattern.IsMatch(session.VMName) : inputName.Equals(session.ContainerId)) && sessionInstanceId.Equals(session.InstanceId) && QueryRunspaces.TestRunspaceState(session.Runspace, filterState) && diff --git a/src/System.Management.Automation/engine/remoting/commands/PushRunspaceCommand.cs b/src/System.Management.Automation/engine/remoting/commands/PushRunspaceCommand.cs index b6364959d..ec4dbc143 100644 --- a/src/System.Management.Automation/engine/remoting/commands/PushRunspaceCommand.cs +++ b/src/System.Management.Automation/engine/remoting/commands/PushRunspaceCommand.cs @@ -206,19 +206,6 @@ namespace Microsoft.PowerShell.Commands } private string containerId; - /// - /// The name of the target container. - /// - [ValidateNotNullOrEmpty] - [Parameter(Position = 0, Mandatory = true, ValueFromPipeline = true, - ValueFromPipelineByPropertyName = true, ParameterSetName = ContainerNameParameterSet)] - public new string ContainerName - { - get { return containerName; } - set { containerName = value; } - } - private string containerName; - /// /// For WSMan sessions: /// If this parameter is not specified then the value specified in @@ -234,8 +221,6 @@ namespace Microsoft.PowerShell.Commands ParameterSetName = EnterPSSessionCommand.UriParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = EnterPSSessionCommand.ContainerIdParameterSet)] - [Parameter(ValueFromPipelineByPropertyName = true, - ParameterSetName = EnterPSSessionCommand.ContainerNameParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = EnterPSSessionCommand.VMIdParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, @@ -377,7 +362,6 @@ namespace Microsoft.PowerShell.Commands break; case ContainerIdParameterSet: - case ContainerNameParameterSet: remoteRunspace = GetRunspaceForContainerSession(); break; } @@ -923,8 +907,7 @@ namespace Microsoft.PowerShell.Commands private bool IsParameterSetForContainer() { - return ((ParameterSetName == ContainerIdParameterSet) || - (ParameterSetName == ContainerNameParameterSet)); + return (ParameterSetName == ContainerIdParameterSet); } /// @@ -1196,8 +1179,8 @@ namespace Microsoft.PowerShell.Commands break; case ContainerIdParameterSet: - case ContainerNameParameterSet: - targetName = this.ContainerName; + targetName = (this.ContainerId.Length <= 15) ? this.ContainerId + : this.ContainerId.Remove(12) + "..."; break; case SessionParameterSet: @@ -1254,24 +1237,16 @@ namespace Microsoft.PowerShell.Commands try { + Dbg.Assert(!String.IsNullOrEmpty(ContainerId), "ContainerId has to be set."); + ContainerConnectionInfo connectionInfo = null; // // Hyper-V container uses Hype-V socket as transport. // Windows Server container uses named pipe as transport. // - if (!String.IsNullOrEmpty(ContainerId)) - { - connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoById(ContainerId, RunAsAdministrator.IsPresent, this.ConfigurationName); - } - else - { - Dbg.Assert(!String.IsNullOrEmpty(ContainerName), "Either ContainerId or ContainerName has to be set."); + connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfo(ContainerId, RunAsAdministrator.IsPresent, this.ConfigurationName); - connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoByName(ContainerName, RunAsAdministrator.IsPresent, this.ConfigurationName); - } - - this.ContainerName = connectionInfo.ComputerName; connectionInfo.CreateContainerProcess(); remoteRunspace = CreateTemporaryRemoteRunspaceForPowerShellDirect(this.Host, connectionInfo); } diff --git a/src/System.Management.Automation/engine/remoting/commands/StartJob.cs b/src/System.Management.Automation/engine/remoting/commands/StartJob.cs index 01bb5c473..2411a2903 100644 --- a/src/System.Management.Automation/engine/remoting/commands/StartJob.cs +++ b/src/System.Management.Automation/engine/remoting/commands/StartJob.cs @@ -357,17 +357,6 @@ namespace Microsoft.PowerShell.Commands } } - /// - /// Overriding to suppress this parameter - /// - public override string[] ContainerName - { - get - { - return null; - } - } - /// /// Overriding to suppress this parameter /// diff --git a/src/System.Management.Automation/engine/remoting/commands/getrunspacecommand.cs b/src/System.Management.Automation/engine/remoting/commands/getrunspacecommand.cs index c8b5a09b9..82a8e8a35 100644 --- a/src/System.Management.Automation/engine/remoting/commands/getrunspacecommand.cs +++ b/src/System.Management.Automation/engine/remoting/commands/getrunspacecommand.cs @@ -137,10 +137,6 @@ namespace Microsoft.PowerShell.Commands ParameterSetName = GetPSSessionCommand.ContainerIdParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = GetPSSessionCommand.ContainerIdInstanceIdParameterSet)] - [Parameter(ValueFromPipelineByPropertyName = true, - ParameterSetName = GetPSSessionCommand.ContainerNameParameterSet)] - [Parameter(ValueFromPipelineByPropertyName = true, - ParameterSetName = GetPSSessionCommand.ContainerNameInstanceIdParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = GetPSSessionCommand.VMIdParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, @@ -176,7 +172,6 @@ namespace Microsoft.PowerShell.Commands [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = PSRunspaceCmdlet.NameParameterSet)] [Parameter(ParameterSetName = GetPSSessionCommand.ContainerIdParameterSet)] - [Parameter(ParameterSetName = GetPSSessionCommand.ContainerNameParameterSet)] [Parameter(ParameterSetName = GetPSSessionCommand.VMIdParameterSet)] [Parameter(ParameterSetName = GetPSSessionCommand.VMNameParameterSet)] [ValidateNotNullOrEmpty()] @@ -197,8 +192,6 @@ namespace Microsoft.PowerShell.Commands ParameterSetName = PSRunspaceCmdlet.InstanceIdParameterSet)] [Parameter(ParameterSetName = GetPSSessionCommand.ContainerIdInstanceIdParameterSet, Mandatory = true)] - [Parameter(ParameterSetName = GetPSSessionCommand.ContainerNameInstanceIdParameterSet, - Mandatory = true)] [Parameter(ParameterSetName = GetPSSessionCommand.VMIdInstanceIdParameterSet, Mandatory = true)] [Parameter(ParameterSetName = GetPSSessionCommand.VMNameInstanceIdParameterSet, @@ -352,8 +345,6 @@ namespace Microsoft.PowerShell.Commands [Parameter(ParameterSetName = GetPSSessionCommand.ConnectionUriInstanceIdParameterSet)] [Parameter(ParameterSetName = GetPSSessionCommand.ContainerIdParameterSet)] [Parameter(ParameterSetName = GetPSSessionCommand.ContainerIdInstanceIdParameterSet)] - [Parameter(ParameterSetName = GetPSSessionCommand.ContainerNameParameterSet)] - [Parameter(ParameterSetName = GetPSSessionCommand.ContainerNameInstanceIdParameterSet)] [Parameter(ParameterSetName = GetPSSessionCommand.VMIdParameterSet)] [Parameter(ParameterSetName = GetPSSessionCommand.VMIdInstanceIdParameterSet)] [Parameter(ParameterSetName = GetPSSessionCommand.VMNameParameterSet)] diff --git a/src/System.Management.Automation/engine/remoting/commands/newrunspacecommand.cs b/src/System.Management.Automation/engine/remoting/commands/newrunspacecommand.cs index c360173d8..c35bea9c3 100644 --- a/src/System.Management.Automation/engine/remoting/commands/newrunspacecommand.cs +++ b/src/System.Management.Automation/engine/remoting/commands/newrunspacecommand.cs @@ -183,8 +183,6 @@ namespace Microsoft.PowerShell.Commands ParameterSetName = NewPSSessionCommand.UriParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = NewPSSessionCommand.ContainerIdParameterSet)] - [Parameter(ValueFromPipelineByPropertyName = true, - ParameterSetName = NewPSSessionCommand.ContainerNameParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = NewPSSessionCommand.VMIdParameterSet)] [Parameter(ValueFromPipelineByPropertyName = true, @@ -273,7 +271,6 @@ namespace Microsoft.PowerShell.Commands break; case NewPSSessionCommand.ContainerIdParameterSet: - case NewPSSessionCommand.ContainerNameParameterSet: { remoteRunspaces = CreateRunspacesWhenContainerParameterSpecified(); } @@ -1023,31 +1020,18 @@ namespace Microsoft.PowerShell.Commands }// CreateRunspacesWhenVMParameterSpecified /// - /// Creates the remote runspace objects when the ContainerId or ContainerName parameter - /// is specified + /// Creates the remote runspace objects when the ContainerId parameter is specified /// private List CreateRunspacesWhenContainerParameterSpecified() { - string[] inputArray; - bool isContainerIdSet = false; int index = 0; List resolvedNameList = new List(); List remoteRunspaces = new List(); + + Dbg.Assert((ParameterSetName == PSExecutionCmdlet.ContainerIdParameterSet), + "Expected ParameterSetName == ContainerId"); - if (ParameterSetName == PSExecutionCmdlet.ContainerIdParameterSet) - { - inputArray = ContainerId; - isContainerIdSet = true; - } - else - { - Dbg.Assert((ParameterSetName == PSExecutionCmdlet.ContainerNameParameterSet), - "Expected ParameterSetName == ContainerId or ContainerName"); - - inputArray = ContainerName; - } - - foreach (var input in inputArray) + foreach (var input in ContainerId) { // // Create helper objects for container ID or name. @@ -1064,14 +1048,7 @@ namespace Microsoft.PowerShell.Commands // Hyper-V container uses Hype-V socket as transport. // Windows Server container uses named pipe as transport. // - if (isContainerIdSet) - { - connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoById(input, RunAsAdministrator.IsPresent, this.ConfigurationName); - } - else - { - connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfoByName(input, RunAsAdministrator.IsPresent, this.ConfigurationName); - } + connectionInfo = ContainerConnectionInfo.CreateContainerConnectionInfo(input, RunAsAdministrator.IsPresent, this.ConfigurationName); resolvedNameList.Add(connectionInfo.ComputerName); diff --git a/src/System.Management.Automation/engine/remoting/commands/removerunspacecommand.cs b/src/System.Management.Automation/engine/remoting/commands/removerunspacecommand.cs index 3c2a998c6..5778cd6d1 100644 --- a/src/System.Management.Automation/engine/remoting/commands/removerunspacecommand.cs +++ b/src/System.Management.Automation/engine/remoting/commands/removerunspacecommand.cs @@ -78,22 +78,6 @@ namespace Microsoft.PowerShell.Commands } private string[] containerId; - /// - /// Name of target container. - /// - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", - Justification = "This is by spec.")] - [Parameter(Mandatory = true, - ValueFromPipelineByPropertyName = true, - ParameterSetName = PSRunspaceCmdlet.ContainerNameParameterSet)] - [ValidateNotNullOrEmpty] - public override string[] ContainerName - { - get { return containerName; } - set { containerName = value; } - } - private string[] containerName; - /// /// Guid of target virtual machine. /// @@ -149,7 +133,6 @@ namespace Microsoft.PowerShell.Commands case RemovePSSessionCommand.InstanceIdParameterSet: case RemovePSSessionCommand.IdParameterSet: case RemovePSSessionCommand.ContainerIdParameterSet: - case RemovePSSessionCommand.ContainerNameParameterSet: case RemovePSSessionCommand.VMIdParameterSet: case RemovePSSessionCommand.VMNameParameterSet: { diff --git a/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs b/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs index dfdb215dc..c567567a4 100644 --- a/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs +++ b/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs @@ -247,7 +247,7 @@ namespace System.Management.Automation.Runspaces /// The duration (in ms) for which PowerShell should wait before it times out on cancel operations /// (close runspace or stop powershell). For instance, when the user hits ctrl-C, /// New-PSSession cmdlet tries to call a stop on all remote runspaces which are in the Opening state. - /// The administrator wouldn’t mind waiting for 15 seconds, but this should be time bound and of a shorter duration. + /// The administrator wouldn�t mind waiting for 15 seconds, but this should be time bound and of a shorter duration. /// A high timeout here like 3 minutes will give the administrator a feeling that the PowerShell client has hung. /// public int CancelTimeout @@ -2181,7 +2181,7 @@ namespace System.Management.Automation.Runspaces /// public override string ComputerName { - get { return _containerProc.ContainerName; } + get { return _containerProc.ContainerId; } set { throw new PSNotSupportedException(); } } @@ -2235,25 +2235,12 @@ namespace System.Management.Automation.Runspaces /// /// Create ContainerConnectionInfo object based on container id. /// - public static ContainerConnectionInfo CreateContainerConnectionInfoById( + public static ContainerConnectionInfo CreateContainerConnectionInfo( string containerId, bool runAsAdmin, string configurationName) { - ContainerProcess containerProc = new ContainerProcess(containerId, null, null, 0, runAsAdmin, configurationName); - - return new ContainerConnectionInfo(containerProc); - } - - /// - /// Create ContainerConnectionInfo object based on container name. - /// - public static ContainerConnectionInfo CreateContainerConnectionInfoByName( - string containerName, - bool runAsAdmin, - string configurationName) - { - ContainerProcess containerProc = new ContainerProcess(null, containerName, null, 0, runAsAdmin, configurationName); + ContainerProcess containerProc = new ContainerProcess(containerId, null, 0, runAsAdmin, configurationName); return new ContainerConnectionInfo(containerProc); } @@ -2290,7 +2277,6 @@ namespace System.Management.Automation.Runspaces private Guid runtimeId; private string containerObRoot; private string containerId; - private string containerName; private int processId; private bool runAsAdmin = false; private string configurationName; @@ -2301,8 +2287,6 @@ namespace System.Management.Automation.Runspaces private const uint NoError = 0; private const uint InvalidContainerId = 1; private const uint ContainersFeatureNotEnabled = 2; - private const uint InvalidContainerNameMultiple = 3; - private const uint InvalidContainerNameNotExist = 4; private const uint OtherError = 9999; #endregion @@ -2337,15 +2321,6 @@ namespace System.Management.Automation.Runspaces set { containerId = value; } } - /// - /// Name of the container. - /// - public string ContainerName - { - get { return containerName; } - set { containerName = value; } - } - /// /// Process ID of the process created in container. /// @@ -2405,16 +2380,67 @@ namespace System.Management.Automation.Runspaces #region Native HCS (i.e., host compute service) methods + [StructLayout(LayoutKind.Sequential)] + internal struct HCS_PROCESS_INFORMATION + { + /// + /// The process id. + /// + public uint ProcessId; + + /// + /// Reserved. + /// + public uint Reserved; + + /// + /// If created, standard input handle of the process. + /// + public IntPtr StdInput; + + /// + /// If created, standard output handle of the process. + /// + public IntPtr StdOutput; + + /// + /// If created, standard error handle of the process. + /// + public IntPtr StdError; + } + [DllImport(PinvokeDllNames.CreateProcessInComputeSystemDllName, SetLastError = true, CharSet = CharSet.Unicode)] - internal static extern uint CreateProcessInComputeSystem( - string id, - string ProcessParameters, - ref int processId); - + internal static extern uint HcsOpenComputeSystem( + string id, + ref IntPtr computeSystem, + ref string result); + [DllImport(PinvokeDllNames.CreateProcessInComputeSystemDllName, SetLastError = true, CharSet = CharSet.Unicode)] - internal static extern uint TerminateProcessInComputeSystem( - string id, - int processId); + internal static extern uint HcsGetComputeSystemProperties( + IntPtr computeSystem, + string propertyQuery, + ref string properties, + ref string result); + + [DllImport(PinvokeDllNames.CreateProcessInComputeSystemDllName, SetLastError = true, CharSet = CharSet.Unicode)] + internal static extern uint HcsCreateProcess( + IntPtr computeSystem, + string processParameters, + ref HCS_PROCESS_INFORMATION processInformation, + ref IntPtr process, + ref string reslt); + + [DllImport(PinvokeDllNames.CreateProcessInComputeSystemDllName, SetLastError = true, CharSet = CharSet.Unicode)] + internal static extern uint HcsOpenProcess( + IntPtr computeSystem, + int processId, + ref IntPtr process, + ref string result); + + [DllImport(PinvokeDllNames.CreateProcessInComputeSystemDllName, SetLastError = true, CharSet = CharSet.Unicode)] + internal static extern uint HcsTerminateProcess( + IntPtr process, + ref string result); #endregion @@ -2423,30 +2449,17 @@ namespace System.Management.Automation.Runspaces /// /// Creates an instance used for PowerShell Direct for container. /// - public ContainerProcess(string containerId, string containerName, string containerObRoot, int processId, bool runAsAdmin, string configurationName) + public ContainerProcess(string containerId, string containerObRoot, int processId, bool runAsAdmin, string configurationName) { this.ContainerId = containerId; - this.ContainerName = containerName; this.ContainerObRoot = containerObRoot; this.ProcessId = processId; this.RunAsAdmin = runAsAdmin; this.ConfigurationName = configurationName; - if (!String.IsNullOrEmpty(containerId)) - { - if (String.IsNullOrEmpty(containerName)) - { - GetContainerPropertiesFromContainerId(); - } - } - else if (!String.IsNullOrEmpty(containerName)) - { - GetContainerPropertiesFromContainerName(); - } - else - { - Dbg.Assert(false, "containerId and containerName inputs cannot be empty at the same time."); - } + Dbg.Assert(!String.IsNullOrEmpty(containerId), "containerId input cannot be empty."); + + GetContainerProperties(); } #endregion @@ -2497,11 +2510,11 @@ namespace System.Management.Automation.Runspaces } /// - /// Get container name and object root based on given container id. + /// Get object root based on given container id. /// - public void GetContainerPropertiesFromContainerId() + public void GetContainerProperties() { - RunOnMTAThread(GetContainerPropertiesFromContainerIdInternal); + RunOnMTAThread(GetContainerPropertiesInternal); // // Report error. @@ -2519,37 +2532,6 @@ namespace System.Management.Automation.Runspaces } } - /// - /// Get container id and object root based on given container name. - /// - public void GetContainerPropertiesFromContainerName() - { - RunOnMTAThread(GetContainerPropertiesFromContainerNameInternal); - - // - // Report error. - // - switch (ErrorCode) - { - case NoError: - break; - - case ContainersFeatureNotEnabled: - throw new PSInvalidOperationException(StringUtil.Format(RemotingErrorIdStrings.ContainersFeatureNotEnabled)); - - case InvalidContainerNameMultiple: - throw new PSInvalidOperationException(StringUtil.Format(RemotingErrorIdStrings.InvalidContainerNameMultiple, - ContainerName)); - - case InvalidContainerNameNotExist: - throw new PSInvalidOperationException(StringUtil.Format(RemotingErrorIdStrings.InvalidContainerNameNotExist, - ContainerName)); - - case OtherError: - throw new PSInvalidOperationException(ErrorMessage); - } - } - #endregion #region Private methods @@ -2583,14 +2565,11 @@ namespace System.Management.Automation.Runspaces // try { - Type computeSystemPropertiesType; - Type hostComputeInteropType; - - GetHostComputeInteropTypes(out computeSystemPropertiesType, out hostComputeInteropType); - - MethodInfo computeSystemExistsInfo = hostComputeInteropType.GetMethod("ComputeSystemExists"); - - if (!(bool)computeSystemExistsInfo.Invoke(null, new object[]{ ContainerId })) + IntPtr ComputeSystem = IntPtr.Zero; + string resultString = String.Empty; + + result = HcsOpenComputeSystem(ContainerId, ref ComputeSystem, ref resultString); + if (result != 0) { processId = 0; error = InvalidContainerId; @@ -2606,19 +2585,23 @@ namespace System.Management.Automation.Runspaces (RuntimeId != Guid.Empty) ? "-so -NoProfile" : "-NamedPipeServerMode", String.IsNullOrEmpty(ConfigurationName) ? String.Empty : String.Concat("-Config ", ConfigurationName), (RunAsAdmin) ? "false" : "true"); - + + HCS_PROCESS_INFORMATION ProcessInformation = new HCS_PROCESS_INFORMATION(); + IntPtr Process = IntPtr.Zero; + // // Create PowerShell process inside the container. // - result = CreateProcessInComputeSystem( - ContainerId, - cmd, - ref processId); + result = HcsCreateProcess(ComputeSystem, cmd, ref ProcessInformation, ref Process, ref resultString); if (result != 0) { processId = 0; error = result; } + else + { + processId = Convert.ToInt32(ProcessInformation.ProcessId); + } } } catch (Exception e) @@ -2654,35 +2637,54 @@ namespace System.Management.Automation.Runspaces /// private void TerminateContainerProcessInternal() { - ProcessTerminated = - (TerminateProcessInComputeSystem(ContainerId, ProcessId) == 0); + IntPtr ComputeSystem = IntPtr.Zero; + string resultString = String.Empty; + IntPtr process = IntPtr.Zero; + + ProcessTerminated = false; + + if (HcsOpenComputeSystem(ContainerId, ref ComputeSystem, ref resultString) == 0) + { + if (HcsOpenProcess(ComputeSystem, ProcessId, ref process, ref resultString) == 0) + { + if (HcsTerminateProcess(process, ref resultString) == 0) + { + ProcessTerminated = true; + } + } + } } /// - /// Get container name and object root based on given container id. + /// Get object root based on given container id. /// - private void GetContainerPropertiesFromContainerIdInternal() + private void GetContainerPropertiesInternal() { try { - Type computeSystemPropertiesType; - Type hostComputeInteropType; - - GetHostComputeInteropTypes(out computeSystemPropertiesType, out hostComputeInteropType); + IntPtr ComputeSystem = IntPtr.Zero; + string resultString = String.Empty; - MethodInfo getComputeSystemPropertiesInfo = hostComputeInteropType.GetMethod("GetComputeSystemProperties"); - - var computeSystemPropertiesHandle = getComputeSystemPropertiesInfo.Invoke(null, new object[]{ ContainerId }); - - ContainerName = (string)computeSystemPropertiesType.GetProperty("Name").GetValue(computeSystemPropertiesHandle); - RuntimeId = (Guid)computeSystemPropertiesType.GetProperty("RuntimeId").GetValue(computeSystemPropertiesHandle); - - // - // Get container object root for Windows Server container. - // - if (RuntimeId == Guid.Empty) + if (HcsOpenComputeSystem(ContainerId, ref ComputeSystem, ref resultString) == 0) { - ContainerObRoot = (string)computeSystemPropertiesType.GetProperty("ObRoot").GetValue(computeSystemPropertiesHandle); + Type computeSystemPropertiesType; + Type hostComputeInteropType; + + GetHostComputeInteropTypes(out computeSystemPropertiesType, out hostComputeInteropType); + + MethodInfo getComputeSystemPropertiesInfo = hostComputeInteropType.GetMethod("HcsGetComputeSystemProperties"); + + var computeSystemPropertiesHandle = getComputeSystemPropertiesInfo.Invoke(null, new object[]{ ComputeSystem }); + + RuntimeId = (Guid)computeSystemPropertiesType.GetProperty("RuntimeId").GetValue(computeSystemPropertiesHandle); + + // + // Get container object root for Windows Server container. + // + if (RuntimeId == Guid.Empty) + { + ContainerObRoot = (string)computeSystemPropertiesType.GetProperty("ObRoot").GetValue(computeSystemPropertiesHandle); + } } } catch (FileNotFoundException) @@ -2712,77 +2714,6 @@ namespace System.Management.Automation.Runspaces } } - /// - /// Get container id and object root based on given container name. - /// - private void GetContainerPropertiesFromContainerNameInternal() - { - try - { - Type computeSystemPropertiesType; - Type hostComputeInteropType; - object computeSystemPropertiesHandle = null; - int computeSystemPropertiesHandlesCount = 0; - var wildCardPattern = WildcardPattern.Get(ContainerName, WildcardOptions.IgnoreCase); - - GetHostComputeInteropTypes(out computeSystemPropertiesType, out hostComputeInteropType); - - MethodInfo enumerateComputeSystemsInfo = hostComputeInteropType.GetMethod("EnumerateComputeSystems"); - - var computeSystemPropertiesHandles = (IEnumerable)enumerateComputeSystemsInfo.Invoke(null, new object[] { null, null, null, null }); - - foreach (var currentComputeSystemPropertiesHandle in computeSystemPropertiesHandles) - { - string name = (string)computeSystemPropertiesType.GetProperty("Name").GetValue(currentComputeSystemPropertiesHandle); - - if (wildCardPattern.IsMatch(name)) - { - computeSystemPropertiesHandle = currentComputeSystemPropertiesHandle; - computeSystemPropertiesHandlesCount++; - - if (computeSystemPropertiesHandlesCount > 1) - { - ErrorCode = InvalidContainerNameMultiple; - return; - } - } - } - - if (computeSystemPropertiesHandle == null) - { - ErrorCode = InvalidContainerNameNotExist; - return; - } - - ContainerId = (string)computeSystemPropertiesType.GetProperty("Id").GetValue(computeSystemPropertiesHandle); - ContainerName = (string)computeSystemPropertiesType.GetProperty("Name").GetValue(computeSystemPropertiesHandle); - RuntimeId = (Guid)computeSystemPropertiesType.GetProperty("RuntimeId").GetValue(computeSystemPropertiesHandle); - - // - // Get container object root for Windows Server container. - // - if (RuntimeId == Guid.Empty) - { - ContainerObRoot = (string)computeSystemPropertiesType.GetProperty("ObRoot").GetValue(computeSystemPropertiesHandle); - } - } - catch (FileNotFoundException) - { - ErrorCode = ContainersFeatureNotEnabled; - } - catch (FileLoadException) - { - ErrorCode = ContainersFeatureNotEnabled; - } - catch (Exception e) - { - CommandProcessorBase.CheckForSevereException(e); - - ErrorCode = OtherError; - ErrorMessage = GetErrorMessageFromException(e); - } - } - /// /// Run some tasks on MTA thread if needed. /// diff --git a/src/System.Management.Automation/engine/remoting/common/remotingexceptions.cs b/src/System.Management.Automation/engine/remoting/common/remotingexceptions.cs index d083fa8d1..94a00961b 100644 --- a/src/System.Management.Automation/engine/remoting/common/remotingexceptions.cs +++ b/src/System.Management.Automation/engine/remoting/common/remotingexceptions.cs @@ -228,8 +228,6 @@ namespace System.Management.Automation.Remoting CannotTerminateProcessInContainer = 968, ContainersFeatureNotEnabled = 969, RemoteSessionHyperVSocketServerConstructorFailure = 970, - InvalidContainerNameMultiple = 971, - InvalidContainerNameNotExist = 972, ContainerSessionConnectFailed = 973, RemoteSessionHyperVSocketClientConstructorSetSocketOptionFailure = 974, InvalidVMState = 975, diff --git a/src/System.Management.Automation/engine/remoting/fanin/WSManPluginFacade.cs b/src/System.Management.Automation/engine/remoting/fanin/WSManPluginFacade.cs index ff39a87d0..68e49038c 100644 --- a/src/System.Management.Automation/engine/remoting/fanin/WSManPluginFacade.cs +++ b/src/System.Management.Automation/engine/remoting/fanin/WSManPluginFacade.cs @@ -459,7 +459,28 @@ namespace System.Management.Automation.Remoting { return WSManPluginConstants.ExitCodeFailure; } +#if !CORECLR + // For long-path support, Full .NET requires some AppContext switches; + // (for CoreCLR this is Not needed, because CoreCLR supports long paths by default) + // internally in .NET they are cached once retrieved and are typically hit very early during an application run; + // so per .NET team's recommendation, we are setting them as soon as we enter managed code. + // We build against CLR4.5 so we can run on Win7/Win8, but we want to use apis added to CLR 4.6, so we use reflection + try + { + Type appContextType = Type.GetType("System.AppContext"); // type is in mscorlib, so it is sufficient to supply the type name qualified by its namespace + object[] blockLongPathsSwitch = new object[] { "Switch.System.IO.BlockLongPaths", false }; + object[] useLegacyPathHandlingSwitch = new object[] { "Switch.System.IO.UseLegacyPathHandling", false }; + + appContextType.InvokeMember("SetSwitch", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod, null, null, blockLongPathsSwitch); + appContextType.InvokeMember("SetSwitch", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.InvokeMethod, null, null, useLegacyPathHandlingSwitch); + } + catch (Exception e) + { + // If there are any non-critical exceptions (e.g. we are running on CLR prior to 4.6.2), we won't be able to use long paths + CommandProcessorBase.CheckForSevereException(e); + } +#endif ClrFacade.StructureToPtr(workerPtrs.UnmanagedStruct, wkrPtrs, false); return WSManPluginConstants.ExitCodeSuccess; } diff --git a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs index 7970e8c5d..50592a4e4 100644 --- a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs +++ b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs @@ -596,9 +596,11 @@ namespace System.Management.Automation.Language // function wouldn't work properly. Instead, we'll fix things up after the binding decisions are made, see // EnumerableOps.NonEnumerableObjectEnumerator for more comments on how this works. + var bindingRestrictions = BindingRestrictions.GetExpressionRestriction( + Expression.Call(typeof(PSEnumerableBinder).GetMethod("IsComObject", BindingFlags.Static | BindingFlags.NonPublic), + target.Expression)); return new DynamicMetaObject( - Expression.Call(CachedReflectionInfo.EnumerableOps_GetCOMEnumerator, target.Expression), - GetRestrictions(target)).WriteToDebugLog(this); + Expression.Call(CachedReflectionInfo.EnumerableOps_GetCOMEnumerator, target.Expression), bindingRestrictions).WriteToDebugLog(this); } var enumerable = targetValue as IEnumerable; @@ -687,8 +689,8 @@ namespace System.Management.Automation.Language internal static bool IsComObject(object obj) { - // Platform notes: We can't use System.Runtime.InteropServices.Marshal.IsComObject(obj) - // since it doesn't work in partial trust + // we can't use System.Runtime.InteropServices.Marshal.IsComObject(obj) since it doesn't work in partial trust + obj = PSObject.Base(obj); return obj != null && ComObjectTypeInfo != null && ComObjectTypeInfo.IsAssignableFrom(obj.GetType().GetTypeInfo()); } @@ -701,7 +703,7 @@ namespace System.Management.Automation.Language private static IEnumerator NotEnumerableRule(CallSite site, object obj) { - if (!(obj is PSObject) && !(obj is IEnumerable) && !(obj is IEnumerator) && !(obj is DataTable)) + if (!(obj is PSObject) && !(obj is IEnumerable) && !(obj is IEnumerator) && !(obj is DataTable) && !IsComObject(obj)) { return null; } diff --git a/src/System.Management.Automation/engine/runtime/Operations/ClassOps.cs b/src/System.Management.Automation/engine/runtime/Operations/ClassOps.cs index 3816f7b33..fd094c6a0 100644 --- a/src/System.Management.Automation/engine/runtime/Operations/ClassOps.cs +++ b/src/System.Management.Automation/engine/runtime/Operations/ClassOps.cs @@ -9,9 +9,137 @@ using System.Reflection; using System.Reflection.Emit; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; +using System.Management.Automation.Language; +using System.Threading; -namespace System.Management.Automation +// These APIs are not part of the public contract. +// They are implementation details and intendent to be called from generated assemlbies for PS classes. +// +// Because they are called from other assemblies, we have to make them public. +// We put them in Internal namespace to emphasise that despite the fact that they are public, it's not part of API contract. +namespace System.Management.Automation.Internal { + /// + /// Every Runspace in one process contains SessionStateInternal per module (module SessionState). + /// Every RuntimeType is associated to only one SessionState in the Runspace, which creates it: + /// it's ever global state or a module state. + /// In the former case, module can be imported from the different runspaces in the same process. + /// And so runspaces will share RuntimeType. But in every runspace, Type is associated with just one SessionState. + /// We want type methods to be able access $script: variables and module-specific methods. + /// To achive it, we preserve reference to SessionState that creates type in the private field 'SessionStateFieldName'. + /// Later, we use it to call scriptBlocks captured in ScriptBlockMemberMethodWrapper with the right sessionState. + /// + public class SessionStateKeeper + { + // We use ConditionalWeakTable, because if GC already collect Runspace, + // then there is no way to call a ctor on the type in this Runspace. + private readonly ConditionalWeakTable _stateMap; + + internal SessionStateKeeper() + { + _stateMap = new ConditionalWeakTable(); + } + + internal void RegisterRunspace() + { + // it's not get, but really 'Add' value. + // ConditionalWeakTable.Add throw exception, when you are trying to add a value with the same key. + _stateMap.GetValue(Runspace.DefaultRunspace, runspace => runspace.ExecutionContext.EngineSessionState); + } + + /// + /// This method should be called only from generated ctors for PowerShell classes. + /// It's not intended to be a public API, but because we generate type in a different assembly it has to be public. + /// Return type should be SessionStateInternal, but it violates accessibility consistency, so we use object. + /// + /// SessionStateInternal + public object GetSessionState() + { + SessionStateInternal ss = null; + bool found = _stateMap.TryGetValue(Runspace.DefaultRunspace, out ss); + Diagnostics.Assert(found, "We always should be able to find corresponding SessionState"); + return ss; + } + } + + /// + public class ScriptBlockMemberMethodWrapper + { + /// Used in codegen + public static readonly object[] _emptyArgumentArray = Utils.EmptyArray(); // See TypeDefiner.DefineTypeHelper.DefineMethodBody + + // we use this _scriptBlock instance for static methods. + private Lazy _scriptBlock; + private IParameterMetadataProvider _ast; + + /// + /// We use ThreadLocal boundScriptBlock to allow multi-thread execution of instance methods. + /// + private ThreadLocal _boundScriptBlock; + + internal ScriptBlockMemberMethodWrapper(IParameterMetadataProvider ast) + { + _ast = ast; + _scriptBlock = new Lazy(() => new ScriptBlock(_ast, isFilter: false)); + _boundScriptBlock = new ThreadLocal( + () => + { + var sb = _scriptBlock.Value.Clone(); + return sb; + }); + } + + internal void InitAtRuntime() + { + var context = Runspace.DefaultRunspace.ExecutionContext; + _scriptBlock.Value.SessionStateInternal = context.EngineSessionState; + } + + /// + /// + /// target object or null for static call + /// sessionStateInternal from private field of instance or null for static call + /// + public void InvokeHelper(object instance, object sessionStateInternal, object[] args) + { + ScriptBlock sb; + if (instance != null) + { + _boundScriptBlock.Value.SessionStateInternal = (SessionStateInternal)sessionStateInternal; + sb = _boundScriptBlock.Value; + } + else + { + sb = _scriptBlock.Value; + } + + sb.InvokeAsMemberFunction(instance, args); + } + + /// + /// + /// + /// target object or null for static call + /// sessionStateInternal from private field of instance or null for static call + /// + /// + public T InvokeHelperT(object instance, object sessionStateInternal, object[] args) + { + ScriptBlock sb; + if (instance != null) + { + _boundScriptBlock.Value.SessionStateInternal = (SessionStateInternal)sessionStateInternal; + sb = _boundScriptBlock.Value; + } + else + { + sb = _scriptBlock.Value; + } + + return sb.InvokeAsMemberFunctionT(instance, args); + } + } + /// /// Support methods for PowerShell classes. /// diff --git a/src/System.Management.Automation/engine/runtime/Operations/MiscOps.cs b/src/System.Management.Automation/engine/runtime/Operations/MiscOps.cs index a59f637bb..95b475da8 100644 --- a/src/System.Management.Automation/engine/runtime/Operations/MiscOps.cs +++ b/src/System.Management.Automation/engine/runtime/Operations/MiscOps.cs @@ -17,10 +17,6 @@ using System.Management.Automation.Runspaces; using System.Reflection; using System.Runtime.CompilerServices; using System.Text.RegularExpressions; -using System.Threading; -#if !CORECLR -using Microsoft.CodeAnalysis; -#endif using Microsoft.PowerShell.Commands; // ReSharper disable UnusedMember.Global @@ -1183,127 +1179,6 @@ namespace System.Management.Automation } } - /// - /// Every Runspace in one process contains SessionStateInternal per module (module SessionState). - /// Every RuntimeType is associated to only one SessionState in the Runspace, which creates it: - /// it's ever global state or a module state. - /// In the former case, module can be imported from the different runspaces in the same process. - /// And so runspaces will share RuntimeType. But in every runspace, Type is associated with just one SessionState. - /// We want type methods to be able access $script: variables and module-specific methods. - /// To achive it, we preserve reference to SessionState that creates type in the private field 'SessionStateFieldName'. - /// Later, we use it to call scriptBlocks captured in ScriptBlockMemberMethodWrapper with the right sessionState. - /// - public class SessionStateKeeper - { - // We use ConditionalWeakTable, because if GC already collect Runspace, - // then there is no way to call a ctor on the type in this Runspace. - private readonly ConditionalWeakTable _stateMap; - - internal SessionStateKeeper() - { - _stateMap = new ConditionalWeakTable(); - } - - internal void RegisterRunspace() - { - // it's not get, but really 'Add' value. - // ConditionalWeakTable.Add throw exception, when you are trying to add a value with the same key. - _stateMap.GetValue(Runspace.DefaultRunspace, runspace => runspace.ExecutionContext.EngineSessionState); - } - - /// - /// This method should be called only from generated ctors for PowerShell classes. - /// It's not intended to be a public API, but because we generate type in a different assembly it has to be public. - /// Return type should be SessionStateInternal, but it violates accessibility consistency, so we use object. - /// - /// SessionStateInternal - public object GetSessionState() - { - SessionStateInternal ss = null; - bool found = _stateMap.TryGetValue(Runspace.DefaultRunspace, out ss); - Diagnostics.Assert(found, "We always should be able to find corresponding SessionState"); - return ss; - } - } - - /// - public class ScriptBlockMemberMethodWrapper - { - /// Used in codegen - public static readonly object[] _emptyArgumentArray = Utils.EmptyArray(); // See TypeDefiner.DefineTypeHelper.DefineMethodBody - - // we use this _scriptBlock instance for static methods. - private Lazy _scriptBlock; - private IParameterMetadataProvider _ast; - - /// - /// We use ThreadLocal boundScriptBlock to allow multi-thread execution of instance methods. - /// - private ThreadLocal _boundScriptBlock; - - internal ScriptBlockMemberMethodWrapper(IParameterMetadataProvider ast) - { - _ast = ast; - _scriptBlock = new Lazy(() => new ScriptBlock(_ast, isFilter: false)); - _boundScriptBlock = new ThreadLocal( - () => - { - var sb = _scriptBlock.Value.Clone(); - return sb; - }); - } - - internal void InitAtRuntime() - { - var context = Runspace.DefaultRunspace.ExecutionContext; - _scriptBlock.Value.SessionStateInternal = context.EngineSessionState; - } - - /// - /// - /// target object or null for static call - /// sessionStateInternal from private field of instance or null for static call - /// - public void InvokeHelper(object instance, object sessionStateInternal, object[] args) - { - ScriptBlock sb; - if (instance != null) - { - _boundScriptBlock.Value.SessionStateInternal = (SessionStateInternal)sessionStateInternal; - sb = _boundScriptBlock.Value; - } - else - { - sb = _scriptBlock.Value; - } - - sb.InvokeAsMemberFunction(instance, args); - } - - /// - /// - /// - /// target object or null for static call - /// sessionStateInternal from private field of instance or null for static call - /// - /// - public T InvokeHelperT(object instance, object sessionStateInternal, object[] args) - { - ScriptBlock sb; - if (instance != null) - { - _boundScriptBlock.Value.SessionStateInternal = (SessionStateInternal)sessionStateInternal; - sb = _boundScriptBlock.Value; - } - else - { - sb = _scriptBlock.Value; - } - - return sb.InvokeAsMemberFunctionT(instance, args); - } - } - static class HashtableOps { internal static void AddKeyValuePair(IDictionary hashtable, object key, object value, IScriptExtent errorExtent) diff --git a/src/System.Management.Automation/help/HelpFileHelpProvider.cs b/src/System.Management.Automation/help/HelpFileHelpProvider.cs index e3d39d661..e46fb2812 100644 --- a/src/System.Management.Automation/help/HelpFileHelpProvider.cs +++ b/src/System.Management.Automation/help/HelpFileHelpProvider.cs @@ -250,22 +250,22 @@ namespace System.Management.Automation private void GetModuleNameAndVersion(string psmodulePathRoot, string filePath, out string moduleName, out Version moduleVersion) { - Version returnVersion = null; - string returnModuleName = null; + moduleVersion = null; + moduleName = null; - if (filePath.StartsWith(psmodulePathRoot)) + if (filePath.StartsWith(psmodulePathRoot, StringComparison.OrdinalIgnoreCase)) { var moduleRootSubPath = filePath.Remove(0, psmodulePathRoot.Length).TrimStart(Utils.Separators.Directory); var pathParts = moduleRootSubPath.Split(Utils.Separators.Directory, StringSplitOptions.RemoveEmptyEntries); - //returnModuleRootPath = Path.Combine(psmodulePathRoot, pathParts[0]); - returnModuleName = pathParts[0]; + moduleName = pathParts[0]; var potentialVersion = pathParts[1]; - Version.TryParse(potentialVersion, out returnVersion); + Version result; + if (Version.TryParse(potentialVersion, out result)) + { + moduleVersion = result; + } } - - moduleVersion = returnVersion; - moduleName = returnModuleName; } /// diff --git a/src/System.Management.Automation/resources/Modules.resx b/src/System.Management.Automation/resources/Modules.resx index e3d9d77d1..2a0d13659 100644 --- a/src/System.Management.Automation/resources/Modules.resx +++ b/src/System.Management.Automation/resources/Modules.resx @@ -392,7 +392,7 @@ Minimum version of the Windows PowerShell engine required by this module - Minimum version of the common language runtime (CLR) required by this module + Minimum version of the common language runtime (CLR) required by this module. {0} Modules that must be imported into the global environment prior to importing this module @@ -473,7 +473,7 @@ List of all modules packaged with this module - Minimum version of Microsoft .NET Framework required by this module + Minimum version of Microsoft .NET Framework required by this module. {0} Name of the Windows PowerShell host required by this module @@ -634,4 +634,7 @@ The module to process '{0}', listed in field '{1}' of module manifest '{2}' was not processed. {3} - + + This prerequisite is valid for the PowerShell Desktop edition only. + + \ No newline at end of file diff --git a/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx b/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx index cabb67a5f..d8148083f 100644 --- a/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx +++ b/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx @@ -1204,12 +1204,6 @@ All WinRM sessions connected to Windows PowerShell session configurations, such The input ContainerId {0} does not exist, or the corresponding container is not running. - - The input ContainerName {0} does not resolve to a single running container. - - - The input ContainerName {0} does not exist, or the corresponding container is not running. - The input VMId parameter does not resolve to a single virtual machine. diff --git a/src/System.Management.Automation/security/Authenticode.cs b/src/System.Management.Automation/security/Authenticode.cs index f175379e9..e93270e6c 100644 --- a/src/System.Management.Automation/security/Authenticode.cs +++ b/src/System.Management.Automation/security/Authenticode.cs @@ -121,6 +121,7 @@ namespace System.Management.Automation /// /// /// + [ArchitectureSensitive] internal static Signature SignFile(SigningOption option, string fileName, X509Certificate2 certificate, @@ -312,6 +313,7 @@ namespace System.Management.Automation /// /// /// + [ArchitectureSensitive] internal static Signature GetSignature(string fileName, string fileContent) { Signature signature = null; @@ -503,6 +505,7 @@ namespace System.Management.Automation return signature; } + [ArchitectureSensitive] private static DWORD GetWinTrustData(string fileName, string fileContent, out NativeMethods.WINTRUST_DATA wtData) { @@ -559,6 +562,7 @@ namespace System.Management.Automation return dwResult; } + [ArchitectureSensitive] private static X509Certificate2 GetCertFromChain(IntPtr pSigner) { X509Certificate2 signerCert = null; @@ -581,6 +585,7 @@ namespace System.Management.Automation return signerCert; } + [ArchitectureSensitive] private static Signature GetSignatureFromWintrustData( string filePath, DWORD error, @@ -653,6 +658,7 @@ namespace System.Management.Automation return signature; } + [ArchitectureSensitive] private static DWORD GetLastWin32Error() { int error = Marshal.GetLastWin32Error(); diff --git a/src/System.Management.Automation/security/SecureStringHelper.cs b/src/System.Management.Automation/security/SecureStringHelper.cs index 7761b5ae6..50948e91f 100644 --- a/src/System.Management.Automation/security/SecureStringHelper.cs +++ b/src/System.Management.Automation/security/SecureStringHelper.cs @@ -76,6 +76,7 @@ namespace Microsoft.PowerShell /// /// contents of s (char[]) converted to byte[] /// + [ArchitectureSensitive] internal static byte[] GetData(SecureString s) { // diff --git a/src/System.Management.Automation/security/SecuritySupport.cs b/src/System.Management.Automation/security/SecuritySupport.cs index f0af41a6e..755b1df4c 100644 --- a/src/System.Management.Automation/security/SecuritySupport.cs +++ b/src/System.Management.Automation/security/SecuritySupport.cs @@ -466,6 +466,7 @@ namespace System.Management.Automation /// /// The path to the file in question /// A file handle to the file in question, if available. + [ArchitectureSensitive] [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods")] internal static SaferPolicy GetSaferPolicy(string path, SafeHandle handle) { @@ -758,6 +759,7 @@ namespace System.Management.Automation /// /// /// + [ArchitectureSensitive] internal static Collection GetCertEKU(X509Certificate2 cert) { Collection ekus = new Collection(); diff --git a/src/System.Management.Automation/security/nativeMethods.cs b/src/System.Management.Automation/security/nativeMethods.cs index 2f374e918..b297e8241 100644 --- a/src/System.Management.Automation/security/nativeMethods.cs +++ b/src/System.Management.Automation/security/nativeMethods.cs @@ -587,6 +587,7 @@ namespace System.Management.Automation.Security internal IntPtr psUnauthenticatedNotUsed; // PCRYPT_ATTRIBUTES }; + [ArchitectureSensitive] internal static CRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO InitSignInfoExtendedStruct(string description, string moreInfoUrl, @@ -692,6 +693,7 @@ namespace System.Management.Automation.Security uint dwGroupId); + [ArchitectureSensitive] internal static DWORD GetCertChoiceFromSigningOption( SigningOption option) { @@ -719,6 +721,7 @@ namespace System.Management.Automation.Security return cc; } + [ArchitectureSensitive] internal static CRYPTUI_WIZ_DIGITAL_SIGN_INFO InitSignInfoStruct(string fileName, X509Certificate2 signingCert, @@ -815,6 +818,7 @@ namespace System.Management.Automation.Security internal byte[] Data4; } + [ArchitectureSensitive] internal static WINTRUST_FILE_INFO InitWintrustFileInfoStruct(string fileName) { WINTRUST_FILE_INFO fi = new WINTRUST_FILE_INFO(); @@ -827,6 +831,7 @@ namespace System.Management.Automation.Security return fi; } + [ArchitectureSensitive] internal static WINTRUST_BLOB_INFO InitWintrustBlobInfoStruct(string fileName, string content) { WINTRUST_BLOB_INFO bi = new WINTRUST_BLOB_INFO(); @@ -959,6 +964,7 @@ namespace System.Management.Automation.Security internal uint dwUIContext; } + [ArchitectureSensitive] internal static WINTRUST_DATA InitWintrustDataStructFromFile(WINTRUST_FILE_INFO wfi) { WINTRUST_DATA wtd = new WINTRUST_DATA(); @@ -982,6 +988,7 @@ namespace System.Management.Automation.Security return wtd; } + [ArchitectureSensitive] internal static WINTRUST_DATA InitWintrustDataStructFromBlob(WINTRUST_BLOB_INFO wbi) { WINTRUST_DATA wtd = new WINTRUST_DATA(); @@ -1005,6 +1012,7 @@ namespace System.Management.Automation.Security return wtd; } + [ArchitectureSensitive] internal static DWORD DestroyWintrustDataStruct(WINTRUST_DATA wtd) { DWORD dwResult = Win32Errors.E_FAIL; diff --git a/src/System.Management.Automation/utils/ClrFacade.cs b/src/System.Management.Automation/utils/ClrFacade.cs index d2d72851d..54f6424ac 100644 --- a/src/System.Management.Automation/utils/ClrFacade.cs +++ b/src/System.Management.Automation/utils/ClrFacade.cs @@ -95,7 +95,17 @@ namespace System.Management.Automation internal static IntPtr GetRawProcessHandle(Process process) { #if CORECLR + try + { return process.SafeHandle.DangerousGetHandle(); + } + catch (InvalidOperationException) + { + // It's possible that the process has already exited when we try to get its handle. + // In that case, InvalidOperationException will be thrown from Process.SafeHandle, + // and we return the invalid zero pointer. + return IntPtr.Zero; + } #else return process.Handle; #endif diff --git a/src/System.Management.Automation/utils/PsUtils.cs b/src/System.Management.Automation/utils/PsUtils.cs index 574a4704e..f27825042 100644 --- a/src/System.Management.Automation/utils/PsUtils.cs +++ b/src/System.Management.Automation/utils/PsUtils.cs @@ -866,7 +866,7 @@ namespace System.Management.Automation internal static readonly string[] ManifestModuleVersionPropertyName = new[] {"ModuleVersion"}; internal static readonly string[] ManifestGuidPropertyName = new[] { "GUID" }; - internal static readonly string[] FastModuleManifestAnalysisPropertyNames = new[] {"AliasesToExport", "CmdletsToExport", "FunctionsToExport", "NestedModules", "RootModule", "ModuleToProcess"}; + internal static readonly string[] FastModuleManifestAnalysisPropertyNames = new[] {"AliasesToExport", "CmdletsToExport", "FunctionsToExport", "NestedModules", "RootModule", "ModuleToProcess", "ModuleVersion"}; internal static Hashtable GetModuleManifestProperties(string psDataFilePath, string[] keys) { From d2cb5610e1812b2c4dec1785737ceab915aaa876 Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Wed, 15 Jun 2016 17:59:26 -0700 Subject: [PATCH 2/2] Resurrect ArchitectureSensitiveAttribute Removal was backed out in SD:712734 --- src/System.Management.Automation/map.json | 1 + .../utils/ArchitectureSensitiveAttribute.cs | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 src/System.Management.Automation/utils/ArchitectureSensitiveAttribute.cs diff --git a/src/System.Management.Automation/map.json b/src/System.Management.Automation/map.json index 17e1a5370..686728edb 100644 --- a/src/System.Management.Automation/map.json +++ b/src/System.Management.Automation/map.json @@ -472,6 +472,7 @@ "monad/src/engine/resources/Authenticode.resx": "resources/Authenticode.resx", "monad/src/engine/COM/ComUtil.cs": "engine/COM/ComUtil.cs", "monad/src/engine/hostifaces/MshHostUserInterface.cs": "engine/hostifaces/MshHostUserInterface.cs", + "monad/src/utils/ArchitectureSensitiveAttribute.cs": "utils/ArchitectureSensitiveAttribute.cs", "monad/src/engine/DriveInterfaces.cs": "engine/DriveInterfaces.cs", "monad/src/engine/ComInterop/Errors.cs": "engine/ComInterop/Errors.cs", "monad/src/singleshell/config/MshConsoleInfo.cs": "singleshell/config/MshConsoleInfo.cs", diff --git a/src/System.Management.Automation/utils/ArchitectureSensitiveAttribute.cs b/src/System.Management.Automation/utils/ArchitectureSensitiveAttribute.cs new file mode 100644 index 000000000..9cf302f0f --- /dev/null +++ b/src/System.Management.Automation/utils/ArchitectureSensitiveAttribute.cs @@ -0,0 +1,28 @@ +/********************************************************************++ +Copyright (c) Microsoft Corporation. All rights reserved. +--********************************************************************/ + +using System; +using System.Reflection; + +namespace System.Management.Automation.Internal +{ + /// + /// This attribute is used for Design For Testability. + /// It should be placed on any method containing code + /// which is likely to be sensitive to X86/X64/IA64 issues, + /// primarily code which calls DllImports or otherwise uses + /// NativeMethods. This allows us to generate code coverage + /// data specific to architecture sensitive code. + /// + [AttributeUsage(AttributeTargets.Method, AllowMultiple=false)] + internal class ArchitectureSensitiveAttribute : Attribute + { + /// + /// Constructor for the ArchitectureSensitiveAttribute class. + /// + internal ArchitectureSensitiveAttribute () + { + } + } +}