Skip to content

Add Find-CommonGroupsForDestination utility#43

Merged
dicolanl merged 2 commits into
zeronetworks:masterfrom
shachafzn:common-groups-script
Jun 18, 2026
Merged

Add Find-CommonGroupsForDestination utility#43
dicolanl merged 2 commits into
zeronetworks:masterfrom
shachafzn:common-groups-script

Conversation

@shachafzn

Copy link
Copy Markdown
Contributor

Summary

Adds a new top-level Utils/ folder with Find-CommonGroupsForDestination.ps1: given a destination asset (FQDN or IP), it lists the AD groups shared by the source users that accessed it, to help build identity-based segmentation rules.

  • Inputs: -DestinationFQDN or -DestinationIP, with optional -MinUserCount, -FromDays, -OutputPath, -IncludeSourceUsers, -MaxParallel.
  • Output: CSV with one row per qualifying group (GroupName, GroupId, SourceUserCount, optional SourceUsers, Destination, LookbackDays), plus a top-10 console summary.
  • Auth: uses $env:ZNApiKey (Set-ZNApiKey / Connect-ZN / direct assignment).

Implementation highlights

  • Fast source-user collection via /activities/network/distinctField/srcUser (single call), with fallback to paging /activities/network for older tenants.
  • Resolves activity SIDs / userName to ZN users via SID first, then PrincipalName; dedupes by ZN user id so case-variant / multi-SID identities are counted once.
  • Parallel /users/{id}/ancestors lookups on PowerShell 7+ (-MaxParallel, default 8, kicks in at ≥ 20 users) using raw REST to avoid per-runspace module import; sequential Get-ZNUserMemberOf on Windows PowerShell 5.1.
  • All API calls wrapped with retry + exponential backoff + jitter on HTTP 429 / 5xx / transport errors; Retry-After honoured.

Also adds Utils/README.md documenting the folder and full script reference (parameters, behavior, output, caveats).

The main README.md is intentionally untouched — .github/workflows/manual_pwsh_update_readme.yml regenerates it from .ps1 synopses on push/PR, so the new script will appear under a ## Utils section automatically.

Test plan

  • Run with -DestinationFQDN against a managed asset; verify CSV columns and top-10 console summary.
  • Run with -DestinationIP against the same target; confirm equivalent results.
  • Run with -IncludeSourceUsers and confirm the additional SourceUsers column appears.
  • Run on Windows PowerShell 5.1 (sequential path) and PowerShell 7+ (parallel path with ≥ 20 users) and confirm both complete successfully.
  • Run with -MaxParallel 1 on PS 7+ to force sequential.
  • Run without $env:ZNApiKey to confirm the auth error message; run with neither destination param to confirm usage is printed.

🤖 Generated with Claude Code

Adds Utils/Find-CommonGroupsForDestination.ps1: given a destination
asset (FQDN or IP), find the AD groups shared by the source users
that accessed it, to help scope identity-based segmentation rules.

Highlights:
- Fast source-user collection via /activities/network/distinctField/srcUser
  with fallback to paging /activities/network for older tenants.
- Resolves activity SIDs/userNames to ZN users via SID first, then
  PrincipalName; dedupes by ZN user id.
- Parallel group-membership lookups on PowerShell 7+ (-MaxParallel,
  default 8, threshold 20 users); sequential on Windows PowerShell 5.1.
- Retry + exponential backoff + jitter on transient API failures
  (HTTP 429 / 5xx); honours Retry-After.
- CSV output with optional -IncludeSourceUsers column.

Also adds Utils/README.md documenting the new folder and script.
Replaces the upfront Get-ZNUser pagination with per-user resolves via
GET /users/searchIdByPrincipalName?principalName=DOMAIN\user (and
searchIdBySid for the activity-scan fallback). This scales to tenants
with 100k+ users where the directory pre-fetch would be slow and
mostly wasted work. HTTP 404 from the resolver is treated as
"not a ZN user" (system/machine/unknown) and skipped silently.

Other changes:
- Fuse resolve + group-membership fetch into one per-user unit of
  work, so each parallel runspace does both API calls.
- Raise -MaxParallel ceiling from 16 to 64 for very large destinations
  (default still 8, threshold still 20 source users).
- Streaming progress with live ETA / rate as each result lands.
- 404 short-circuits the retry loop (only transient errors retried).

Updates Utils/README.md to match.
@dicolanl dicolanl merged commit 777047a into zeronetworks:master Jun 18, 2026
1 check failed
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.

2 participants