Files
napalm-windows/README.md
T
Christian Manivong d43d697700
driver / standard (pull_request) Successful in 15s
driver / lint (pull_request) Successful in 11s
driver / types (pull_request) Successful in 44s
driver / test (3.10) (pull_request) Successful in 46s
driver / test (3.11) (pull_request) Successful in 45s
driver / test (3.12) (pull_request) Successful in 42s
driver / test (3.13) (pull_request) Successful in 38s
driver / lowest (pull_request) Successful in 22s
driver / security (pull_request) Successful in 45s
driver / build (pull_request) Successful in 22s
CI / driver (pull_request) Successful in 5m30s
driver / publish (pull_request) Skipped
chore: adopt the NAPALM driver standard
- 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.
2026-10-23 08:49:27 +02:00

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.