Python library for Windows Remote Management (WinRM) service enabling remote command execution and PowerShell scripts on Windows machines.
—
Support for multiple authentication methods and secure communication protocols with message-level encryption capabilities. PyWinRM provides comprehensive security features for remote Windows management across different network environments and security requirements.
PyWinRM supports multiple authentication mechanisms for different deployment scenarios and security requirements.
# Supported authentication types
FEATURE_SUPPORTED_AUTHTYPES = [
"basic", "certificate", "ntlm", "kerberos",
"plaintext", "ssl", "credssp"
]
# Feature flags for client capability detection
FEATURE_READ_TIMEOUT = True
FEATURE_OPERATION_TIMEOUT = True
FEATURE_PROXY_SUPPORT = TrueConfigure transport-level security including certificates, validation, and encryption options.
class Transport:
def __init__(
self,
endpoint: str,
username: str | None = None,
password: str | None = None,
realm: None = None,
service: str = "HTTP",
keytab: None = None,
ca_trust_path: Literal["legacy_requests"] | str = "legacy_requests",
cert_pem: str | None = None,
cert_key_pem: str | None = None,
read_timeout_sec: int | None = None,
server_cert_validation: Literal["validate", "ignore"] = "validate",
kerberos_delegation: bool | str = False,
kerberos_hostname_override: str | None = None,
auth_method: Literal["auto", "basic", "certificate", "ntlm", "kerberos", "credssp", "plaintext", "ssl"] = "auto",
message_encryption: Literal["auto", "always", "never"] = "auto",
credssp_disable_tlsv1_2: bool = False,
credssp_auth_mechanism: Literal["auto", "ntlm", "kerberos"] = "auto",
credssp_minimum_version: int = 2,
send_cbt: bool = True,
proxy: Literal["legacy_requests"] | str | None = "legacy_requests"
):
"""
Configure transport-level security and authentication.
Parameters:
- endpoint: WinRM webservice endpoint URL
- username: authentication username
- password: authentication password
- realm: realm parameter (currently unused)
- service: service name for Kerberos authentication (default: "HTTP")
- keytab: keytab parameter (currently unused)
- ca_trust_path: CA certificate trust path or "legacy_requests" for env vars
- cert_pem: client certificate file path (PEM format)
- cert_key_pem: client certificate private key file path (PEM format)
- read_timeout_sec: HTTP connection/read timeout in seconds
- server_cert_validation: certificate validation mode ("validate" or "ignore")
- kerberos_delegation: enable Kerberos delegation for multi-hop scenarios
- kerberos_hostname_override: override hostname for Kerberos SPN
- auth_method: authentication method to use
- message_encryption: message-level encryption policy
- credssp_disable_tlsv1_2: disable TLS 1.2 for CredSSP compatibility
- credssp_auth_mechanism: CredSSP authentication mechanism
- credssp_minimum_version: minimum CredSSP version
- send_cbt: send Channel Binding Tokens for enhanced security
- proxy: proxy configuration
"""
def build_session(self) -> requests.Session:
"""
Create and configure a requests.Session object.
Sets up proxy configuration, SSL verification, authentication,
and message encryption if required.
Returns:
Configured requests.Session object ready for WinRM communication
"""
def setup_encryption(self, session: requests.Session) -> None:
"""
Set up message encryption for the transport.
Sends an initial blank message to initialize security context
and creates an Encryption instance for the session.
Parameters:
- session: requests.Session to configure encryption for
"""
def close_session(self) -> None:
"""
Close the current session if it exists.
Sets the session attribute to None and cleans up resources.
"""
def send_message(self, message: str | bytes) -> bytes:
"""
Send WinRM message and return response.
Handles both encrypted and unencrypted messages.
Converts string messages to bytes automatically.
Parameters:
- message: WinRM message as string or bytes
Returns:
Response content as bytes
"""Message-level encryption for secure communication over potentially untrusted networks.
class Encryption:
"""Message-level encryption for WinRM communication."""
# Constants
SIXTEN_KB = 16384 # 16KB chunk size for large message encryption
MIME_BOUNDARY = b"--Encrypted Boundary" # MIME boundary for encrypted messages
def __init__(self, session: requests.Session, protocol: str):
"""
Initialize message encryption for supported protocols.
Supported protocols:
- "ntlm": NTLM with SPNEGO session encryption
- "kerberos": Kerberos with SPNEGO session encryption
- "credssp": CredSSP with session encryption
Parameters:
- session: HTTP session with established authentication context
- protocol: encryption protocol type
Raises:
- WinRMError: if protocol is not supported for encryption
"""
def prepare_encrypted_request(
self,
session: requests.Session,
endpoint: str | bytes,
message: bytes
) -> requests.PreparedRequest:
"""
Prepare HTTP request with encrypted message payload.
Handles both single-part and multi-part encryption based on message size.
For CredSSP messages larger than 16KB, uses multipart/x-multi-encrypted.
Parameters:
- session: requests.Session to prepare request with
- endpoint: target endpoint URL
- message: unencrypted message bytes to send
Returns:
Prepared request with encrypted body and appropriate headers
"""
def parse_encrypted_response(self, response: requests.Response) -> bytes:
"""
Parse and decrypt encrypted response from WinRM service.
Automatically detects if response is encrypted based on Content-Type
header and decrypts accordingly.
Parameters:
- response: HTTP response from WinRM service
Returns:
Decrypted response message bytes
"""Simple username/password authentication over HTTP or HTTPS.
import winrm
# HTTP Basic (not recommended for production)
s = winrm.Session(
'http://windows-host:5985/wsman',
auth=('username', 'password'),
transport='basic'
)
# HTTPS Basic (recommended)
s = winrm.Session(
'https://windows-host:5986/wsman',
auth=('username', 'password'),
transport='ssl'
)Windows NTLM authentication with optional message encryption.
# NTLM with message encryption (recommended)
s = winrm.Session(
'windows-host.domain.com',
auth=('domain\\username', 'password'),
transport='ntlm',
message_encryption='always'
)
# NTLM without encryption (faster, less secure)
s = winrm.Session(
'windows-host.domain.com',
auth=('domain\\username', 'password'),
transport='ntlm',
message_encryption='never'
)Domain-based Kerberos authentication with delegation support.
# Standard Kerberos authentication
s = winrm.Session(
'windows-host.domain.com',
auth=('user@DOMAIN.COM', 'password'),
transport='kerberos'
)
# Kerberos with delegation (for multi-hop scenarios)
s = winrm.Session(
'windows-host.domain.com',
auth=('user@DOMAIN.COM', 'password'),
transport='kerberos',
kerberos_delegation=True,
kerberos_hostname_override='custom-host.domain.com'
)CredSSP with credential delegation for accessing network resources.
# CredSSP authentication (requires pywinrm[credssp])
s = winrm.Session(
'windows-host.domain.com',
auth=('domain\\username', 'password'),
transport='credssp',
message_encryption='always'
)
# CredSSP with TLS compatibility options
s = winrm.Session(
'windows-host.domain.com',
auth=('domain\\username', 'password'),
transport='credssp',
credssp_disable_tlsv1_2=True # For older systems
)Client certificate-based authentication for PKI environments.
# Certificate authentication
s = winrm.Session(
'https://windows-host:5986/wsman',
auth=('username', 'password'), # May still be required
transport='certificate',
cert_pem='/path/to/client.crt',
cert_key_pem='/path/to/client.key',
server_cert_validation='validate',
ca_trust_path='/path/to/ca-bundle.crt'
)
# Certificate auth with custom CA trust
s = winrm.Session(
'https://windows-host:5986/wsman',
auth=('username', 'password'),
transport='certificate',
cert_pem='/path/to/client.pem',
cert_key_pem='/path/to/client.key',
ca_trust_path='/etc/ssl/certs/custom-ca.pem'
)# Strict certificate validation (production)
s = winrm.Session(
'https://windows-host.domain.com:5986/wsman',
auth=('user', 'password'),
transport='ssl',
server_cert_validation='validate',
ca_trust_path='/etc/ssl/certs/ca-certificates.crt'
)# Disabled certificate validation (development only)
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
s = winrm.Session(
'https://windows-host:5986/wsman',
auth=('user', 'password'),
transport='ssl',
server_cert_validation='ignore' # NOT for production
)# Explicit proxy configuration
s = winrm.Session(
'windows-host',
auth=('user', 'password'),
proxy='http://proxy.company.com:8080'
)
# Proxy with authentication
s = winrm.Session(
'windows-host',
auth=('user', 'password'),
proxy='http://proxyuser:proxypass@proxy.company.com:8080'
)
# Disable proxy completely
s = winrm.Session(
'windows-host',
auth=('user', 'password'),
proxy=None
)
# Use environment variables (default)
s = winrm.Session(
'windows-host',
auth=('user', 'password'),
proxy='legacy_requests' # Uses HTTP_PROXY, HTTPS_PROXY env vars
)import winrm
import os
def create_secure_session(hostname, username, password):
"""Create WinRM session with security best practices."""
# Use HTTPS transport with NTLM
session = winrm.Session(
f'https://{hostname}:5986/wsman',
auth=(username, password),
transport='ntlm',
# Security settings
message_encryption='always',
server_cert_validation='validate',
ca_trust_path='/etc/ssl/certs/ca-certificates.crt',
send_cbt=True,
# Timeout settings
read_timeout_sec=60,
operation_timeout_sec=30
)
return session
# Usage with environment variables for credentials
hostname = os.environ['WINRM_HOST']
username = os.environ['WINRM_USERNAME']
password = os.environ['WINRM_PASSWORD']
s = create_secure_session(hostname, username, password)def select_auth_method(hostname, username, password, domain=None):
"""Select appropriate authentication method based on environment."""
# Domain environment - prefer Kerberos
if domain and '@' in username:
return winrm.Session(
hostname,
auth=(username, password),
transport='kerberos',
message_encryption='auto'
)
# Domain environment - NTLM fallback
elif domain:
return winrm.Session(
hostname,
auth=(f'{domain}\\{username}', password),
transport='ntlm',
message_encryption='always'
)
# Local account - SSL Basic
else:
return winrm.Session(
f'https://{hostname}:5986/wsman',
auth=(username, password),
transport='ssl',
server_cert_validation='validate'
)
# Usage
s = select_auth_method('windows-host.domain.com', 'user', 'password', 'DOMAIN')ssl transport) or message encryption (ntlm, kerberos, credssp) in productionInstall with Tessl CLI
npx tessl i tessl/pypi-pywinrm