### Install PSWSMan Module Source: https://github.com/jborean93/pswsman/blob/main/README.md Use PowerShellGet to install the module for either the current user or all users. ```powershell # Install for only the current user Install-Module -Name PSWSMan -Scope CurrentUser # Install for all users Install-Module -Name PSWSMan -Scope AllUsers ``` -------------------------------- ### Start the Test Environment with Vagrant and Ansible Source: https://github.com/jborean93/pswsman/blob/main/tests/integration/README.md Use Vagrant to start the virtual machines and Ansible to provision them for the test environment. ```bash vagrant up ansible-playbook main.yml -vv ``` -------------------------------- ### Clone wsman-environment and Install Dependencies Source: https://github.com/jborean93/pswsman/blob/main/tests/integration/README.md Clone the wsman-environment repository and install Ansible collections required for setting up the test environment. ```bash git clone https://github.com/jborean93/wsman-environment.git cd wsman-environment ansible-galaxy collection install -r requirements.yml ``` -------------------------------- ### Configure WinRM authentication methods Source: https://context7.com/jborean93/pswsman/llms.txt Examples for connecting using various authentication protocols. Note that Basic and NTLM authentication should be used with HTTPS for security. ```powershell # Basic authentication (local accounts only, use with HTTPS) # First enable on server: Set-Item -Path WSMan:\localhost\Service\Auth\Basic -Value True $cred = Get-Credential -UserName "localadmin" # Don't use DOMAIN\user format $pso = New-PSWSManSessionOption -AuthMethod Basic Invoke-Command -ComputerName Server01 -UseSSL -Credential $cred -SessionOption $pso -ScriptBlock { "Authenticated with Basic auth" } ``` ```powershell # Kerberos authentication (domain accounts, supports delegation) $pso = New-PSWSManSessionOption -AuthMethod Kerberos -RequestKerberosDelegate Invoke-Command -ComputerName dc01.domain.com -SessionOption $pso -ScriptBlock { # Can access downstream resources with delegated credentials Get-ADUser -Filter * | Select-Object -First 5 } ``` ```powershell # Negotiate authentication (default - tries Kerberos, falls back to NTLM) Invoke-Command -ComputerName Server01 -ScriptBlock { hostname } ``` ```powershell # NTLM authentication (explicit, use with HTTPS for security) $pso = New-PSWSManSessionOption -AuthMethod NTLM $cred = Get-Credential Invoke-Command -ComputerName Server01 -UseSSL -Credential $cred -SessionOption $pso -ScriptBlock { "Connected with NTLM" } ``` ```powershell # CredSSP for double-hop scenarios # First enable on server: Enable-WSManCredSSP -Role Server $cred = Get-Credential Invoke-Command -ComputerName Server01 -Authentication CredSSP -Credential $cred -ScriptBlock { # Credentials are delegated - can access network resources Copy-Item -Path "\\FileServer\Share\file.txt" -Destination "C:\Temp\" Get-Content "C:\Temp\file.txt" } ``` -------------------------------- ### Define Test Settings JSON Source: https://github.com/jborean93/pswsman/blob/main/tests/integration/README.md Example structure for the test.settings.json file using values exported from the configuration script. ```json { ... "data": { ... "exchange_online": { "organization": "Located in exchange.json - organization", "app_id": "Located in exchange.json - app_id", "certificate_path": "path/to/exchange-cert.pfx", "certificate_password": "Located in exchange.json - cert_password" } } } ``` -------------------------------- ### Create Callback to Reject Specific Hosts Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/New-PSWSManCertValidationCallback.md This example demonstrates creating a callback that rejects certificates with specific subjects. It uses the `$using:` syntax to access external variables like `$denyHosts` within the scriptblock. ```powershell PS C:\> $denyHosts = @('CN=host1', 'CN=host2') PS C:\> $delegate = New-PSWSManCertValidationCallback -ScriptBlock { param ( [System.Net.Security.SslStream]$Sender, [System.Security.Cryptography.X509Certificates.X509Certificate]$Certificate, [System.Security.Cryptography.X509Certificates.X509Chain]$Chain, [System.Net.Security.SslPolicyErrors]$PolicyErrors ) # Delegate has access to the same host to display host messages Write-Host $Certificate.Subject # Pulls in the $denyHosts variable $denyHosts = $using:denyHosts # Returns $true if the subject is not one we want to deny $Certificate.Subject -notin $denyHosts } PS C:\> $tlsOptions = [System.Net.Security.SslClientAuthenticationOptions]@{ RemoteCertificateValidationCallback = $delegate TargetHost = 'host1' } PS C:\> $pso = New-PSWSManSessionOption -TlsOption $tlsOptions ``` -------------------------------- ### Install Certificate into Trusted Stores Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/about_PSWSManAuthentication.md Installs the reloaded certificate (without its private key) into the Local Machine's Root and TrustedPeople stores. This ensures the system trusts the self-signed certificate for authentication purposes. ```powershell # Store the certificate in the trusted root store. This can be skipped if the # cert is signed by a trusted CA. If the cert is signed but the issuer is not # trusted, this should be the root CA certificate to trust. $store = Get-Item -Path Cert:\LocalMachine\Root $store.Open("ReadWrite") $store.Add($certNoKey) $store.Dispose() # Install the client certificate into the TrustedPeople store. # This is the client certificate itself and not the CA. $store = Get-Item -Path Cert:\LocalMachine\TrustedPeople $store.Open("ReadWrite") $store.Add($certNoKey) $store.Dispose() ``` -------------------------------- ### Accessing Downstream Server Fails Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/about_PSWSManAuthentication.md This example demonstrates a common scenario where accessing a resource on a downstream server from a remote PowerShell session fails due to the double hop problem. ```powershell Invoke-Command -ComputerName Server1 -ScriptBlock { # This will fail to access Server2 Get-Content -Path "\\Server2\share\file.txt" } ``` -------------------------------- ### Get-PSWSManAuthProvider Source: https://context7.com/jborean93/pswsman/llms.txt Gets the current default authentication provider used by PSWSMan for NTLM, Kerberos, Negotiate, or CredSSP authentication. Returns either "System" (using OS-provided SSPI/GSSAPI libraries) or "Devolutions" (using the bundled sspi-rs library). The default provider is "System". ```APIDOC ## Get-PSWSManAuthProvider ### Description Gets the current default authentication provider used by PSWSMan for NTLM, Kerberos, Negotiate, or CredSSP authentication. Returns either "System" (using OS-provided SSPI/GSSAPI libraries) or "Devolutions" (using the bundled sspi-rs library). The default provider is "System". ### Method GET ### Endpoint /pswsman/auth/provider ### Parameters None ### Response #### Success Response (200) - **provider** (string) - The name of the current default authentication provider ('System' or 'Devolutions'). ### Response Example ``` System ``` ``` -------------------------------- ### Enable PSWSMan Transport Source: https://context7.com/jborean93/pswsman/llms.txt Installs the module and enables the PSWSMan transport globally for the current PowerShell process. Once enabled, standard PowerShell remoting cmdlets automatically utilize the PSWSMan client. ```powershell # Install the module from PowerShell Gallery Install-Module -Name PSWSMan -Scope CurrentUser # Enable PSWSMan in the current PowerShell session (with confirmation prompt) Enable-PSWSMan # Enable PSWSMan without confirmation prompt Enable-PSWSMan -Force # After enabling, all WSMan operations use PSWSMan automatically $session = New-PSSession -ComputerName Server01 Invoke-Command -Session $session -ScriptBlock { hostname } # Run a remote command directly Invoke-Command -ComputerName Server01 -ScriptBlock { "Hello from $env:COMPUTERNAME!" } # Enter an interactive remote session Enter-PSSession -ComputerName Server01 # Debug PSWSMan hooks using Trace-Command Trace-Command -PSHost -Name ClientTransport -Expression { Invoke-Command -ComputerName Server01 { 'test' } } ``` -------------------------------- ### Get Current Default Authentication Provider Source: https://context7.com/jborean93/pswsman/llms.txt Retrieves the current default authentication provider used by PSWSMan. This can be either 'System' (OS-provided) or 'Devolutions' (bundled sspi-rs). ```powershell # Get the current default authentication provider $provider = Get-PSWSManAuthProvider Write-Host "Current auth provider: $provider" ``` ```powershell # Check provider before establishing connections $currentProvider = Get-PSWSManAuthProvider if ($currentProvider -eq 'System') { Write-Host "Using system SSPI/GSSAPI for authentication" } else { Write-Host "Using Devolutions sspi-rs for authentication" } ``` ```powershell # Display provider info alongside connection test Enable-PSWSMan -Force $provider = Get-PSWSManAuthProvider Write-Host "Connecting with $provider provider..." Invoke-Command -ComputerName Server01 -ScriptBlock { hostname } ``` -------------------------------- ### Get Default Authentication Provider Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/Get-PSWSManAuthProvider.md Retrieves the currently configured default authentication provider for PSWSMan. This is useful for understanding which authentication method will be used by default for NTLM, Kerberos, Negotiate, or CredSSP authentication. ```powershell PS C:\> Get-PSWSManAuthProvider ``` -------------------------------- ### Connect using client certificate with separate key and cert files Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/New-PSWSManSessionOption.md Combines a certificate file and a separate private key file into an X509Certificate2 object for authentication. ```powershell PS C:\> $certPath = Resolve-Path ~/cert.pem PS C:\> $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($certPath) PS C:\> $keyContent = Get-Content -Path ~/cert.key -Raw # Example for RSA keys PS C:\> $key = [System.Security.Cryptography.RSA]::Create() PS C:\> $key.ImportFromEncryptedPem($keyContent, "KeyPassword") PS C:\> $cert = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::CopyWithPrivateKey($cert, $key) # Example for ECDSA keys PS C:\> $key = [System.Security.Cryptography.ECDsa]::Create() PS C:\> $key.ImportFromEncryptedPem($keyContent, "KeyPassword") PS C:\> $cert = [System.Security.Cryptography.X509Certificates.ECDsaCertificateExtensions]::CopyWithPrivateKey($cert, $key) PS C:\> $pso = New-PSWSManSessionOption -ClientCertificate $cert PS C:\> Invoke-Command -ComputerName host.domain.com -UseSSL -SessionOption $pso { 'hi' } ``` -------------------------------- ### Build and Test PSWSMan Source: https://github.com/jborean93/pswsman/blob/main/README.md Use the build script to compile the module or execute the test suite. ```powershell .\build.ps1 -Task Build ``` ```powershell .\build.ps1 -Task Test ``` -------------------------------- ### Connection Configuration Parameters Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/New-PSWSManSessionOption.md Parameters for configuring HTTPS, TLS, and Kerberos authentication settings for pswsman sessions. ```APIDOC ## Connection Configuration Parameters ### Parameters - **SkipCACheck** (SwitchParameter) - Optional - Specifies that the client does not validate that the server certificate is signed by a trusted CA. Mutually exclusive to -TlsOption. - **SkipCNCheck** (SwitchParameter) - Optional - Specifies that the certificate common name (CN) does not have to match the hostname. Mutually exclusive to -TlsOption. - **SPNHostName** (String) - Optional - Override the hostname portion used for the Service Principal Name (SPN) requested by Kerberos. - **SPNService** (String) - Optional - Override the service portion used for the Service Principal Name (SPN) requested by Kerberos. - **TlsOption** (SslClientAuthenticationOptions) - Optional - Set the TLS authentication options used on a HTTPS connection. Mutually exclusive to -SkipCACheck, -SkipCNCheck, and -ClientCertificate. - **UICulture** (CultureInfo) - Optional - Specifies the UI culture to use for the session. ``` -------------------------------- ### Connect to a session with custom options Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/New-PSWSManSessionOption.md Creates a custom SessionOption object configured for Kerberos authentication and applies it to a PSSession connection. ```powershell PS C:\> $pso = New-PSWSManSessionOption -AuthMethod Kerberos PS C:\> Enter-PSSession -ComputerName Server01 -SessionOption $pso ``` -------------------------------- ### PSWSMan Configuration Parameters Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/New-PSWSManSessionOption.md Overview of parameters used to configure authentication and connection behavior in PSWSMan. ```APIDOC ## PSWSMan Configuration Parameters ### -AuthMethod - **Type**: AuthenticationMethod - **Required**: False - **Description**: Selects authentication mechanisms (Default, Basic, Negotiate, NTLM, Kerberos, CredSSP). ### -AuthProvider - **Type**: AuthenticationProvider - **Required**: False - **Description**: Sets the authentication provider (Default, System, Devolutions) for NTLM, Kerberos, Negotiate, or CredSSP. ### -CancelTimeout - **Type**: Int32 - **Required**: False - **Description**: Sets the wait time in milliseconds for a cancel operation to finish. Default is 60000. ### -ClientCertificate - **Type**: X509Certificate - **Required**: False - **Description**: Specifies an X509Certificate object for TLS client authentication. Requires -UseSSL. ### -CredSSPAuthMethod - **Type**: AuthenticationMethod - **Required**: False - **Description**: Controls the sub-authentication protocol for CredSSP (Negotiate, NTLM, Kerberos). ### -CredSSPTlsOption - **Type**: SslClientAuthenticationOptions - **Required**: False - **Description**: Configures TLS options for the CredSSP connection, including server certificate validation and protocol selection. ``` -------------------------------- ### Set System as Default Provider Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/Set-PSWSManAuthProvider.md Use this command to set the default authentication provider to use the system's native libraries (SSPI on Windows, GSSAPI on Linux/macOS). ```powershell PS C:\> Set-PSWSManAuthProvider -AuthProvider System ``` -------------------------------- ### Set Default Authentication Provider to Devolutions Source: https://context7.com/jborean93/pswsman/llms.txt Sets the process-wide default authentication provider for PSWSMan to 'Devolutions'. This ensures consistent cross-platform authentication without requiring system GSSAPI configuration. Use -WhatIf or -Confirm for previewing or confirming the change. ```powershell # Set Devolutions as the default provider for consistent cross-platform auth Set-PSWSManAuthProvider -AuthProvider Devolutions ``` ```powershell # Verify the change Get-PSWSManAuthProvider ``` ```powershell # All subsequent connections will use Devolutions $cred = Get-Credential Invoke-Command -ComputerName Server01 -Credential $cred -ScriptBlock { "Connected using Devolutions provider" } ``` ```powershell # Revert to system provider Set-PSWSManAuthProvider -AuthProvider System ``` ```powershell # Use -WhatIf to preview changes Set-PSWSManAuthProvider -AuthProvider Devolutions -WhatIf ``` ```powershell # Use -Confirm to prompt before changing Set-PSWSManAuthProvider -AuthProvider Devolutions -Confirm ``` ```powershell # Override global setting for specific connection Set-PSWSManAuthProvider -AuthProvider Devolutions # Global default $pso = New-PSWSManSessionOption -AuthProvider System # Override for this connection Invoke-Command -ComputerName Server01 -SessionOption $pso -ScriptBlock { hostname } ``` -------------------------------- ### Create Callback to Accept All Certificates Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/New-PSWSManCertValidationCallback.md Use this to create a WSMan session option that accepts any certificate, effectively disabling certificate verification. The scriptblock simply returns $true. ```powershell PS C:\> $delegate = New-PSWSManCertValidationCallback -ScriptBlock { $true } PS C:\> $tlsOptions = [System.Net.Security.SslClientAuthenticationOptions]@{ RemoteCertificateValidationCallback = $delegate TargetHost = 'host' } PS C:\> $pso = New-PSWSManSessionOption -TlsOption $tlsOptions ``` -------------------------------- ### Authenticate with Separate PEM and Key Files Source: https://context7.com/jborean93/pswsman/llms.txt Combines a PEM certificate and a private key into an X509Certificate2 object for authentication on Linux/macOS. ```PowerShell $certPath = Resolve-Path ~/cert.pem $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($certPath) $keyContent = Get-Content -Path ~/cert.key -Raw $key = [System.Security.Cryptography.RSA]::Create() $key.ImportFromPem($keyContent) # Use ImportFromEncryptedPem for password-protected keys $cert = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::CopyWithPrivateKey($cert, $key) $pso = New-PSWSManSessionOption -ClientCertificate $cert ``` -------------------------------- ### Prepare for Exchange Online Modern Authentication Testing Source: https://github.com/jborean93/pswsman/blob/main/tests/integration/README.md Navigate to the integration tests directory and run a Docker container to set up a principal for Exchange Online modern authentication testing. This container provides access to Azure Graph in PowerShell. ```powershell # Make sure we are in the `tests/integration` folder cd tests/integration # Run it in this container to access Azure Graph in PowerSHellazure-cli docker run -it -v "$( pwd ):/app:Z" -w /app mcr.microsoft.com/microsoftgraph/powershell:latest ``` -------------------------------- ### Set Devolutions as Default Provider Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/Set-PSWSManAuthProvider.md Use this command to set the default authentication provider to use the bundled DevolutionsSspi library, which provides a standalone implementation of Kerberos and NTLM. ```powershell PS C:\> Set-PSWSManAuthProvider -AuthProvider Devolutions ``` -------------------------------- ### Enable Basic Authentication on WSMan Service Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/about_PSWSManAuthentication.md Run this command on the server to enable Basic authentication. Ensure it is only used over HTTPS. ```powershell Set-Item -Path WSMan:\localhost\Service\Auth\Basic -Value True ``` -------------------------------- ### Load CA Certificate on macOS Source: https://github.com/jborean93/pswsman/blob/main/tests/integration/README.md Load the CA certificate generated by wsman-environment into the system trust store on macOS to enable secure connections. Ensure the certificate is at ~/ca.pem. ```bash sudo security authorizationdb read com.apple.trust-settings.admin > rights sudo security authorizationdb write com.apple.trust-settings.admin allow sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ~/ca.pem sudo security authorizationdb write com.apple.trust-settings.admin < rights ``` -------------------------------- ### New-PSWSManSessionOption Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/New-PSWSManSessionOption.md Creates an object that specifies custom connection options for a WSMan PSSession, which can be used with cmdlets like New-PSSession or Enter-PSSession. ```APIDOC ## New-PSWSManSessionOption ### Description Creates an object that contains advanced options for a user-managed session (PSSession). This object can be passed to the -SessionOption parameter of cmdlets that create a PSSession. ### Parameters #### Optional Parameters - **MaximumRedirection** (Int32) - Optional - Maximum number of redirections. - **NoMachineProfile** (Switch) - Optional - Do not load the user profile. - **Culture** (CultureInfo) - Optional - Culture settings for the session. - **UICulture** (CultureInfo) - Optional - UI culture settings for the session. - **MaximumReceivedDataSizePerCommand** (Int32) - Optional - Max data size per command. - **MaximumReceivedObjectSize** (Int32) - Optional - Max object size. - **MaxConnectionRetryCount** (Int32) - Optional - Number of connection retries. - **ApplicationArguments** (PSPrimitiveDictionary) - Optional - Arguments for the application. - **OpenTimeout** (Int32) - Optional - Timeout for opening the session. - **CancelTimeout** (Int32) - Optional - Timeout for cancellation. - **SkipCACheck** (Switch) - Optional - Skip CA certificate check. - **SkipCNCheck** (Switch) - Optional - Skip CN certificate check. - **ClientCertificate** (X509Certificate) - Optional - Client certificate for authentication. - **OperationTimeout** (Int32) - Optional - Timeout for operations. - **NoEncryption** (Switch) - Optional - Disable encryption. - **SPNService** (String) - Optional - SPN service name. - **SPNHostName** (String) - Optional - SPN host name. - **AuthMethod** (AuthenticationMethod) - Optional - Authentication method. - **AuthProvider** (AuthenticationProvider) - Optional - Authentication provider. - **RequestKerberosDelegate** (Switch) - Optional - Request Kerberos delegation. - **CredSSPAuthMethod** (AuthenticationMethod) - Optional - CredSSP authentication method. - **CredSSPTlsOption** (SslClientAuthenticationOptions) - Optional - CredSSP TLS options. - **TlsOption** (SslClientAuthenticationOptions) - Optional - TLS options for the connection. ### Request Example $pso = New-PSWSManSessionOption -AuthMethod Kerberos Enter-PSSession -ComputerName Server01 -SessionOption $pso ``` -------------------------------- ### Session Configuration Parameters Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/New-PSWSManSessionOption.md A collection of parameters used to define the behavior and constraints of a WinRM session. ```APIDOC ## Session Configuration Parameters ### Description These parameters are used to configure the behavior, security, and resource limits of a WinRM session created via pswsman. ### Parameters - **-Culture** (CultureInfo) - Optional - Specifies the culture to use for the session (e.g., 'en-US'). - **-MaxConnectionRetryCount** (Int32) - Optional - Number of times to retry connection on failure. Default is 5. - **-MaximumReceivedDataSizePerCommand** (Int32) - Optional - Maximum bytes received from the remote computer in a single command. - **-MaximumReceivedObjectSize** (Int32) - Optional - Maximum size of an object in bytes. Default is 200MiB. - **-MaximumRedirection** (Int32) - Optional - Number of times to follow URI redirection. Default is 5. - **-NoEncryption** (SwitchParameter) - Optional - Disables data encryption for NTLM, Kerberos, and CredSSP over HTTP. - **-NoMachineProfile** (SwitchParameter) - Optional - Prevents loading the user's Windows user profile. - **-OpenTimeout** (Int32) - Optional - Time in milliseconds to wait for session connection. Default is 180000. - **-OperationTimeout** (Int32) - Optional - Time in milliseconds for the server to process an operation. Default is 180000. - **-RequestKerberosDelegate** (SwitchParameter) - Optional - Requests delegation-enabled tickets when using Kerberos authentication. ``` -------------------------------- ### Configure PSWSMan Session Options Source: https://context7.com/jborean93/pswsman/llms.txt Creates advanced session configuration objects for authentication, TLS, and delegation. These options are passed to standard remoting cmdlets via the -SessionOption parameter. ```powershell # Create session option with specific authentication method $pso = New-PSWSManSessionOption -AuthMethod Kerberos Enter-PSSession -ComputerName Server01 -SessionOption $pso # Connect to HTTPS endpoint while skipping certificate checks $pso = New-PSWSManSessionOption -SkipCACheck -SkipCNCheck Invoke-Command -ComputerName 192.168.1.2 -UseSSL -SessionOption $pso -ScriptBlock { Get-Service | Select-Object -First 5 } # Use NTLM authentication with Devolutions provider (cross-platform) $pso = New-PSWSManSessionOption -AuthMethod NTLM -AuthProvider Devolutions $cred = Get-Credential Invoke-Command -ComputerName Server01 -Credential $cred -SessionOption $pso -ScriptBlock { whoami } # Request Kerberos delegation for double-hop scenarios $pso = New-PSWSManSessionOption -RequestKerberosDelegate Invoke-Command -ComputerName Server01 -SessionOption $pso -ScriptBlock { # Can now access downstream servers Get-Content -Path "\\Server02\share\file.txt" } # Custom SPN for Kerberos authentication $pso = New-PSWSManSessionOption -SPNService http -SPNHostName myserver.domain.com Invoke-Command -ComputerName myserver -SessionOption $pso -ScriptBlock { hostname } # Configure custom TLS options with certificate revocation checking $tlsOptions = [System.Net.Security.SslClientAuthenticationOptions]@{ TargetHost = "Server03" CertificateRevocationCheckMode = [System.Security.Cryptography.X509Certificates.X509RevocationMode]::Online } $pso = New-PSWSManSessionOption -TlsOption $tlsOptions Invoke-Command -ComputerName Server03 -UseSSL -SessionOption $pso -ScriptBlock { $env:COMPUTERNAME } # Client certificate authentication (requires HTTPS) $cert = Get-PfxCertificate -FilePath ~/client_auth.pfx $pso = New-PSWSManSessionOption -ClientCertificate $cert Invoke-Command -ComputerName host.domain.com -UseSSL -SessionOption $pso -ScriptBlock { "Authenticated with certificate" } # Pass application arguments to remote session $appArgs = @{ Environment = "Production"; DebugMode = $false } $pso = New-PSWSManSessionOption -ApplicationArguments $appArgs Invoke-Command -ComputerName Server01 -SessionOption $pso -ScriptBlock { if ($PSSenderInfo.ApplicationArguments.Environment -eq "Production") { "Running in production mode" } } ``` -------------------------------- ### Generate Test Settings File Source: https://github.com/jborean93/pswsman/blob/main/tests/integration/README.md Generate the test.settings.json file required by the test suite by running a PowerShell script with the path to the wsman-environment directory. ```powershell pwsh -File tests/integration/generate_settings.ps1 ~/wsman-environment ``` -------------------------------- ### Connect using client certificate authentication Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/New-PSWSManSessionOption.md Authenticates to a remote endpoint using a client certificate loaded from a PFX file. ```powershell PS C:\> $cert = Get-PfxCertificate -FilePath ~/client.pfx PS C:\> $pso = New-PSWSManSessionOption -ClientCertificate $cert PS C:\> Invoke-Command -ComputerName host.domain.com -UseSSL -SessionOption $pso { 'hi' } ``` -------------------------------- ### Set Devolutions SSPI as Default Provider Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/about_PSWSManAuthentication.md Use this command to set the Devolutions SSPI as the default authentication provider for all PSWSMan processes. This is useful for ensuring consistent cross-platform authentication behavior. ```powershell Set-PSWSManAuthProvider -AuthProvider Devolutions ``` -------------------------------- ### Authenticate with PFX Certificate Source: https://context7.com/jborean93/pswsman/llms.txt Uses a PFX file to create a session option for secure remote execution. ```PowerShell $clientCert = Get-PfxCertificate -FilePath "~/client_auth.pfx" $pso = New-PSWSManSessionOption -ClientCertificate $clientCert Invoke-Command -ComputerName host.domain.com -UseSSL -SessionOption $pso -ScriptBlock { "Authenticated via client certificate" } ``` -------------------------------- ### Configure Microsoft Graph and Exchange Permissions Source: https://github.com/jborean93/pswsman/blob/main/tests/integration/README.md Connects to Microsoft Graph, creates an application with required Exchange permissions, and assigns the Exchange Administrator role to the service principal. ```powershell $connectParams = @{ ContextScope = 'Process' Scopes = @( 'Application.ReadWrite.All' 'AppRoleAssignment.ReadWrite.All' 'RoleManagement.ReadWrite.Directory' ) UseDeviceAuthentication = $true } Connect-MgGraph @connectParams $exchangeManageAsAppId = "dc50a0fb-09a3-484d-be87-e023b12c6440" $exoId = '00000002-0000-0ff1-ce00-000000000000' $exoResourceId = (Get-MgServicePrincipal -Filter "AppId eq '$exoId'").Id $newAppParams = @{ DisplayName = 'PSWSManTest' RequiredResourceAccess = @( @{ ResourceAppId = $exoId ResourceAccess = @( @{ Id = $exchangeManageAsAppId Type = 'Role' } ) }, @{ ResourceAppId = '00000003-0000-0000-c000-000000000000' ResourceAccess = @( @{ Id = 'e1fe6dd8-ba31-4d61-89e7-88639da4683d' Type = 'Scope' } ) } ) KeyCredentials = @( @{ Type = 'AsymmetricX509Cert' Usage = 'Verify' Key = $cert.RawData } ) } $azApp = New-MgApplication @newAppParams $azSP = New-MgServicePrincipal -BodyParameter @{AppId = $azApp.AppId} $grantParams = @{ ServicePrincipalId = $azSP.Id PrincipalId = $azSP.Id AppRoleId = $exchangeManageAsAppId ResourceId = $exoResourceId } $null = New-MgServicePrincipalAppRoleAssignment @grantParams $clientSecret = Add-MgApplicationPassword -ApplicationId $azApp.Id -PasswordCredential @{ DisplayName = 'Test Secret' EndDateTime = (Get-Date).AddDays(1) } $exchangeRole = Get-MgDirectoryRole -Filter "displayName eq 'Exchange Administrator'" $roleAssignmentParams = @{ # v1.0 doesn't return service principals # https://github.com/microsoftgraph/msgraph-sdk-powershell/issues/880 Uri = "beta/directoryRoles/$($exchangeRole.Id)/members" Method = 'GET' } $roleAssignment = (Invoke-MgGraphRequest @roleAssignmentParams).value | Where-Object { $_.id -eq $azSP.Id } | Select-Object -First 1 if (-not $roleAssignment) { New-MgDirectoryRoleMemberByRef -DirectoryRoleId $exchangeRole.Id -BodyParameter @{ "@odata.id" = "https://graph.microsoft.com/v1.0/directoryObjects/$($azSP.Id)" } } @{ tenant_id = (Get-MgContext).TenantId organization = (Get-MgDomain).Id app_id = $azApp.AppId client_secret = $clientSecret.SecretText cert_password = $certPassword } | ConvertTo-Json | Set-Content -Path exchange.json Disconnect-MgGraph ``` -------------------------------- ### Generate Self-Signed Certificate and PFX Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/about_PSWSManAuthentication.md Generates a self-signed certificate for client authentication, exports it as a PFX file, and then removes it from the user's certificate store. This process is useful for setting up client authentication without a dedicated Certificate Authority. ```powershell $selfSignedParams = @{ Subject = "CN=$($credential.UserName)" KeyUsage = 'DigitalSignature', 'KeyEncipherment' KeyAlgorithm = 'RSA' KeyLength = 2048 TextExtension = @("2.5.29.37={text}1.3.6.1.5.5.7.3.2","2.5.29.17={text}upn=$($credential.UserName)@localhost") Type = 'Custom' CertStoreLocation = "Cert:\CurrentUser\My" } $cert = New-SelfSignedCertificate @selfSignedParams # Create a PFX for the client to use. $certPath = Join-Path $pwd "client_auth.pfx" $certBytes = $cert.Export("Pfx") # Use this to export and protect with a password # $certBytes = $cert.Export("Pfx", $password) [System.IO.File]::WriteAllBytes($certPath, $certBytes) # Remove it from the cert store once exported Remove-Item -Path "Cert:\CurrentUser\My\$($cert.Thumbprint)" -Force # Reload the certificate but with no key associated with it # before loading it into the relevant stores. $certNoKey = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($cert.RawData) ``` -------------------------------- ### Map Certificate to User Credentials Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/about_PSWSManAuthentication.md Maps the generated certificate to the user's credentials for WSMan client authentication. This step associates the certificate with the specific user account that will be used for connections. ```powershell # Get the thumbprint of the chain root. For self signed certs this is # the cert itself, for a signed cert this is the root issuer. $certChain = [Security.Cryptography.X509Certificates.X509Chain]::new() [void]$certChain.Build($certNokey) $caThumbprint = $certChain.ChainElements.Certificate[-1].Thumbprint # Map the certificate to the user's credentials $credBinding = @{ Path = 'WSMan:\localhost\ClientCertificate' Subject = $credential.UserName URI = "*" Issuer = $caThumbprint Credential = $credential Force = $true } New-Item @credBinding ``` -------------------------------- ### Generate Certificate for Exchange Authentication Source: https://github.com/jborean93/pswsman/blob/main/tests/integration/README.md Generate a self-signed certificate and a PKCS12 file for Exchange authentication using OpenSSL. The certificate is valid for 1 day and the private key is removed after creation. ```powershell $certPassword = [Guid]::NewGuid().ToString() openssl @( 'req', '-x509' '-newkey', 'rsa:2048' '-keyout', 'exchange-key.pem' '-passout', "pass:$certPassword" '-out', 'exchange-cert.pem' '-days', '1' '-subj', '/CN=ExchangeTest' ) openssl @( 'pkcs12', '-export' '-out', 'exchange-cert.pfx' '-passout', "pass:$certPassword" '-inkey', 'exchange-key.pem' '-passin', "pass:$certPassword" '-in', 'exchange-cert.pem' ) chmod 644 exchange-cert.pfx $cert = Get-PfxCertificate -FilePath exchange-cert.pem Remove-Item -Path exchange-key.pem Remove-Item -Path exchange-cert.pem ``` -------------------------------- ### Send arguments to remote session Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/New-PSWSManSessionOption.md Creates a hashtable with primitive values to pass as application arguments, accessible via $PSSenderInfo.ApplicationArguments in the remote session. ```powershell PS C:\> $info = @{Foo = "Bar"} PS C:\> $pso = New-PSWSManSessionOption -ApplicationArguments $info PS C:\> Invoke-Command -ComputerName Server02 -SessionOption $pso -ScriptBlock { >> if ($PSSenderInfo.ApplicationArguments.Foo -eq "Bar") { >> "Hello Bar" >> } >> else { >> "Hello Unknown" >> } >> } ``` -------------------------------- ### Set-PSWSManAuthProvider Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/Set-PSWSManAuthProvider.md Configures the default authentication provider for PSWSMan. ```APIDOC ## Set-PSWSManAuthProvider ### Description Sets the default authentication provider used by PSWSMan. This provider is utilized when NTLM, Kerberos, Negotiate, or CredSSP authentication is selected for a PSSession and no explicit provider is specified for the connection. ### Method Cmdlet ### Endpoint N/A (Local cmdlet) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters #### -AuthProvider **Type**: AuthenticationProvider **Description**: The authentication provider to set as the PSWSMan default. Must be either `System` or `Devolutions`. Using `Default` will result in an error. **Accepted values**: Default, System, Devolutions **Required**: True **Position**: 0 #### -Confirm **Type**: SwitchParameter **Description**: Prompts you for confirmation before running the cmdlet. **Required**: False **Position**: Named #### -WhatIf **Type**: SwitchParameter **Description**: Shows what would happen if the cmdlet runs. The cmdlet is not run. **Required**: False **Position**: Named ### Request Example ```powershell Set-PSWSManAuthProvider -AuthProvider System ``` ### Response #### Success Response (200) None (This cmdlet modifies configuration and does not return output). #### Response Example None ``` -------------------------------- ### Generate self-signed certificate for authentication Source: https://context7.com/jborean93/pswsman/llms.txt Create and export a self-signed certificate for use with certificate-based authentication. ```powershell # Certificate authentication setup on server $credential = Get-Credential -UserName "localuser" $selfSignedParams = @{ Subject = "CN=$($credential.UserName)" KeyUsage = 'DigitalSignature', 'KeyEncipherment' KeyAlgorithm = 'RSA' KeyLength = 2048 TextExtension = @( "2.5.29.37={text}1.3.6.1.5.5.7.3.2", "2.5.29.17={text}upn=$($credential.UserName)@localhost" ) Type = 'Custom' CertStoreLocation = "Cert:\CurrentUser\My" } $cert = New-SelfSignedCertificate @selfSignedParams # Export and configure the certificate (run on server) $certPath = Join-Path $pwd "client_auth.pfx" $certBytes = $cert.Export("Pfx") [System.IO.File]::WriteAllBytes($certPath, $certBytes) ``` -------------------------------- ### Set-PSWSManAuthProvider Source: https://context7.com/jborean93/pswsman/llms.txt Sets the process-wide default authentication provider for PSWSMan. This affects all subsequent NTLM, Kerberos, Negotiate, or CredSSP authentication unless overridden by the -AuthProvider parameter in New-PSWSManSessionOption. The Devolutions provider offers consistent cross-platform behavior without requiring system GSSAPI configuration. ```APIDOC ## Set-PSWSManAuthProvider ### Description Sets the process-wide default authentication provider for PSWSMan. This affects all subsequent NTLM, Kerberos, Negotiate, or CredSSP authentication unless overridden by the -AuthProvider parameter in New-PSWSManSessionOption. The Devolutions provider offers consistent cross-platform behavior without requiring system GSSAPI configuration. ### Method PUT ### Endpoint /pswsman/auth/provider ### Parameters #### Query Parameters - **AuthProvider** (string) - Required - The authentication provider to set. Accepts 'System' or 'Devolutions'. - **WhatIf** (boolean) - Optional - Shows what would happen if the command runs without actually running it. - **Confirm** (boolean) - Optional - Prompts for confirmation before executing the command. ### Request Example ```json { "AuthProvider": "Devolutions" } ``` ### Response #### Success Response (200) - **message** (string) - Confirmation message indicating the provider has been set. #### Response Example ``` Provider set to Devolutions ``` ``` -------------------------------- ### Use Devolutions SSPI for a Specific Session Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/about_PSWSManAuthentication.md This command allows you to specify the Devolutions SSPI provider for a particular PSWSMan session. This setting takes precedence over the global process-wide default. ```powershell New-PSWSManSessionOption -AuthProvider Devolutions ``` -------------------------------- ### Create a default session option Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/New-PSWSManSessionOption.md Generates a SessionOption object using default values. ```powershell PS C:\> New-PSWSManSessionOption ``` -------------------------------- ### Implement custom certificate validation callbacks Source: https://context7.com/jborean93/pswsman/llms.txt Use New-PSWSManCertValidationCallback to define custom logic for validating server certificates, such as checking against a deny list or monitoring expiration dates. ```powershell $denyList = @('CN=untrusted-host', 'CN=compromised-server') $delegate = New-PSWSManCertValidationCallback -ScriptBlock { param ( [System.Net.Security.SslStream]$Sender, [System.Security.Cryptography.X509Certificates.X509Certificate]$Certificate, [System.Security.Cryptography.X509Certificates.X509Chain]$Chain, [System.Net.Security.SslPolicyErrors]$PolicyErrors ) # Log certificate details to host Write-Host "Certificate Subject: $($Certificate.Subject)" Write-Host "Certificate Issuer: $($Certificate.Issuer)" Write-Host "Policy Errors: $PolicyErrors" # Check against deny list $denyHosts = $using:denyList if ($Certificate.Subject -in $denyHosts) { Write-Host "REJECTED: Certificate is in deny list" -ForegroundColor Red return $false } # Accept if no policy errors, or only name mismatch (we verified subject) $PolicyErrors -eq [System.Net.Security.SslPolicyErrors]::None } $tlsOptions = [System.Net.Security.SslClientAuthenticationOptions]@{ RemoteCertificateValidationCallback = $delegate TargetHost = 'production-server' } $pso = New-PSWSManSessionOption -TlsOption $tlsOptions Invoke-Command -ComputerName production-server -UseSSL -SessionOption $pso -ScriptBlock { "Connection established with validated certificate" } ``` ```powershell # Validate certificate expiration $delegate = New-PSWSManCertValidationCallback -ScriptBlock { param ($Sender, $Certificate, $Chain, $PolicyErrors) $cert2 = [System.Security.Cryptography.X509Certificates.X509Certificate2]$Certificate $daysUntilExpiry = ($cert2.NotAfter - (Get-Date)).Days if ($daysUntilExpiry -lt 0) { Write-Host "Certificate has expired!" -ForegroundColor Red return $false } elseif ($daysUntilExpiry -lt 30) { Write-Host "Warning: Certificate expires in $daysUntilExpiry days" -ForegroundColor Yellow } $true } ``` -------------------------------- ### Enable Certificate Authentication on WSMan Service Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/about_PSWSManAuthentication.md Enables certificate authentication on the local WSMan service. This setting allows the WSMan service to accept and process client certificates for authentication. ```powershell # Enable Certificate authentication on the WSMan service Set-Item -Path WSMan:\localhost\Service\Auth\Certificate -Value True ``` -------------------------------- ### Configure TLS for WSMan Session Options Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/about_PSWSManAuthentication.md Configures TLS options for a WSMan session, specifically setting the protocol to TLS 1.2 for Linux environments running older PowerShell versions to ensure compatibility. This is crucial for environments where TLS 1.3 might not be fully supported with client certificate authentication. ```powershell $tlsOption = [System.Net.Security.SslClientAuthenticationOptions]@{ TargetHost = 'TargetHost' ClientCertificates = [System.Security.Cryptography.X509Certificates.X509CertificateCollection]::new( @($ClientCertificate)) } if ($IsLinux -and [Environment]::Version -lt [Version]'7.0') { $tlsOption.EnabledSslProtocols = [System.Security.Authentication.SslProtocols]::Tls12 } $pso = New-PSWSManSessionOption -TlsOption $tlsOption Invoke-Command -ComputerName host -SessionOption $pso -ScriptBlock { ... } ``` -------------------------------- ### Create Callback for TLS Certificate Thumbprint Validation Source: https://context7.com/jborean93/pswsman/llms.txt Creates a delegate for custom TLS certificate validation that checks if the certificate's thumbprint matches a specified value. The scriptblock receives sender, certificate, chain, and policy errors as parameters. ```powershell # Create a callback that validates certificate thumbprint $expectedThumbprint = "1234567890ABCDEF1234567890ABCDEF12345678" $delegate = New-PSWSManCertValidationCallback -ScriptBlock { param ($Sender, $Certificate, $Chain, $PolicyErrors) $Certificate.GetCertHashString() -eq $using:expectedThumbprint } $tlsOptions = [System.Net.Security.SslClientAuthenticationOptions]@{ RemoteCertificateValidationCallback = $delegate TargetHost = 'securehost' } $pso = New-PSWSManSessionOption -TlsOption $tlsOptions Invoke-Command -ComputerName securehost -UseSSL -SessionOption $pso -ScriptBlock { "Verified!" } ``` -------------------------------- ### Get-PSWSManAuthProvider Source: https://github.com/jborean93/pswsman/blob/main/docs/en-US/Get-PSWSManAuthProvider.md Retrieves the default authentication provider used by PSWSMan for NTLM, Kerberos, Negotiate, or CredSSP authentication when no explicit provider is specified. ```APIDOC ## GET /api/pswsman/auth/provider ### Description Retrieves the default authentication provider used by PSWSMan. This provider is utilized when NTLM, Kerberos, Negotiate, or CredSSP authentication is selected for a PSSession and no explicit provider is specified for the connection. ### Method GET ### Endpoint /api/pswsman/auth/provider ### Parameters #### Query Parameters - **CommonParameters** (object) - Optional - Supports common parameters like -Debug, -ErrorAction, etc. ### Request Example ```json { "example": "GET /api/pswsman/auth/provider" } ``` ### Response #### Success Response (200) - **authenticationProvider** (string) - The current default authentication provider, either `System` or `Devolutions`. #### Response Example ```json { "authenticationProvider": "System" } ``` ```