Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added
- **Per-function module split.** `NetDiagram-PS.psm1` is a loader that
dot-sources `Private/` then `Public/` (one function per file). See
[STRUCTURE.md](STRUCTURE.md).
- **`Invoke-NetworkDiscovery`.** Enumerate an IPv4 CIDR (Quick/Medium/Full,
/22 cap) and return a topology after `Install-Module` without a repo clone.
- **`Import-NmapScan`.** Ingest nmap `-oX` XML; up hosts become nodes.
- **`Import-NmapScan` imports IPv6 hosts.** nmap `-oX` `address` elements with
`addrtype='ipv6'` are accepted when a host has no IPv4 address. Dual-stack
hosts keep a single node identity: IPv4 is preferred when both families are
present. Addresses are parsed with `[System.Net.IPAddress]::Parse` and stored
in canonical form; malformed addresses are skipped (same as invalid IPv4).
- **`Export-Mermaid`.** Flowchart LR with subnet subgraphs; L2 solid,
L3-Inferred dotted.
- **`Export-NetBox`.** Devices CSV for NetBox bulk import (`-Site`,
role/status mapping).
- **`Export-NodeInventoryCsv`.** Flat node inventory CSV.
- **`Export-Topology` / `Import-Topology`.** JSON round-trip of Nodes,
Edges, and Subnets.
- **`Get-SnmpBridgeNeighbors`.** Walks BRIDGE-MIB `dot1dTpFdbTable` and
emits `L2-FDB` edges (ranked between L2-SNMP and L3-Inferred) for MACs
that resolve via the local ARP table.
- **IPv6 in subnet matching, ARP, and DrawIO.** `Test-IPInSubnet`,
`Get-LocalARPTable` / `ConvertFrom-ArpText`, and subnet parenting accept
IPv6. Mixed-family placement is a non-match (no throw).
- **`Get-MACVendor -OuiDatabasePath`.** Optional IEEE `oui.csv` for full
OUI coverage (built-in table remains a 31-prefix sample).

### Changed
- **`Import-Inventory` accepts dual-stack addresses.** Device `ip` and subnet
Expand All @@ -21,6 +42,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
string. Each device still has a single identity address; prefer IPv4 when a
dual-stack host needs only one row. Discovery (`Invoke-NetworkDiscovery`)
remains IPv4-only.
- **Reachability is tri-state.** `Test-DeviceReachability` records `$true` /
`$false` / `$null` (indeterminate, e.g. local send failure). Optional
`-TcpFallbackPort` can promote ICMP-silent hosts. DrawIO paints unknown gray.
- **Packaged CI smoke** imports every `FunctionsToExport` entry, uses
`actions/checkout@v7`, and asserts offline dual-stack DrawIO parenting.

### Fixed
- **`Export-DrawIO` L2-FDB edge style.** Bridge forwarding-table edges (`Confidence='L2-FDB'`)
Expand All @@ -31,6 +57,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
local send failure stays `$null` (Unknown) rather than being painted
Unreachable. Optional `-TcpFallbackPort` is forwarded to the same helper.
The step-[4/5] summary reports reachable, unreachable, and unknown counts.
- **`Compare-NetworkScans` respects incomplete SNMP.** Nodes skipped because
the current snapshot’s SNMP outcome is `noCredential` or `error` are not
reported as Removed.
- **SNMP per-node outcomes.** `Get-SnmpNeighbors` records
answered/noCredential/error/noData per queried node; `Export-Metadata`
persists `snmpSummary` / `snmpOutcomes`.
- **`Export-DrawIO` / `Export-Metadata` require `-Force` to overwrite.**

## [1.3.0] - 2026-07-30

Expand Down Expand Up @@ -198,4 +231,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[1.0.0]: https://github.com/jacobyoby/PSNetMap/releases/tag/v1.0.0
[1.1.0]: https://github.com/jacobyoby/PSNetMap/compare/v1.0.0...v1.1.0
[1.2.0]: https://github.com/jacobyoby/PSNetMap/compare/v1.1.0...v1.2.0
[unreleased]: https://github.com/jacobyoby/PSNetMap/compare/v1.3.0...HEAD
[1.3.0]: https://github.com/jacobyoby/PSNetMap/compare/v1.2.0...v1.3.0
4 changes: 2 additions & 2 deletions NetDiagram-PS/NetDiagram-PS.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@

