Add New-CustomGroupsFromSubnets: create/populate custom groups from subnet mappings - #48
Merged
tjobarow merged 9 commits intoAug 18, 2026
Conversation
Create/populate Zero Networks custom groups from a subnet-to-group-name CSV mapping, reusing the subnet expansion and API plumbing patterns from Pin-AssetsToClusters.ps1. Skips assets already in a group, keeps a local JSON audit record, and supports re-running against a single known group by name. API key is read from a local .env file and the tenant portal URL is derived from the key's JWT aud claim. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Pin-AssetsToClusters.ps1 and *.csv are local reference/input material, not deliverables of this script, so keep them out of version control. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Documents setup (.env, subnet CSV), both parameter sets, the local JSON record format, logging, dry-run behavior, and troubleshooting. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The assetType filter added server-side to /assets/monitored used an unverified value format and caused every subnet lookup to return zero assets. Drop it in favor of the already-proven lastIpAddress filter, with -Client/-Server (now required, at least one) driving a client-side assetType restriction instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds a -RemoveAssets switch that removes matching assets currently in a group instead of adding them, for both the CSV bulk path and -TargetGroupName. Groups are never auto-created in this mode. The local JSON record's assetsAssigned list is kept in sync by dropping removed asset IDs. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Dry-run previously short-circuited before subnet expansion/asset discovery whenever the target group didn't exist yet, so it reported zero information about what would actually happen. Discovery is read-only (GET calls only), so it now always runs; only the group membership check (which needs a real group ID) is skipped when the group doesn't exist, with discovered assets still counted and reported in that case. Verified end-to-end against a real tenant: -DryRun -Server correctly found the 2 expected server assets in 10.1.11.0/24. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…roup PowerShell rejects an empty collection bound to a Mandatory, strongly-typed collection parameter, distinct from rejecting $null. Any subnet with zero matching assets crashed the run with "Cannot bind argument to parameter 'Assets' because it is an empty collection." Add [AllowEmptyCollection()] to the Assets parameter on Add-AssetsToCustomGroup and Remove-AssetsFromCustomGroup (both already handle Count -eq 0 internally), and defensively to Write-RunSummary's Results parameter for the same reason. Verified against the real tenant: a live (non-dry-run) pass over a 3-row CSV with two zero-match subnets and one 2-asset match now completes end-to-end instead of crashing on the first zero-match row. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… -AllType Clearer parameter names for the assetType restriction, plus a new -AllType switch that removes the Client/Server restriction entirely so any asset type can be matched/added/removed. At least one of -ClientType, -ServerType, or -AllType is now required; -AllType takes precedence if combined with either of the others. Verified against the real tenant: the updated validation error fires correctly with no type switch given, and -AllType picked up server assets in 10.1.10.0/24 that -ServerType alone had not (a segment server and AD DC not otherwise in a client/server-restricted run). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Reference file was added to .gitignore in an earlier commit but the README's Notes section only mentioned Pin-AssetsToClusters.ps1 and *.csv. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
New-CustomGroupsFromSubnets.ps1(inSegment/Segment/Asset Management/Create Custom Group from Asset Subnets) which creates Zero Networks custom groups from a subnet-to-group-name CSV mapping and populates each group with matching assets by last known IP, reusing the subnet expansion/API plumbing patterns from the siblingPin-AssetsToClusters.ps1.-ClientType/-ServerType/-AllTypecontrol which asset types are matched (at least one required);-RemoveAssetsreverses the operation to remove matching assets from a group instead of adding them;-TargetGroupNamere-runs against a single already-known group via a local JSON audit record instead of the CSV..envfile (never a command-line parameter); the tenant portal URL is derived automatically from the key's JWTaudclaim.-DryRunperforms all read-only work (group lookup, subnet expansion, asset discovery, membership checks) and only skips mutating calls, so previews report real counts.README.mdwith setup, usage examples, and troubleshooting.Test plan
ParseFile) and both parameter sets verified viaGet-Command -Syntax-RemoveAssetscorrectly skips group auto-creation and never calls the create pathAllowEmptyCollection) and dry-run discovery fix against subnets with zero matching assets🤖 Generated with Claude Code