/********************************************************************++ Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Management.Automation; using System.Management.Automation.Remoting; using System.Management.Automation.Runspaces; namespace System.Management.Automation.Remoting { /// /// IMPORTANT: proxy configuration is supported for HTTPS only; for HTTP, the direct /// connection to the server is used /// [SuppressMessage("Microsoft.Design", "CA1027:MarkEnumsWithFlags")] public enum ProxyAccessType { /// /// ProxyAccessType is not specified. That means Proxy information (ProxyAccessType, ProxyAuthenticationMechanism /// and ProxyCredential)is not passed to WSMan at all. /// None = 0, /// /// use the Internet Explorer proxy configuration for the current user. /// Internet Explorer proxy settings for the current active network connection. /// This option requires the user profile to be loaded, so the option can /// be directly used when called within a process that is running under /// an interactive user account identity; if the client application is running /// under a user context different than the interactive user, the client /// application has to explicitly load the user profile prior to using this option. /// IEConfig = 1, /// /// proxy settings configured for WinHTTP, using the ProxyCfg.exe utility /// WinHttpConfig = 2, /// /// Force autodetection of proxy /// AutoDetect = 4, /// /// do not use a proxy server - resolves all host names locally /// NoProxyServer = 8 } /// /// Options for a remote PSSession /// public sealed class PSSessionOption { /// /// Creates a new instance of /// public PSSessionOption() { } /// /// The MaximumConnectionRedirectionCount parameter enables the implicit redirection functionality. /// -1 = no limit /// 0 = no redirection /// public int MaximumConnectionRedirectionCount { get; set; } = WSManConnectionInfo.defaultMaximumConnectionRedirectionCount; /// /// If false, underlying WSMan infrastructure will compress data sent on the network. /// If true, data will not be compressed. Compression improves performance by /// reducing the amount of data sent on the network. Compression my require extra /// memory consumption and CPU usage. In cases where available memory / CPU is less, /// set this property to "true". /// By default the value of this property is "false". /// public bool NoCompression { get; set; } = false; /// /// If true then Operating System won't load the user profile (i.e. registry keys under HKCU) on the remote server /// which can result in a faster session creation time. This option won't have any effect if the remote machine has /// already loaded the profile (i.e. in another session). /// public bool NoMachineProfile { get; set; } = false; /// /// By default, ProxyAccessType is None, that means Proxy information (ProxyAccessType, /// ProxyAuthenticationMechanism and ProxyCredential)is not passed to WSMan at all. /// public ProxyAccessType ProxyAccessType { get; set; } = ProxyAccessType.None; /// /// The following is the definition of the input parameter "ProxyAuthentication". /// This parameter takes a set of authentication methods the user can select /// from. The available options should be as follows: /// - Negotiate: Use the default authentication (as defined by the underlying /// protocol) for establishing a remote connection. /// - Basic: Use basic authentication for establishing a remote connection /// - Digest: Use Digest authentication for establishing a remote connection /// /// Default is Negotiate. /// public AuthenticationMechanism ProxyAuthentication { get { return _proxyAuthentication; } set { switch (value) { case AuthenticationMechanism.Basic: case AuthenticationMechanism.Negotiate: case AuthenticationMechanism.Digest: _proxyAuthentication = value; break; default: string message = PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.ProxyAmbiguosAuthentication, value, AuthenticationMechanism.Basic.ToString(), AuthenticationMechanism.Negotiate.ToString(), AuthenticationMechanism.Digest.ToString()); throw new ArgumentException(message); } } } private AuthenticationMechanism _proxyAuthentication = AuthenticationMechanism.Negotiate; /// /// The following is the definition of the input parameter "ProxyCredential". /// public PSCredential ProxyCredential { get; set; } /// /// When connecting over HTTPS, the client does not validate that the server /// certificate is signed by a trusted certificate authority (CA). Use only when /// the remote computer is trusted by other means, for example, if the remote /// computer is part of a network that is physically secure and isolated or the /// remote computer is listed as a trusted host in WinRM configuration /// public bool SkipCACheck { get; set; } /// /// Indicates that certificate common name (CN) of the server need not match the /// hostname of the server. Used only in remote operations using https. This /// option should only be used for trusted machines. /// public bool SkipCNCheck { get; set; } /// /// Indicates that certificate common name (CN) of the server need not match the /// hostname of the server. Used only in remote operations using https. This /// option should only be used for trusted machines /// public bool SkipRevocationCheck { get; set; } /// /// The duration for which PowerShell remoting waits before timing out /// for any operation. The user would like to tweak this timeout /// depending on whether he/she is connecting to a machine in the data /// center or across a slow WAN. /// /// Default: 3*60*1000 == 3minutes /// public TimeSpan OperationTimeout { get; set; } = TimeSpan.FromMilliseconds(BaseTransportManager.ClientDefaultOperationTimeoutMs); /// /// Specifies that no encryption will be used when doing remote operations over /// http. Unencrypted traffix is not allowed by default and must be enabled in /// the local configuration /// public bool NoEncryption { get; set; } /// /// Indicates the request is encoded in UTF16 format rather than UTF8 format; /// UTF8 is the default. /// [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "UTF")] public bool UseUTF16 { get; set; } /// /// Uses Service Principal Name (SPN) along with the Port number during authentication. /// [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SPN")] public bool IncludePortInSPN { get; set; } /// /// Determines how server in disconnected state deals with cached output /// data when the cache becomes filled. /// Default value is 'block mode' where command execution is blocked after /// the server side data cache becomes filled. /// public OutputBufferingMode OutputBufferingMode { get; set; } = WSManConnectionInfo.DefaultOutputBufferingMode; /// /// Number of times a connection will be re-attempted when a connection fails due to network /// issues. /// public int MaxConnectionRetryCount { get; set; } = WSManConnectionInfo.DefaultMaxConnectionRetryCount; /// /// Culture that the remote session should use /// public CultureInfo Culture { get; set; } /// /// UI culture that the remote session should use /// public CultureInfo UICulture { get; set; } /// /// Total data (in bytes) that can be received from a remote machine /// targeted towards a command. If null, then the size is unlimited. /// Default is unlimited data. /// public Nullable MaximumReceivedDataSizePerCommand { get; set; } /// /// Maximum size (in bytes) of a deserialized object received from a remote machine. /// If null, then the size is unlimited. Default is 200MB object size. /// public Nullable MaximumReceivedObjectSize { get; set; } = 200 << 20; /// /// Application arguments the server can see in /// [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public PSPrimitiveDictionary ApplicationArguments { get; set; } /// /// The duration for which PowerShell remoting waits before timing out on a connection to a remote machine. /// Simply put, the timeout for a remote runspace creation. /// The user would like to tweak this timeout depending on whether /// he/she is connecting to a machine in the data center or across a slow WAN. /// /// Default: 3 * 60 * 1000 = 3 minutes /// public TimeSpan OpenTimeout { get; set; } = TimeSpan.FromMilliseconds(RunspaceConnectionInfo.DefaultOpenTimeout); /// /// The duration 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 user 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 user a feeling that the PowerShell client has hung. /// /// Default: 60 * 1000 = 1 minute /// public TimeSpan CancelTimeout { get; set; } = TimeSpan.FromMilliseconds(RunspaceConnectionInfo.defaultCancelTimeout); /// /// The duration for which a Runspace on server needs to wait before it declares the client dead and closes itself down. /// This is especially important as these values may have to be configured differently for enterprise administration /// and exchange scenarios. /// /// Default: -1 -> Use current server value for IdleTimeout. /// public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromMilliseconds(RunspaceConnectionInfo.DefaultIdleTimeout); } } namespace Microsoft.PowerShell.Commands { /// /// This class implements New-PSSessionOption cmdlet. /// Spec: TBD /// [Cmdlet(VerbsCommon.New, "PSSessionOption", HelpUri = "http://go.microsoft.com/fwlink/?LinkID=144305", RemotingCapability = RemotingCapability.None)] [OutputType(typeof(PSSessionOption))] public sealed class NewPSSessionOptionCommand : PSCmdlet { #region Parameters (specific to PSSessionOption) /// /// The MaximumRedirection parameter enables the implicit redirection functionality /// -1 = no limit /// 0 = no redirection /// [Parameter] public int MaximumRedirection { get { return _maximumRedirection.Value; } set { _maximumRedirection = value; } } private int? _maximumRedirection; /// /// If false, underlying WSMan infrastructure will compress data sent on the network. /// If true, data will not be compressed. Compression improves performance by /// reducing the amount of data sent on the network. Compression my require extra /// memory consumption and CPU usage. In cases where available memory / CPU is less, /// set this property to "true". /// By default the value of this property is "false". /// [Parameter] public SwitchParameter NoCompression { get; set; } /// /// If true then Operating System won't load the user profile (i.e. registry keys under HKCU) on the remote server /// which can result in a faster session creation time. This option won't have any effect if the remote machine has /// already loaded the profile (i.e. in another session). /// [Parameter] public SwitchParameter NoMachineProfile { get; set; } /// /// Culture that the remote session should use /// [Parameter] [ValidateNotNull] public CultureInfo Culture { get; set; } /// /// UI culture that the remote session should use /// [Parameter] [ValidateNotNull] public CultureInfo UICulture { get; set; } /// /// Total data (in bytes) that can be received from a remote machine /// targeted towards a command. If null, then the size is unlimited. /// Default is unlimited data. /// [Parameter] public int MaximumReceivedDataSizePerCommand { get { return _maxRecvdDataSizePerCommand.Value; } set { _maxRecvdDataSizePerCommand = value; } } private Nullable _maxRecvdDataSizePerCommand; /// /// Maximum size (in bytes) of a deserialized object received from a remote machine. /// If null, then the size is unlimited. Default is unlimited object size. /// [Parameter] public int MaximumReceivedObjectSize { get { return _maxRecvdObjectSize.Value; } set { _maxRecvdObjectSize = value; } } private Nullable _maxRecvdObjectSize; /// /// Specifies the output mode on the server when it is in Disconnected mode /// and its output data cache becomes full. /// [Parameter] public OutputBufferingMode OutputBufferingMode { get; set; } /// /// Maximum number of times a connection will be re-attempted when a connection fails due to network /// issues. /// [Parameter] [ValidateRange(0, Int32.MaxValue)] public int MaxConnectionRetryCount { get; set; } /// /// Application arguments the server can see in /// [Parameter] [ValidateNotNull] [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] public PSPrimitiveDictionary ApplicationArguments { get; set; } /// /// The duration for which PowerShell remoting waits (in milliseconds) before timing /// out on a connection to a remote machine. Simply put, the timeout for a remote /// runspace creation. /// /// The user would like to tweak this timeout depending on whether /// he/she is connecting to a machine in the data center or across a slow WAN. /// [Parameter] [Alias("OpenTimeoutMSec")] [ValidateRange(0, Int32.MaxValue)] public int OpenTimeout { get { return _openTimeout.HasValue ? _openTimeout.Value : RunspaceConnectionInfo.DefaultOpenTimeout; } set { _openTimeout = value; } } private int? _openTimeout; /// /// The duration for which PowerShell should wait (in milliseconds) 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 user /// 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 user /// a feeling that the PowerShell client has hung. /// [Parameter] [Alias("CancelTimeoutMSec")] [ValidateRange(0, Int32.MaxValue)] public int CancelTimeout { get { return _cancelTimeout.HasValue ? _cancelTimeout.Value : BaseTransportManager.ClientCloseTimeoutMs; } set { _cancelTimeout = value; } } private int? _cancelTimeout; /// /// The duration for which a Runspace on server needs to wait (in milliseconds) before it /// declares the client dead and closes itself down. /// This is especially important as these values may have to be configured differently /// for enterprise administration scenarios. /// [Parameter] [ValidateRange(-1, Int32.MaxValue)] [Alias("IdleTimeoutMSec")] public int IdleTimeout { get { return _idleTimeout.HasValue ? _idleTimeout.Value : RunspaceConnectionInfo.DefaultIdleTimeout; } set { _idleTimeout = value; } } private int? _idleTimeout; #endregion Parameters #region Parameters copied from New-WSManSessionOption /// /// By default, ProxyAccessType is None, that means Proxy information (ProxyAccessType, /// ProxyAuthenticationMechanism and ProxyCredential)is not passed to WSMan at all. /// [Parameter] [ValidateNotNullOrEmpty] public ProxyAccessType ProxyAccessType { get; set; } = ProxyAccessType.None; /// /// The following is the definition of the input parameter "ProxyAuthentication". /// This parameter takes a set of authentication methods the user can select /// from. The available options should be as follows: /// - Negotiate: Use the default authentication (as defined by the underlying /// protocol) for establishing a remote connection. /// - Basic: Use basic authentication for establishing a remote connection /// - Digest: Use Digest authentication for establishing a remote connection /// [Parameter] public AuthenticationMechanism ProxyAuthentication { get; set; } = AuthenticationMechanism.Negotiate; /// /// The following is the definition of the input parameter "ProxyCredential". /// [Parameter] [ValidateNotNullOrEmpty] [Credential] public PSCredential ProxyCredential { get; set; } /// /// The following is the definition of the input parameter "SkipCACheck". /// When connecting over HTTPS, the client does not validate that the server /// certificate is signed by a trusted certificate authority (CA). Use only when /// the remote computer is trusted by other means, for example, if the remote /// computer is part of a network that is physically secure and isolated or the /// remote computer is listed as a trusted host in WinRM configuration /// [Parameter] public SwitchParameter SkipCACheck { get { return _skipcacheck; } set { _skipcacheck = value; } } private bool _skipcacheck; /// /// The following is the definition of the input parameter "SkipCNCheck". /// Indicates that certificate common name (CN) of the server need not match the /// hostname of the server. Used only in remote operations using https. This /// option should only be used for trusted machines /// [Parameter] public SwitchParameter SkipCNCheck { get { return _skipcncheck; } set { _skipcncheck = value; } } private bool _skipcncheck; /// /// The following is the definition of the input parameter "SkipRevocation". /// Indicates that certificate common name (CN) of the server need not match the /// hostname of the server. Used only in remote operations using https. This /// option should only be used for trusted machines /// [Parameter] public SwitchParameter SkipRevocationCheck { get { return _skiprevocationcheck; } set { _skiprevocationcheck = value; } } private bool _skiprevocationcheck; /// /// The following is the definition of the input parameter "Timeout". /// Defines the timeout in milliseconds for the wsman operation /// [Parameter] [Alias("OperationTimeoutMSec")] [ValidateRange(0, Int32.MaxValue)] public Int32 OperationTimeout { get { return (_operationtimeout.HasValue ? _operationtimeout.Value : BaseTransportManager.ClientDefaultOperationTimeoutMs); } set { _operationtimeout = value; } } private Int32? _operationtimeout; /// /// The following is the definition of the input parameter "UnEncrypted". /// Specifies that no encryption will be used when doing remote operations over /// http. Unencrypted traffix is not allowed by default and must be enabled in /// the local configuration /// [Parameter] public SwitchParameter NoEncryption { get { return _noencryption; } set { _noencryption = value; } } private bool _noencryption; /// /// The following is the definition of the input parameter "UTF16". /// Indicates the request is encoded in UTF16 format rather than UTF8 format; /// UTF8 is the default. /// [Parameter] [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "UTF")] public SwitchParameter UseUTF16 { get { return _useutf16; } set { _useutf16 = value; } } private bool _useutf16; /// /// Uses Service Principal Name (SPN) along with the Port number during authentication. /// [Parameter] [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "SPN")] public SwitchParameter IncludePortInSPN { get { return _includePortInSPN; } set { _includePortInSPN = value; } } private bool _includePortInSPN; #endregion #region Implementation /// /// Performs initialization of cmdlet execution. /// protected override void BeginProcessing() { PSSessionOption result = new PSSessionOption(); // Begin: WSMan specific options result.ProxyAccessType = this.ProxyAccessType; result.ProxyAuthentication = this.ProxyAuthentication; result.ProxyCredential = this.ProxyCredential; result.SkipCACheck = this.SkipCACheck; result.SkipCNCheck = this.SkipCNCheck; result.SkipRevocationCheck = this.SkipRevocationCheck; if (_operationtimeout.HasValue) { result.OperationTimeout = TimeSpan.FromMilliseconds(_operationtimeout.Value); } result.NoEncryption = this.NoEncryption; result.UseUTF16 = this.UseUTF16; result.IncludePortInSPN = this.IncludePortInSPN; // End: WSMan specific options if (_maximumRedirection.HasValue) { result.MaximumConnectionRedirectionCount = this.MaximumRedirection; } result.NoCompression = this.NoCompression.IsPresent; result.NoMachineProfile = this.NoMachineProfile.IsPresent; result.MaximumReceivedDataSizePerCommand = _maxRecvdDataSizePerCommand; result.MaximumReceivedObjectSize = _maxRecvdObjectSize; if (this.Culture != null) { result.Culture = this.Culture; } if (this.UICulture != null) { result.UICulture = this.UICulture; } if (_openTimeout.HasValue) { result.OpenTimeout = TimeSpan.FromMilliseconds(_openTimeout.Value); } if (_cancelTimeout.HasValue) { result.CancelTimeout = TimeSpan.FromMilliseconds(_cancelTimeout.Value); } if (_idleTimeout.HasValue) { result.IdleTimeout = TimeSpan.FromMilliseconds(_idleTimeout.Value); } result.OutputBufferingMode = OutputBufferingMode; result.MaxConnectionRetryCount = MaxConnectionRetryCount; if (this.ApplicationArguments != null) { result.ApplicationArguments = this.ApplicationArguments; } this.WriteObject(result); } #endregion Methods } }