- CI moves to .gitea/workflows/ci.yml and calls the shared driver workflow of NAPALM/driver-standard; .github/ is gone. - requires-python >=3.10 (napalm-device-types needs it), LICENSE file, py.typed, setuptools>=77 with the SPDX license string, Issues and Changelog links on git.netork.io, napalm-device-types>=4.21.1 from PyPI, floors on the dev extra. - mypy strict for the whole package, no module exempt: optional_args is dict[str, Any] | None. - tests/quality_baseline.json records get_facts and get_route_to, over complexity 10. Coverage floor 95 % (measured 95.67 %). - CHANGELOG.md in Keep a Changelog form; the README says no host output is recorded yet, links napalm-device-types in the NAPALM org and pypsrp on PyPI.
3.4 KiB
napalm-windows
NAPALM driver for Windows Server 2016+ and Windows 10/11, part of the netOrk
driver family built on napalm-device-types.
Driver name: windows · Role: OSDriver · Transport: PowerShell Remoting
(PSRP) over WinRM via pypsrp.
Tested against
Not recorded yet: the fixtures under tests/fixtures/synthetic/ are the JSON the scripts
are designed to emit, not output recorded from a host.
Install
pip install napalm-windows
How it works
Every getter sends one PowerShell script. The script projects the cmdlet
results onto flat, primitive fields and ends in ConvertTo-Json, so the
Python side parses JSON, never text. All device I/O goes through a single
seam (PsrpTransport.run(script) -> str), which is what the tests replace.
One runspace pool stays open per connection, so a poll pays the WinRM handshake once.
Supported
| Method | Source |
|---|---|
get_facts |
Win32_ComputerSystem, Win32_OperatingSystem, Win32_BIOS, registry (DisplayVersion, UBR) |
get_interfaces |
Get-NetAdapter |
get_interfaces_ip |
Get-NetIPAddress (loopback dropped, IPv6 zone index stripped) |
get_arp_table |
Get-NetNeighbor -AddressFamily IPv4 (broadcast, multicast, unreachable dropped) |
get_route_to |
Get-NetRoute (multicast, broadcast, loopback dropped) |
get_services / manage_service |
Win32_Service, Start-/Stop-/Restart-Service, Set-Service -StartupType |
get_listening_sockets |
Get-NetTCPConnection -State Listen, Get-NetUDPEndpoint, Get-Process, Win32_Service (a shared svchost names no service) |
running_kernel carries the full build including the update revision
(10.0.20348.2340): Windows ships fixes as UBR bumps, which is what CVE
matching has to compare against.
Not yet: packages, Windows Update, scheduled tasks, health metrics, Hyper-V. See netork#300 for the plan.
Preparing a host
WinRM is on by default on Windows Server; on Windows 10/11 run
Enable-PSRemoting once. Then either
- HTTPS (5986, default) — needs a certificate-backed HTTPS listener, or
- HTTP (5985) — set the device port to 5985. Traffic is still encrypted at message level (NTLM/Kerberos), credentials never travel in the clear.
A local administrator account additionally needs
LocalAccountTokenFilterPolicy = 1 under
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System; without it
remote UAC strips the admin token. Domain accounts are not affected.
optional_args
| Key | Default | Meaning |
|---|---|---|
port |
5986 |
WinRM port |
winrm_ssl |
port != 5985 |
force HTTPS on or off |
winrm_auth |
negotiate |
pypsrp auth protocol (negotiate, ntlm, kerberos, credssp, basic) |
ssl_verify |
True |
validate the WinRM certificate |
Development
The rules are in STANDARDS.md.
python -m venv .venv && .venv/bin/pip install -e ".[dev]"
.venv/bin/pytest --cov
Tests and fixtures
tests/fixtures/synthetic/ holds the JSON the scripts are designed to emit.
To record the real thing from a host:
python tools/harvest.py <host> <user> <label> [--port 5985] [--insecure]
Output lands in tools/harvest-out/ (gitignored); scrub it before copying
anything into tests/.
License
Apache-2.0, see LICENSE.