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.
69 lines
2.1 KiB
Python
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()
|