Apache Airflow provider package for Windows Remote Management (WinRM) protocol integration enabling remote command execution on Windows systems
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Comprehensive WinRM connection management and command execution hook for Apache Airflow. Provides low-level interface for establishing secure connections to Windows systems and executing commands or PowerShell scripts remotely.
from winrm.protocol import Protocol
from airflow.providers.microsoft.winrm.version_compat import BaseHookCreate WinRM hook instances with flexible configuration options supporting multiple authentication methods and security settings.
class WinRMHook(BaseHook):
def __init__(
self,
ssh_conn_id: str | None = None,
endpoint: str | None = None,
remote_host: str | None = None,
remote_port: int = 5985,
transport: str = "plaintext",
username: str | None = None,
password: str | None = None,
service: str = "HTTP",
keytab: str | None = None,
ca_trust_path: str | None = None,
cert_pem: str | None = None,
cert_key_pem: str | None = None,
server_cert_validation: str = "validate",
kerberos_delegation: bool = False,
read_timeout_sec: int = 30,
operation_timeout_sec: int = 20,
kerberos_hostname_override: str | None = None,
message_encryption: str | None = "auto",
credssp_disable_tlsv1_2: bool = False,
send_cbt: bool = True,
) -> None:
"""
Initialize WinRM hook with connection parameters.
Parameters:
- ssh_conn_id: Airflow connection ID containing WinRM settings
- endpoint: Full WinRM endpoint URL (auto-constructed if not provided)
- remote_host: Target Windows host IP address or hostname
- remote_port: WinRM service port (5985 for HTTP, 5986 for HTTPS)
- transport: Authentication transport ('plaintext', 'kerberos', 'ssl', 'ntlm', 'credssp')
- username: Username for authentication (auto-detected if not provided)
- password: Password for authentication
- service: Service name for Kerberos authentication
- keytab: Path to Kerberos keytab file
- ca_trust_path: Certificate Authority trust path for SSL validation
- cert_pem: Client certificate file in PEM format
- cert_key_pem: Client certificate private key file in PEM format
- server_cert_validation: Certificate validation mode ('validate' or 'ignore')
- kerberos_delegation: Enable Kerberos ticket delegation
- read_timeout_sec: HTTP connection read timeout
- operation_timeout_sec: WinRM operation timeout
- kerberos_hostname_override: Override hostname for Kerberos
- message_encryption: Message encryption setting ('auto', 'always', 'never')
- credssp_disable_tlsv1_2: Disable TLS v1.2 for CredSSP authentication
- send_cbt: Send channel binding tokens over HTTPS
"""Usage Examples:
# Using Airflow connection
hook = WinRMHook(ssh_conn_id='windows_server_1')
# Direct configuration with NTLM
hook = WinRMHook(
remote_host='192.168.1.100',
username='administrator',
password='SecurePass123',
transport='ntlm'
)
# SSL with certificate authentication
hook = WinRMHook(
remote_host='winserver.company.com',
remote_port=5986,
transport='ssl',
cert_pem='/path/to/client.pem',
cert_key_pem='/path/to/client-key.pem',
server_cert_validation='validate'
)
# Kerberos authentication
hook = WinRMHook(
remote_host='winserver.domain.com',
transport='kerberos',
service='HTTP',
kerberos_delegation=True
)Establish and manage WinRM protocol connections with comprehensive configuration from Airflow connections or direct parameters.
def get_conn(self) -> Protocol:
"""
Create and return WinRM protocol connection.
Handles connection parameter resolution from Airflow connections,
endpoint construction, authentication setup, and protocol initialization.
Returns:
winrm.protocol.Protocol: Configured WinRM protocol instance
Raises:
AirflowException: Connection creation failures, missing parameters, authentication errors
"""Connection Parameter Resolution:
The hook resolves connection parameters in this priority order:
Supported Extra Parameters in Airflow Connections:
{
"endpoint": "https://winserver:5986/wsman",
"remote_port": 5986,
"transport": "ssl",
"service": "HTTP",
"keytab": "/etc/krb5.keytab",
"ca_trust_path": "/etc/ssl/certs/ca-certificates.crt",
"cert_pem": "/path/to/client.pem",
"cert_key_pem": "/path/to/client-key.pem",
"server_cert_validation": "validate",
"kerberos_delegation": "true",
"read_timeout_sec": 60,
"operation_timeout_sec": 45,
"kerberos_hostname_override": "winserver.domain.com",
"message_encryption": "auto",
"credssp_disable_tlsv1_2": "false",
"send_cbt": "true"
}Execute Windows commands and PowerShell scripts on remote systems with comprehensive output handling and error management.
def run(
self,
command: str,
ps_path: str | None = None,
output_encoding: str = "utf-8",
return_output: bool = True,
) -> tuple[int, list[bytes], list[bytes]]:
"""
Execute command on remote Windows host via WinRM.
Parameters:
- command: Command or script to execute on remote host
- ps_path: PowerShell executable path ('powershell' for v5.1-, 'pwsh' for v6+)
- output_encoding: Encoding for stdout/stderr decoding
- return_output: Whether to accumulate and return stdout data
Returns:
tuple: (return_code, stdout_buffer, stderr_buffer)
- return_code: Command exit code
- stdout_buffer: List of stdout byte chunks
- stderr_buffer: List of stderr byte chunks
Raises:
AirflowException: Connection failures, command execution errors
"""Command Execution Examples:
# Execute Windows command
return_code, stdout, stderr = hook.run('dir C:\\Windows\\System32')
# Execute PowerShell command
return_code, stdout, stderr = hook.run(
'Get-Service | Where-Object Status -eq "Running" | Select-Object Name, Status',
ps_path='powershell'
)
# Execute PowerShell script with modern PowerShell
return_code, stdout, stderr = hook.run(
'''
$processes = Get-Process | Sort-Object CPU -Descending | Select-Object -First 10
$processes | Format-Table Name, CPU, WorkingSet -AutoSize
''',
ps_path='pwsh'
)
# Execute command without output buffering (for large outputs)
return_code, stdout, stderr = hook.run(
'robocopy C:\\Source D:\\Backup /E /LOG:backup.log',
return_output=False
)PowerShell Script Encoding:
When ps_path is specified, commands are automatically encoded using PowerShell's -encodedcommand parameter to handle special characters and multi-line scripts properly. The encoding process:
{ps_path} -encodedcommand {base64_encoded_command}This ensures proper handling of Unicode characters, quotes, and multi-line PowerShell scripts.
Validate WinRM connections with built-in connection testing functionality.
def test_connection(self) -> tuple[bool, str]:
"""
Test WinRM connection by executing a simple command.
Executes 'cd' command to verify connectivity and authentication.
Returns:
tuple: (success, message)
- success: True if connection successful, False otherwise
- message: Success message or error description
"""Usage Example:
hook = WinRMHook(ssh_conn_id='windows_server_1')
success, message = hook.test_connection()
if success:
print(f"Connection successful: {message}")
else:
print(f"Connection failed: {message}")Basic authentication with username and password transmitted in plaintext. Only recommended for trusted networks.
hook = WinRMHook(
remote_host='192.168.1.100',
username='admin',
password='password',
transport='plaintext'
)Windows NTLM authentication providing secure credential transmission with challenge-response protocol.
hook = WinRMHook(
remote_host='winserver.local',
username='DOMAIN\\user',
password='password',
transport='ntlm'
)Enterprise-grade Kerberos authentication with ticket-based security and delegation support.
hook = WinRMHook(
remote_host='winserver.domain.com',
username='user@DOMAIN.COM',
transport='kerberos',
service='HTTP',
kerberos_delegation=True,
kerberos_hostname_override='winserver.domain.com'
)Secure transport with SSL/TLS encryption and optional certificate-based client authentication.
hook = WinRMHook(
remote_host='winserver.company.com',
remote_port=5986,
username='admin',
password='password',
transport='ssl',
cert_pem='/path/to/client.pem',
cert_key_pem='/path/to/client-key.pem',
ca_trust_path='/path/to/ca-bundle.crt',
server_cert_validation='validate'
)Credential Security Support Provider enabling credential delegation for multi-hop scenarios.
hook = WinRMHook(
remote_host='winserver.domain.com',
username='DOMAIN\\user',
password='password',
transport='credssp',
credssp_disable_tlsv1_2=False
)The WinRMHook handles various error conditions:
WinRMOperationTimeoutError is caught and handled silently for long-running processesAll errors are wrapped in AirflowException with descriptive error messages for troubleshooting. The hook also handles different pywinrm library versions gracefully by attempting get_command_output_raw() first, then falling back to _raw_get_command_output() for older versions.
Install with Tessl CLI
npx tessl i tessl/pypi-apache-airflow-providers-microsoft-winrm