Files
napalm-windows/tools/harvest.py
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

69 lines
2.1 KiB
Python

"""Record what the driver's PowerShell scripts emit on a real Windows host.
python tools/harvest.py <host> <user> <label> [--port 5985] [--insecure]
Asks for the password, runs every getter script over one WinRM connection and
writes the raw JSON to tools/harvest-out/<label>/<fixture>.json — the same file
names as tests/fixtures/synthetic/. harvest-out/ is gitignored: scrub serials,
MAC and IP addresses and host names before copying anything into tests/.
"""
from __future__ import annotations
import argparse
import getpass
import pathlib
from napalm_windows import WindowsDriver
from napalm_windows import windows as mod
SCRIPTS = {
"facts": mod._PS_FACTS,
"interfaces": mod._PS_INTERFACES,
"interfaces_ip": mod._PS_INTERFACES_IP,
"arp": mod._PS_ARP,
"routes": mod._PS_ROUTES,
"services": mod._PS_SERVICES,
"listening": mod._PS_LISTENING,
}
OUT = pathlib.Path(__file__).parent / "harvest-out"
def main() -> None:
ap = argparse.ArgumentParser(description=__doc__.splitlines()[0])
ap.add_argument("host")
ap.add_argument("user")
ap.add_argument("label", help="subdirectory name, e.g. server2022 or win11")
ap.add_argument("--port", type=int, default=5986)
ap.add_argument("--insecure", action="store_true", help="skip certificate validation")
args = ap.parse_args()
driver = WindowsDriver(
args.host,
args.user,
getpass.getpass(f"Password for {args.user}@{args.host}: "),
optional_args={"port": args.port, "ssl_verify": not args.insecure},
)
target = OUT / args.label
target.mkdir(parents=True, exist_ok=True)
driver.open()
try:
for name, script in SCRIPTS.items():
try:
raw = driver._run_raw(script)
except Exception as exc: # record the failure, keep harvesting
raw = ""
print(f" {name}: FAILED — {exc}")
else:
print(f" {name}: {len(raw)} bytes")
(target / f"{name}.json").write_text(raw + "\n")
finally:
driver.close()
print(f"written to {target}")
if __name__ == "__main__":
main()