Capture. Plan.
Change. Record.
Four steps, in the order the work actually happens on site. It starts with a console cable, not with a dashboard.
Plug in and capture.
Console cable into the switch, Groundplane in the browser. It runs the show commands, reads back ports, VLANs, trunks, neighbours and the configuration, and strips every password before any of it is stored. The model, the serial and the port map come from the device, not from a spreadsheet.
The switch describes itself.

Design the scheme.
VLANs, subnets, gateways and DHCP ranges in one place, checked as arithmetic. Overlapping subnets, a gateway outside its own subnet, a DHCP pool that would hand out the gateway: all caught on the page rather than at two in the morning.
The plan is checked before it is a change.
Change it, safely.
Pick ports, say what should be true, and Groundplane writes the commands. It refuses to send a config with a placeholder still in it, blocks the change that would strand you, such as DHCP snooping with no trusted uplink or the last local user removed, and sends line by line, stopping dead on the first error the device returns.
Half a config is worse than none.
Hand off the evidence.
An as-built document, a port-map workbook and an issued report, all built from the same captured data and all stating what could not be measured rather than leaving it blank. Your mark on the cover. Still correct a year later.
The record outlives the visit.
Ten lines that break
a tool written from the manual.
Reading show interfaces status looks like a morning’s work until you meet the output. These are the cases that decide whether a capture is trustworthy, each one a line a real Catalyst prints and each one cited to the assertion that keeps it true.
68 assertions across the parser, run on every build against a reproduced Catalyst 2960X capture. Where a vendor is untested, the product says so rather than guessing: Juniper is marked unverified in the UI until somebody has run it against real hardware.
Gi1/0/1 uplink to core sw connected trunk a-full a-1000
Naive
Reads the Vlan column with parseInt and stores NaN, or worse, 0.
Here
trunk becomes a port mode. The lint rules then know this port is load-bearing, which is what stops the shutdown.
parse.test.mjs · "trunk" in the Vlan column becomes a mode, not a VLAN number
Vl20 mgmt connected routed a-full a-1000
Naive
Same column, different word. routed is not a number either.
Here
Recognised, not coerced. An SVI is not an access port in VLAN zero.
parse.test.mjs · "routed" is recognised and not coerced to NaN
Gi1/0/5 printer back offic connected 20 a-full a-100
Naive
Splits on whitespace. The description becomes "printer", and "back" and "offic" shift every field after it by two.
Here
Columns are located from the header offsets, so a description with spaces survives intact, even when it crowds its column and the device truncates it.
parse.test.mjs · a description containing spaces survives
Po1 to-core connected trunk a-full a-2000
Naive
a-2000 is one character wider than its right-aligned column, so the field bleeds and the speed arrives as "a-200" and "0".
Here
Right-aligned columns are read from the right. The speed is a-2000.
parse.test.mjs · a speed wider than its right-aligned column is not split
20 DATA active Gi1/0/3, Gi1/0/4, Gi1/0/5,
Gi1/0/6, Gi1/0/7Naive
Reads line by line. VLAN 20 has three ports. Gi1/0/6 and Gi1/0/7 are silently lost, and on a 48-port switch almost every VLAN wraps.
Here
Continuation lines are joined to the VLAN above them. Five ports.
parse.test.mjs · a wrapped port list keeps the continuation ports
All 0100.0ccc.cccc STATIC CPU
Naive
Counts the switch’s own control-plane MACs as learned endpoints, and the asset count is quietly wrong on every device.
Here
CPU and control-plane rows are skipped.
parse.test.mjs · CPU and control-plane rows are skipped
Port Vlans allowed on trunk Po1 1-4094
Naive
Expands the range. Thirty-nine ninety-four rows in the database, per trunk.
Here
Kept as the device wrote it. The range is expanded only when something actually needs to ask whether a VLAN is in it.
parse.test.mjs · 1-4094 is not enumerated into 4094 entries, but the raw value is kept
Device ID: core-sw1.acme.local (CDP) System Name: core-sw1.acme.local (LLDP)
Naive
Both protocols see the same switch, so the topology shows two neighbours and one phantom link.
Here
CDP and LLDP describing the same neighbour produce one link.
parse.test.mjs · CDP and LLDP describing the same neighbour produce ONE link
enable secret 5 <redacted>
Naive
Keeps the running config verbatim, hash and all. The password hashes of every switch you ever touched end up in somebody’s database.
Here
Redacted in the browser, before the capture leaves the laptop, which is why this line reads this way in the project’s own test fixture. The record knows a secret is set. It does not know what it is.
parse.test.mjs · an enable secret is recorded as PRESENT, never as a value
% Invalid input detected at '^' marker.
Naive
The trunk command failed, so the device has no trunks. Reported as a clean result.
Here
Reported as unparsed. A command that did not run is unmeasured, which is not the same as zero. That is the single rule the whole product is built on.
parse.test.mjs · a failed trunk command is reported, not treated as "no trunks"
What a terminal will not do.
Every terminal is a pipe. It sends what you type, which is the point of a terminal and also how the bad afternoons start. These are the five things Groundplane declines to do to you.
- 01
It will not send a template
A line still carrying <GATEWAY> or <VLAN> never reaches the switch. The paste stops before the first byte goes out and tells you which lines are unfilled, rather than applying the ones above them and failing on line fourteen.
- 02
It will not outrun the console
A 9600 baud console drops characters from a block paste, and a mangled command is worse than a refused one. Lines go one at a time, each waiting for the prompt. The first error the device reports stops the run. Half a config you know about is recoverable.
- 03
It will not let you shut the uplink
Not a guess from the port number: it is checked against what the switch itself reported: the trunk, the neighbour on the other end, the port-channel. If it is genuinely a planned cutover you override it, and the override is written into the record as a decision.
- 04
It will not keep your secrets
Enable secrets, SNMP communities, PSKs and keys are stripped in the browser before anything is stored, and the database refuses a document that still contains credential material. A password is typed at the device, in a session nothing records.
- 05
It will not make you write the as-built
The session is the document. Ports, VLANs, neighbours and patch panels come out as a PDF, a port-map workbook, or a diagram you can open in draw.io, built from what the switch said, not from what anyone remembered.
Every one of these is enforced in the code and has a test behind it. None of it is a setting you can switch off, and none of it depends on your plan.
Know what you are standing on.
Groundplane turns infrastructure reality into a reference you can explain.