pypsrp
A pure-Python client for WinRM and the PowerShell Remoting Protocol, for running commands and PowerShell on remote Windows hosts.
Repository Health
Technical Analysis
pypsrp is a Python client library that implements the Windows Remote Management (WinRM) and PowerShell Remoting Protocol (PSRP) wire protocols from scratch, letting any Python program execute commands, run PowerShell scripts, and copy files to and from a remote Windows host without needing PowerShell or .NET installed locally. It exposes four layers of API depth: a high-level Client facade for simple command execution and file copy, a WSMan layer for raw WS-Management SOAP calls, a WinRS layer for cmd-style remote shells, and a full RunspacePool/PowerShell pipeline API modeled closely on .NET’s System.Management.Automation.Runspaces.RunspacePool.
Authentication support spans Basic, Certificate, NTLM, Negotiate/Kerberos, and CredSSP (the latter two via optional extras), with configurable TLS and message-level encryption independent of transport encryption. This protocol depth is why pypsrp is used as the underlying WinRM/PSRP connection engine inside larger automation tools such as Ansible, rather than being consumed directly by most application code.
The project has been maintained by Jordan Borean since 2018, ships full type hints (py.typed), and is tested across a Python 3.10-3.14 and Windows/Linux CI matrix.
What You Get
- Client facade - a simple
pypsrp.client.Clientclass for executing cmd commands, running PowerShell scripts, and copying files to/from a remote Windows host in a few lines of code. - Full PSRP pipeline API -
RunspacePoolandPowerShellclasses that mirror .NET’s Runspace Pool model, supporting async pipelines, multiple concurrent runspaces, and Just Enough Administration (JEA) configuration names. - WinRS shell layer - a
WinRSclass for classic cmd.exe-style remote shells, including environment variables, working directory, and codepage control. - Multi-mechanism authentication - Basic, Certificate, NTLM, Negotiate, Kerberos, and CredSSP auth, with optional message encryption over plain HTTP and CredSSP sub-mechanism selection.
- Low-level WSMan access - direct
Send/Create/Connect/DisconnectWS-Management operations for callers that need protocol-level control. - Reconnection and timeout controls - configurable operation, connection, and read timeouts plus automatic reconnection with backoff on transport failures.
Common Use Cases
- Ansible-style remote execution - building or extending automation tooling that needs to run commands and PowerShell on Windows hosts from a Linux/macOS control node, the same role pypsrp already plays inside Ansible’s winrm/psrp connection plugins.
- File deployment to Windows servers - copying configuration files, scripts, or installers to remote Windows machines and fetching logs or output files back, without SMB/file-share access.
- Windows infrastructure orchestration scripts - Python-based provisioning or configuration-management scripts that need to execute PowerShell against many Windows hosts in a CI/CD or infra pipeline.
- Kerberos/CredSSP-authenticated remoting - environments where domain-joined Windows hosts require Kerberos or CredSSP (e.g. to satisfy the WinRM double-hop problem) rather than NTLM.
- Interactive PSRP host implementations - building custom interactive PowerShell-over-WinRM clients using the
host.pyreference host implementation for prompts, progress records, and choice dialogs.
Under The Hood
Architecture
pypsrp is organized as a protocol stack with a clear one-way dependency flow: client.py provides a high-level facade over shell.py (WinRS) and powershell.py (RunspacePool/PowerShell), both of which are built on top of wsman.py’s WSMan transport object; messages.py implements PSRP message fragmentation/defragmentation, complex_objects.py (~1,650 lines) defines the full set of serializable PSRP/WSMV objects (host info, pipeline state, error records, etc.), and serializer.py (~880 lines) converts those objects to and from Microsoft’s CLIXML format. Because every higher layer takes a WSMan/connection object as a constructor argument rather than constructing its own transport, swapping the transport implementation (e.g. adding an SSH connection, which the README notes is planned) would touch shell.py, powershell.py, and host.py but not require rewriting the CLIXML/PSRP serialization layers underneath.
Tech Stack
Built for Python 3.10+ using setuptools/PEP 621 (pyproject.toml) for packaging. Core runtime dependencies are cryptography (message-level encryption), pyspnego (NTLM/Negotiate/Kerberos SPNEGO authentication), and requests (HTTP transport for WSMan SOAP calls); requests-credssp and pyspnego[kerberos] are optional extras for CredSSP and Linux Kerberos support respectively. Development tooling is strict: black and isort for formatting, mypy configured with disallow_any_unimported, disallow_untyped_calls, and no_implicit_reexport, all wired through pre-commit. CI (GitHub Actions) builds sdist/wheel artifacts and runs the test matrix across Ubuntu and Windows for Python 3.10 through 3.14.
Code Quality
The tests/tests_pypsrp/ suite mirrors the src/pypsrp layout file-for-file (test_wsman.py, test_shell.py, test_powershell.py, test_serializer.py, test_messages.py, test_complex_objects.py, test_encryption.py, test_negotiate.py, test_client.py, test_host.py, plus a dedicated test_integration.py), backed by recorded response fixtures under responses/ and data/, and uses pytest-mock for isolation. The package ships a py.typed marker and full type annotations throughout, enforced by a strict mypy configuration in pre-commit. A custom exception hierarchy (WinRMError, AuthenticationError, WinRMTransportError) surfaces structured protocol/status-code/response-text details rather than swallowing transport errors. Naming is consistent snake_case throughout, and coverage is tracked via .coveragerc across the installed package and source tree.
What Makes It Unique
Rather than shelling out to PowerShell or wrapping an existing .NET/WinRM SDK, pypsrp implements the WS-Management (WSMV) and PowerShell Remoting (MS-PSRP) wire protocols itself in pure Python — including PSRP message fragmentation, CLIXML object serialization, and a RunspacePool/PowerShell pipeline model deliberately modeled on .NET’s own System.Management.Automation.Runspaces.RunspacePool API. That protocol-level reimplementation is precisely why the library ended up as the connection engine behind other tools’ Windows remoting support (most notably Ansible’s winrm/psrp connection plugins) rather than being a thin convenience wrapper.