PyPSRP
PyPSRP is a Python library that provides client implementations for the PowerShell Remoting Protocol (PSRP) and the underlying WS-Management (WinRM) protocol. It allows Python applications to execute PowerShell commands and scripts on remote Windows machines. The current version is 0.9.1, and releases are made on an as-needed basis to add features or fix bugs.
Warnings
- breaking PyPSRP requires Python 3.10 or newer. Attempting to install or run on older Python versions will result in dependency resolution failures or runtime errors.
- gotcha WinRM and PowerShell Remoting require specific configurations on the target Windows host, including enabling WinRM (e.g., `winrm quickconfig` in an elevated PowerShell) and ensuring firewall rules allow traffic on ports 5985 (HTTP) or 5986 (HTTPS).
- gotcha Remote PowerShell command errors (e.g., cmdlets failing) are not raised as Python exceptions by default. Instead, they are captured in the `ps.streams.error` or `ps.streams.warning` lists.
- gotcha Authentication can be complex. NTLM and Kerberos are supported, but Kerberos requires the `gssapi` dependency and proper Kerberos configuration (e.g., `krb5.conf`). SSL/TLS certificate verification can also be an issue, especially with self-signed certificates.
- gotcha PyPSRP provides both low-level WS-Management (WinRM) through `WSMan` and higher-level PowerShell Remoting through `RunspacePool` and `PowerShell`. Using `WSMan` directly for PowerShell commands will be significantly more complex as it doesn't handle the PowerShell serialization and object model.
Install
-
pip install pypsrp -
pip install pypsrp[kerberos]
Imports
- WSMan
from pypsrp.wsman import WSMan
- RunspacePool
from pypsrp.powershell import RunspacePool
- PowerShell
from pypsrp.powershell import PowerShell
Quickstart
import os
from pypsrp.powershell import PowerShell, RunspacePool
# Set these environment variables for a runnable example:
# PYPSRP_HOST='your_windows_host'
# PYPSRP_USERNAME='your_username'
# PYPSRP_PASSWORD='your_password'
host = os.environ.get('PYPSRP_HOST', '')
username = os.environ.get('PYPSRP_USERNAME', '')
password = os.environ.get('PYPSRP_PASSWORD', '')
if not all([host, username, password]):
print("Please set PYPSRP_HOST, PYPSRP_USERNAME, and PYPSRP_PASSWORD environment variables to run this quickstart.")
else:
try:
# Establish a PowerShell RunspacePool connection
with RunspacePool(
server=host,
username=username,
password=password,
# For self-signed certificates or non-verified hosts, use verify_ssl=False
# connection_options={'verify_ssl': False, 'connection_timeout': 30}
) as pool:
print(f"Connected to {host} successfully.")
# Create a PowerShell pipeline
ps = PowerShell(pool)
# Add a script to execute
ps.add_script("Get-Service -Name bits | Select-Object Name, Status, DisplayName")
# Invoke the script and get the output
output = ps.invoke()
print("\n--- Command Output ---")
if output:
for item in output:
print(item)
else:
print("No output from command.")
# Check for any error or warning streams from PowerShell
if ps.streams.error:
print("\n--- PowerShell Errors ---")
for error in ps.streams.error:
print(error.message)
if ps.streams.warning:
print("\n--- PowerShell Warnings ---")
for warning in ps.streams.warning:
print(warning.message)
except Exception as e:
print(f"An error occurred: {e}")