/********************************************************************++
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
}
}