Files
napalm-windows/README.md
T
Christian Manivong a6814ad92e feat: report what listens, and which Windows service it is
One script: Get-NetTCPConnection -State Listen, Get-NetUDPEndpoint, the
processes holding them and Win32_Service's PIDs. A process running one
service names it; a shared svchost runs several, and which of them holds
the socket Windows does not say, so it names none. http.sys sockets
(WinRM, IIS, SMB) belong to the System process.

The fixture is synthetic: no Windows host was at hand. tools/harvest.py
records the real output. For netOrk#673.
2026-10-07 07:20:27 +02:00

77 lines
3.0 KiB
Markdown

# napalm-windows
NAPALM driver for Windows Server 2016+ and Windows 10/11, part of the netOrk
driver family built on [`napalm-device-types`](https://git.netork.io/christianmanivong/napalm-device-types).
Driver name: `windows` · Role: `OSDriver` · Transport: PowerShell Remoting
(PSRP) over WinRM via [`pypsrp`](https://github.com/jborean93/pypsrp).
## 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 |
## Tests and fixtures
```bash
pip install -e ".[dev]"
pytest
```
`tests/fixtures/synthetic/` holds the JSON the scripts are *designed* to emit.
To record the real thing from a host:
```bash
python tools/harvest.py <host> <user> <label> [--port 5985] [--insecure]
```
Output lands in `tools/harvest-out/` (gitignored); scrub it before copying
anything into `tests/`.