Remote power management library for workstations and servers (iDRAC, iLO, AMT, SSH).
powerctl is a Python library designed to provide a unified interface for controlling the power state of various workstations and servers. It supports multiple protocols through a driver-based architecture, allowing for easy extension via drivers and concurrency via asyncio.
| Protocol ID | Technology | Notes |
|---|---|---|
idrac |
Dell iDRAC (Redfish) | iDRAC 8 / 9 |
ilo |
HP iLO (Redfish) | iLO 4 / 5 / 6 |
amt |
Intel AMT (WS-Man) | WS-Management SOAP over HTTP(S) |
ssh_linux |
SSH Linux | Uses asyncssh or ssh CLI |
ssh_windows |
SSH / WinRM Windows | PowerShell via SSH or WinRM |
pip install "powerctl[all]" # everything (recommended)
pip install powerctl # core, no optional deps
pip install "powerctl[ssh]" # + asyncssh for SSH drivers
pip install "powerctl[winrm]" # + pywinrm for WinRM driverimport asyncio
from powerctl import PowerClient, Host, Credentials
host = Host(
hostname="192.168.1.10",
protocol="idrac",
credentials=Credentials(username="root", password="calvin"),
)
async def main():
async with PowerClient(host) as client:
result = await client.reboot()
print(result) # <PowerResult action=reboot status=OK ...>
asyncio.run(main())Host(
hostname="192.168.1.10",
protocol="idrac",
credentials=Credentials(username="root", password="calvin"),
)Host(
hostname="192.168.1.20",
protocol="ilo",
credentials=Credentials(username="Administrator", password="hunter2"),
)Host(
hostname="192.168.1.30",
protocol="amt",
credentials=Credentials(username="admin", password="AMTs3cret!"),
extra={"tls": True}, # use port 16993 (HTTPS)
)Host(
hostname="192.168.1.40",
protocol="ssh_linux",
credentials=Credentials(username="sysadmin", private_key_path="/home/me/.ssh/id_ed25519"),
extra={"sudo": True},
)# Via SSH (OpenSSH Server must be installed on Windows)
Host(
hostname="192.168.1.50",
protocol="ssh_windows",
credentials=Credentials(username="Administrator", password="W1nd0ws!"),
extra={"transport": "ssh"},
)
# Via WinRM (requires pip install powerctl[winrm])
Host(
hostname="192.168.1.50",
protocol="ssh_windows",
credentials=Credentials(username="Administrator", password="W1nd0ws!"),
extra={"transport": "winrm", "https": True},
)from powerctl import reboot_all, run_action_all, Host, Credentials
hosts = [
Host(hostname=f"10.0.0.{i}", protocol="idrac",
credentials=Credentials(username="root", password="calvin"))
for i in range(1, 21)
]
async def main():
results = await reboot_all(hosts, max_concurrent=5)
for r in results:
print(r)The project uses setuptools and pyproject.toml.
# Create a virtual environment
python -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
# install build tool
pip install --upgrade build
# Install in editable mode with all dependencies
pip install -e ".[all,dev]"Tests are located in the tests/ directory and use pytest with pytest-asyncio.
pytestThe project enforces strict typing and linting standards.
# Linting and formatting
ruff check .
ruff format .
# Type checking
python3 -m pip install types-requests
mypy src/powerctlpython -m buildfrom powerctl import register_driver, BaseDriver, PowerAction, PowerResult
from powerctl.core import Host
@register_driver
class IpmiDriver(BaseDriver):
"""Example IPMI driver using ipmitool CLI."""
protocol = "ipmi"
async def power_on(self) -> PowerResult:
# call ipmitool here ...
return PowerResult(PowerAction.POWER_ON, success=True)
async def power_off(self) -> PowerResult: ...
async def power_cycle(self) -> PowerResult: ...
async def reboot(self) -> PowerResult: ...
async def shutdown(self) -> PowerResult: ...Once decorated with @register_driver, the driver is immediately
available to PowerClient by its protocol string.
pip install "powerctl[dev]"
pytestpowerctl/
├── __init__.py # Public API surface
├── client.py # PowerClient facade + bulk helpers
├── core/
│ ├── base.py # BaseDriver ABC, PowerAction enum, PowerResult
│ ├── host.py # Host & Credentials dataclasses
│ ├── registry.py # @register_driver decorator + driver factory
│ └── exceptions.py # Exception hierarchy
└── drivers/
├── _redfish.py # Shared Redfish HTTP helpers
├── idrac.py # Dell iDRAC
├── ilo.py # HP iLO
├── amt.py # Intel AMT
├── ssh_linux.py # SSH Linux
└── ssh_windows.py # SSH / WinRM Windows
Notes:
- Strategy + Registry pattern — drivers are registered by
protocolstring;build_driver(host)picks the right one at runtime. - Abstract Base Class —
BaseDriverenforces the interface;mypy --strictwill catch missing methods. - Zero mandatory dependencies — the stdlib covers iDRAC/iLO/AMT; SSH and WinRM libs are opt-in extras.
- Async-first — all operations are
async, enabling high-throughput bulk management withasyncio.gather. - Dataclasses for config —
HostandCredentialsare frozen.