Skip to content

Add New-CustomGroupsFromSubnets: create/populate custom groups from subnet mappings - #48

Merged
tjobarow merged 9 commits into
masterfrom
worktree-create-custom-group-of-assets-by-subnet
Aug 18, 2026
Merged

Add New-CustomGroupsFromSubnets: create/populate custom groups from subnet mappings#48
tjobarow merged 9 commits into
masterfrom
worktree-create-custom-group-of-assets-by-subnet

Conversation

@tjobarow

Copy link
Copy Markdown
Contributor

Summary

  • Adds New-CustomGroupsFromSubnets.ps1 (in Segment/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 sibling Pin-AssetsToClusters.ps1.
  • -ClientType/-ServerType/-AllType control which asset types are matched (at least one required); -RemoveAssets reverses the operation to remove matching assets from a group instead of adding them; -TargetGroupName re-runs against a single already-known group via a local JSON audit record instead of the CSV.
  • API key is read from a local .env file (never a command-line parameter); the tenant portal URL is derived automatically from the key's JWT aud claim.
  • -DryRun performs all read-only work (group lookup, subnet expansion, asset discovery, membership checks) and only skips mutating calls, so previews report real counts.
  • Full README.md with setup, usage examples, and troubleshooting.

Test plan

  • Script parses cleanly (ParseFile) and both parameter sets verified via Get-Command -Syntax
  • Live-tested against a real tenant: dry-run and real (non-dry-run) runs against a 3-row subnet CSV, confirming group creation, correct client/server/all-type asset matching, membership-skip logic, and JSON record accuracy
  • Verified -RemoveAssets correctly skips group auto-creation and never calls the create path
  • Verified the empty-match-subnet fix (AllowEmptyCollection) and dry-run discovery fix against subnets with zero matching assets

🤖 Generated with Claude Code

tjobarow and others added 9 commits August 18, 2026 09:07
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>
@tjobarow
tjobarow merged commit e9d37c1 into master Aug 18, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant