Talks PSRP over WinRM via pypsrp, one runspace pool per connection. Each getter sends one PowerShell script that projects cmdlet results onto flat fields and ends in ConvertTo-Json, so the Python side parses JSON, not text. Covers facts, interfaces, IP addresses, ARP, routes and services, plus service start/stop/restart/enable/disable. Service names are validated and quoted as PowerShell verbatim strings, typographic quotes included. Fixtures are synthetic: they pin down the JSON the scripts are designed to emit. tools/harvest.py records the real output from a host. Refs christianmanivong/netork#300
68 lines
2.1 KiB
Python
68 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,
|
|
}
|
|
|
|
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()
|