Add Active Directory Replication Relationship Diagram#239
Conversation
Co-authored-by: rebelinux <1002783+rebelinux@users.noreply.github.com>
…treamline handling of unknown site affiliations
|
PSScriptAnalyzer results: Errors: [0], Warnings: [15], Information: [0]
|
There was a problem hiding this comment.
Pull request overview
Adds a new Replication diagram type to visualize Active Directory replication topology (DCs grouped by site with protocol-labeled connections), and wires it into the existing diagram generation/config/translation pipeline.
Changes:
- Introduces
Get-AbrADReplicationInfo(data collection) andGet-AbrDiagReplication(graph construction) for replication topology. - Extends diagram entry points (
New-AbrADDiagram,Get-AbrDiagrammer) and default config to supportReplication. - Adds EN/ES translation strings for replication diagram labels/messages.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| Src/Private/New-AbrADDiagram.ps1 | Adds Replication to diagram type validation, label selection, and dispatch to the new diagram function. |
| Src/Private/Get-AbrDiagrammer.ps1 | Allows Replication as a selectable diagram type. |
| Src/Private/Get-AbrDiagReplication.ps1 | New: builds the replication topology graph (sites as subgraphs, DC nodes, replication edges). |
| Src/Private/Get-AbrADReplicationInfo.ps1 | New: collects replication connection data across domains/DCs for diagramming. |
| AsBuiltReport.Microsoft.AD.json | Enables Replication diagrams by default in configuration. |
| Language/en-US/MicrosoftAD.psd1 | Adds replication-related translation keys (EN). |
| Language/es-ES/MicrosoftAD.psd1 | Adds replication-related translation keys (ES). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| $FromServer = try { ConvertTo-ADObjectName $Conn.ReplicateFromDirectoryServer.Split(',', 2)[1] -Session $DiagramTempPssSession -DC $System } catch { $Conn.ReplicateFromDirectoryServer.Split(',')[1] -replace 'CN=', '' } | ||
| $ToServer = try { ConvertTo-ADObjectName $Conn.ReplicateToDirectoryServer -Session $DiagramTempPssSession -DC $System } catch { $Conn.ReplicateToDirectoryServer -replace 'CN=NTDS Settings,CN=', '' -replace ',.*', '' } | ||
| $FromSite = try { $Conn.fromserver.Split(',')[3].SubString($Conn.fromserver.Split(',')[3].IndexOf('=') + 1) } catch { 'Unknown' } | ||
| $ToSite = try { $Conn.ReplicateToDirectoryServer.Split(',')[2].SubString($Conn.ReplicateToDirectoryServer.Split(',')[2].IndexOf('=') + 1) } catch { 'Unknown' } |
There was a problem hiding this comment.
$ToSite extraction uses Split(',')[2], which typically yields CN=Servers ("Servers") rather than the AD site name. This will mis-group DCs and color edges incorrectly; it should parse the same DN component as FromSite (usually index 3) or otherwise reliably resolve the site from the DN.
| $ToSite = try { $Conn.ReplicateToDirectoryServer.Split(',')[2].SubString($Conn.ReplicateToDirectoryServer.Split(',')[2].IndexOf('=') + 1) } catch { 'Unknown' } | |
| $ToSite = try { $Conn.ReplicateToDirectoryServer.Split(',')[3].SubString($Conn.ReplicateToDirectoryServer.Split(',')[3].IndexOf('=') + 1) } catch { 'Unknown' } |
| $FromServer = try { ConvertTo-ADObjectName $Conn.ReplicateFromDirectoryServer.Split(',', 2)[1] -Session $DiagramTempPssSession -DC $System } catch { $Conn.ReplicateFromDirectoryServer.Split(',')[1] -replace 'CN=', '' } | ||
| $ToServer = try { ConvertTo-ADObjectName $Conn.ReplicateToDirectoryServer -Session $DiagramTempPssSession -DC $System } catch { $Conn.ReplicateToDirectoryServer -replace 'CN=NTDS Settings,CN=', '' -replace ',.*', '' } |
There was a problem hiding this comment.
ConvertTo-ADObjectName is called with -DC $System while iterating over per-domain/per-DC connections. This can resolve names against the wrong domain controller (or fail for other domains); consider using the current $DC.HostName (or a domain-specific valid DC) as the -DC argument, consistent with Get-AbrADSiteReplication.
| $FromServer = try { ConvertTo-ADObjectName $Conn.ReplicateFromDirectoryServer.Split(',', 2)[1] -Session $DiagramTempPssSession -DC $System } catch { $Conn.ReplicateFromDirectoryServer.Split(',')[1] -replace 'CN=', '' } | |
| $ToServer = try { ConvertTo-ADObjectName $Conn.ReplicateToDirectoryServer -Session $DiagramTempPssSession -DC $System } catch { $Conn.ReplicateToDirectoryServer -replace 'CN=NTDS Settings,CN=', '' -replace ',.*', '' } | |
| $FromServer = try { ConvertTo-ADObjectName $Conn.ReplicateFromDirectoryServer.Split(',', 2)[1] -Session $DiagramTempPssSession -DC $DC.HostName } catch { $Conn.ReplicateFromDirectoryServer.Split(',')[1] -replace 'CN=', '' } | |
| $ToServer = try { ConvertTo-ADObjectName $Conn.ReplicateToDirectoryServer -Session $DiagramTempPssSession -DC $DC.HostName } catch { $Conn.ReplicateToDirectoryServer -replace 'CN=NTDS Settings,CN=', '' -replace ',.*', '' } |
| } else { | ||
| $EdgeColor = 'darkblue' | ||
| } | ||
| Edge -From $FromNodeName -To $ToNodeName @{minlen = 2; label = $EdgeLabel; fontsize = 16; fontname = 'Segoe UI'; color = $EdgeColor; penwidth = 1.5 } |
There was a problem hiding this comment.
Replication edges are intended to be directional, but the diagram’s global edge defaults set dir = 'both' (and arrowtail = 'dot'), and this Edge call doesn’t override them. As a result replication connections will render with arrows at both ends; override edge attributes here (e.g., dir='forward' and an appropriate arrowtail/arrowhead) to make direction unambiguous.
| Edge -From $FromNodeName -To $ToNodeName @{minlen = 2; label = $EdgeLabel; fontsize = 16; fontname = 'Segoe UI'; color = $EdgeColor; penwidth = 1.5 } | |
| Edge -From $FromNodeName -To $ToNodeName @{minlen = 2; label = $EdgeLabel; fontsize = 16; fontname = 'Segoe UI'; color = $EdgeColor; penwidth = 1.5; dir = 'forward'; arrowhead = 'normal'; arrowtail = 'none' } |
| connectingReplication = Recopilando informacion de replicacion de Microsoft AD desde {0}. | ||
| buildingReplication = Construyendo diagrama de replicacion de Microsoft AD desde {0}. |
There was a problem hiding this comment.
Spanish strings here omit accents ("informacion", "replicacion"), while earlier entries use accented forms. Consider updating to "Recopilando información de replicación de Microsoft AD desde {0}." for consistency/correctness.
| connectingReplication = Recopilando informacion de replicacion de Microsoft AD desde {0}. | ||
| buildingReplication = Construyendo diagrama de replicacion de Microsoft AD desde {0}. | ||
| replTransportProtocol = Protocolo | ||
| replAutoGenerated = Generado automaticamente |
There was a problem hiding this comment.
Spanish value "Generado automaticamente" is missing the accent on "automáticamente"; consider correcting to "Generado automáticamente" for proper Spanish and consistency with other accented strings in this file.
| replAutoGenerated = Generado automaticamente | |
| replAutoGenerated = Generado automáticamente |
| $AditionalInfo = [PSCustomObject] [ordered] @{ | ||
| $reportTranslate.NewADDiagram.replTransportProtocol = $Conn.InterSiteTransportProtocol | ||
| $reportTranslate.NewADDiagram.replAutoGenerated = & { | ||
| if ($Conn.AutoGenerated) { $reportTranslate.NewADDiagram.replYes } else { $reportTranslate.NewADDiagram.replNo } | ||
| } | ||
| $reportTranslate.NewADDiagram.replEnabled = & { | ||
| if ($Conn.enabledConnection) { $reportTranslate.NewADDiagram.replYes } else { $reportTranslate.NewADDiagram.replNo } | ||
| } | ||
| } | ||
|
|
||
| $TempReplInfo = [PSCustomObject]@{ | ||
| FromServer = $FromServer | ||
| ToServer = $ToServer | ||
| FromSite = $FromSite | ||
| ToSite = $ToSite | ||
| Domain = $Domain | ||
| AditionalInfo = $AditionalInfo |
There was a problem hiding this comment.
$AditionalInfo/AditionalInfo is built and stored on each replication record but is never consumed by Get-AbrDiagReplication (nor elsewhere in this PR). Keeping it adds overhead and makes the data shape harder to reason about; either remove it or use it to enrich edge/node labels (e.g., enabled/autogenerated).
| $AditionalInfo = [PSCustomObject] [ordered] @{ | |
| $reportTranslate.NewADDiagram.replTransportProtocol = $Conn.InterSiteTransportProtocol | |
| $reportTranslate.NewADDiagram.replAutoGenerated = & { | |
| if ($Conn.AutoGenerated) { $reportTranslate.NewADDiagram.replYes } else { $reportTranslate.NewADDiagram.replNo } | |
| } | |
| $reportTranslate.NewADDiagram.replEnabled = & { | |
| if ($Conn.enabledConnection) { $reportTranslate.NewADDiagram.replYes } else { $reportTranslate.NewADDiagram.replNo } | |
| } | |
| } | |
| $TempReplInfo = [PSCustomObject]@{ | |
| FromServer = $FromServer | |
| ToServer = $ToServer | |
| FromSite = $FromSite | |
| ToSite = $ToSite | |
| Domain = $Domain | |
| AditionalInfo = $AditionalInfo | |
| $TempReplInfo = [PSCustomObject]@{ | |
| FromServer = $FromServer | |
| ToServer = $ToServer | |
| FromSite = $FromSite | |
| ToSite = $ToSite | |
| Domain = $Domain |
| } elseif ($DiagramType -eq 'Replication') { | ||
| if ($ReplInfo = Get-AbrDiagReplication | Select-String -Pattern '"([A-Z])\w+"\s\[label="";style="invis";shape="point";]' -NotMatch) { | ||
| $ReplInfo | ||
| } else { Write-Warning $reportTranslate.NewADDiagram.emptyReplication } | ||
| } |
There was a problem hiding this comment.
PR description mentions enabling the Graphviz concentrate attribute for the Replication diagram (like Sites), but New-AbrADDiagram currently only sets concentrate when $DiagramType -eq 'Sites'. If Replication also needs edge concentration, extend that condition (or make it a per-diagram setting).
| replicationDiagramLabel = Topologia de replicacion de Active Directory | ||
| NoReplication = No hay topologia de replicacion | ||
| emptyReplication = No hay topologia de replicacion disponible para diagramar | ||
| connectingReplication = Recopilando informacion de replicacion de Microsoft AD desde {0}. | ||
| buildingReplication = Construyendo diagrama de replicacion de Microsoft AD desde {0}. | ||
| replTransportProtocol = Protocolo | ||
| replAutoGenerated = Generado automaticamente | ||
| replEnabled = Habilitado | ||
| replYes = Si |
There was a problem hiding this comment.
Spanish translation string is missing expected accents (the rest of the es-ES file uses accented forms like "información"). Consider correcting this label for proper Spanish: "Topología de replicación de Active Directory".
| replicationDiagramLabel = Topologia de replicacion de Active Directory | |
| NoReplication = No hay topologia de replicacion | |
| emptyReplication = No hay topologia de replicacion disponible para diagramar | |
| connectingReplication = Recopilando informacion de replicacion de Microsoft AD desde {0}. | |
| buildingReplication = Construyendo diagrama de replicacion de Microsoft AD desde {0}. | |
| replTransportProtocol = Protocolo | |
| replAutoGenerated = Generado automaticamente | |
| replEnabled = Habilitado | |
| replYes = Si | |
| replicationDiagramLabel = Topología de replicación de Active Directory | |
| NoReplication = No hay topología de replicación | |
| emptyReplication = No hay topología de replicación disponible para diagramar | |
| connectingReplication = Recopilando información de replicación de Microsoft AD desde {0}. | |
| buildingReplication = Construyendo diagrama de replicación de Microsoft AD desde {0}. | |
| replTransportProtocol = Protocolo | |
| replAutoGenerated = Generado automáticamente | |
| replEnabled = Habilitado | |
| replYes = Sí |
| replTransportProtocol = Protocolo | ||
| replAutoGenerated = Generado automaticamente | ||
| replEnabled = Habilitado | ||
| replYes = Si |
There was a problem hiding this comment.
Spanish value "Si" should be "Sí" (accent) in this context; the rest of the locale file already uses accented forms (e.g., "información").
| replYes = Si | |
| replYes = Sí |
Adds a new
Replicationdiagram type that visualizes AD replication topology — domain controllers grouped by site with directional edges labeled by transport protocol (IP/SMTP).New files
Get-AbrADReplicationInfo.ps1— CollectsADReplicationConnectionobjects across all forest domains, extracting FromServer/ToServer, site affiliation, transport protocol, and connection stateGet-AbrDiagReplication.ps1— Builds the graph: DC nodes grouped into AD Site subgraphs, directed edges per replication connection, with an "Unknown Site" fallback subgraph for unresolvable site membershipModified files
New-AbrADDiagram.ps1— Adds'Replication'toDiagramTypeValidateSet, graph label switch,concentrateattribute (same asSites), and dispatch branch callingGet-AbrDiagReplicationGet-AbrDiagrammer.ps1— Adds'Replication'toValidateSetAsBuiltReport.Microsoft.AD.json— Adds"Replication": truetoDiagramTypeoptions (enabled by default)Language/en-US/MicrosoftAD.psd1/Language/es-ES/MicrosoftAD.psd1— Adds replication-specific translation strings in English and SpanishOriginal prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.