PrivateData = @{
PSData = @{
Tags = @('Network', 'Discovery', 'Diagram', 'SNMP', 'DrawIO', 'Topology', 'NetworkMapping', 'Cisco', 'LLDP', 'Visualization')
Tags = @('Network', 'Discovery', 'Diagram', 'SNMP', 'DrawIO', 'Topology', 'NetworkMapping', 'Cisco', 'LLDP', 'IPv6', 'Visualization')
LicenseUri = 'https://github.com/jacobyoby/PSNetMap/blob/main/LICENSE'
ProjectUri = 'https://github.com/jacobyoby/PSNetMap'
ReleaseNotes = 'Version 1.3.0 - Code-review hardening. Get-SnmpNeighbors now queries untested nodes by default (Reachable = $null), fixing the import-then-discover workflow, with an -OnlyReachable opt-in switch. Invoke-SnmpWalk redacts the community string from verbose output, validates all parameters (SNMP version set, IP/FQDN, OID format, argument-injection guard), restricts binary resolution to Application, and documents process-list exposure. LLDP/CDP parsing hardened (value-only, octet-validated, Hex-STRING aware) and clearly documented as best-effort. Export-DrawIO de-duplicates node IPs and parents nodes into their matching subnet containers. Invoke-PortScan validates port/timeout ranges and drops TCP 161 (SNMP is UDP). Resolve-IPHostname now honors -TimeoutSeconds via async DNS. Example wizard uses real CIDR host enumeration (with a /22 scan cap) instead of assuming /24.'
ReleaseNotes = 'Unreleased (post-1.3.0). Module split into Public/Private loader files. IPv6 subnet matching, ARP discovery, DrawIO parenting, and dual-stack Import-Inventory. Import-NmapScan accepts IPv6-only nmap hosts (IPv4 preferred on dual-stack). Get-SnmpBridgeNeighbors walks BRIDGE-MIB forwarding tables and emits L2-FDB edges. New commands: Invoke-NetworkDiscovery, Import-NmapScan, Export-Mermaid, Export-NetBox, Export-NodeInventoryCsv, Export-Topology, Import-Topology. Test-DeviceReachability is tri-state ($true/$false/$null) with optional TCP fallback; the wizard uses the same helper. Packaged CI smoke checks FunctionsToExport and offline IPv6 DrawIO parenting.'
}
}
}
22 changes: 14 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,15 @@ Set-Secret -Name 'MySNMPCommunity' -Secret 'public'
# 3. Discover topology with SNMP
$topo = Import-Inventory -Path '.\my-inventory.json'
$topo = $topo | Get-SnmpNeighbors -CredentialMapPath '.\my-credmap.json'
$topo = $topo | Get-SnmpBridgeNeighbors -CredentialMapPath '.\my-credmap.json'
$topo | Export-DrawIO -OutFile '.\network.drawio'
```

> **Note:** `Get-SnmpNeighbors` queries every imported node by default (nodes whose
> reachability has not been tested are still queried), so the workflow above runs end to
> end without a separate reachability pass. Add `-OnlyReachable` (after piping through
> `Test-DeviceReachability`) to query only nodes that answered a ping.
> **Note:** `Get-SnmpNeighbors` and `Get-SnmpBridgeNeighbors` query every imported node
> by default (nodes whose reachability has not been tested are still queried), so the
> workflow above runs end to end without a separate reachability pass. Add
> `-OnlyReachable` (after piping through `Test-DeviceReachability`) to query only nodes
> that answered a ping. Bridge FDB links are labeled `L2-FDB` and drawn as solid teal.
>
> **LLDP/CDP parsing is best-effort (MVP):** it extracts typed management-address values
> from `snmpwalk` output and links them to known nodes, but does not fully decode the
Expand Down Expand Up @@ -247,7 +249,9 @@ PSNetMap/
├── README.md # Main documentation and conventions
├── NetDiagram-PS/
│ ├── NetDiagram-PS.psd1 # Module manifest
│ └── NetDiagram-PS.psm1 # Module implementation
│ ├── NetDiagram-PS.psm1 # Loader (dot-sources Private/ then Public/)
│ ├── Private/ # Internal helpers (not exported)
│ └── Public/ # Exported commands (one file per function)
├── examples/
│ ├── New-NetworkDiagram.ps1 # Guided discovery wizard
│ ├── credmap.json # SNMP credential-map template
Expand All @@ -256,8 +260,9 @@ PSNetMap/
└── NetDiagram.Tests.ps1 # Pester test suite
```

This is the single maintained repository-layout reference. Update it when tracked
top-level files or test entry points change.
This tree is the top-level layout. Per-file module contents and loader
conventions live in [STRUCTURE.md](STRUCTURE.md). Update both when tracked
top-level files, Public/Private files, or test entry points change.

### Keep generated network data outside the clone

Expand Down Expand Up @@ -298,7 +303,8 @@ After importing the module, you have access to:
| `Resolve-IPHostname` | Perform reverse DNS lookups |
| `Get-MACVendor` | Look up vendors for MAC addresses |
| `Invoke-PortScan` | Check TCP ports with optional banner grabbing |
| `Get-SnmpNeighbors` | Discover connections via SNMP |
| `Get-SnmpNeighbors` | Discover connections via SNMP (LLDP/CDP) |
| `Get-SnmpBridgeNeighbors` | Discover L2-FDB edges from switch forwarding tables |
| `Get-CommonSNMPStrings` | Suggest likely SNMP community strings |
| `Merge-Edges` | Combine and deduplicate connections |
| `Export-DrawIO` | Generate diagram file |
Expand Down
1 change: 1 addition & 0 deletions STRUCTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ NetDiagram-PS/
├── Get-CommonSNMPStrings.ps1
├── Get-LocalARPTable.ps1
├── Get-MACVendor.ps1
├── Get-SnmpBridgeNeighbors.ps1
├── Get-SnmpNeighbors.ps1
├── Import-Inventory.ps1
├── Import-NmapScan.ps1
Expand Down