Src/Private/Get-DiagBackupToProtectedGroup.ps1

function Get-DiagBackupToProtectedGroup {
    <#
    .SYNOPSIS
        Function to build a Backup Server to Protected Group diagram.
    .DESCRIPTION
        Build a diagram of the configuration of Veeam VBR in PDF/PNG/SVG formats using Psgraph.
    .NOTES
        Version: 0.5.9
        Author: Jonathan Colon
        Twitter: @jcolonfzenpr
        Github: rebelinux
    .LINK
        https://github.com/rebelinux/Veeam.Diagrammer
    #>

    [CmdletBinding()]

    Param
    (

    )

    begin {
        # Get Veeam Backup Server Object
        Get-DiagBackupServer
    }

    process {
        try {
            $ProtectedGroups = Get-VbrBackupProtectedGroupInfo
            $ADContainer = $ProtectedGroups | Where-Object { $_.Container -eq 'ActiveDirectory' }
            $ManualContainer = $ProtectedGroups | Where-Object { $_.Container -eq 'ManuallyDeployed' }
            $IndividualContainer = $ProtectedGroups | Where-Object { $_.Container -eq 'IndividualComputers' }
            $CSVContainer = $ProtectedGroups | Where-Object { $_.Container -eq 'CSV' }

            try {
                $FileBackupProxy = Get-VbrBackupProxyInfo -Type 'nas'
                if ($BackupServerInfo) {
                    if ($Dir -eq 'LR') {
                        $DiagramLabel = 'File Backup Proxies'
                        $DiagramDummyLabel = ' '
                    } else {
                        $DiagramLabel = ' '
                        $DiagramDummyLabel = 'File Backup Proxies'
                    }
                    if ($FileBackupProxy) {
                        $ProxiesAttr = @{
                            Label = $DiagramLabel
                            fontsize = 18
                            penwidth = 1.5
                            labelloc = 't'
                            color = $SubGraphDebug.color
                            style = 'dashed,rounded'
                        }
                        SubGraph MainSubGraphFileProxy -Attributes $ProxiesAttr -ScriptBlock {
                            # Dummy Node used for subgraph centering
                            Node DummyFileProxy @{Label = $DiagramDummyLabel; fontsize = 18; fontname = "Segoe Ui Black"; fontcolor = '#005f4b'; shape = 'plain' }
                            Node DummyFileProxyToPG @{Label = "DummyFileProxyToPG"; style = $EdgeDebug.style; color = $EdgeDebug.color; shape = 'plain'; fillColor = 'transparent' }
                            if ($Dir -eq "TB") {
                                Node FileLeft @{Label = 'FileLeft'; style = $EdgeDebug.style; color = $EdgeDebug.color; shape = 'plain'; fillColor = 'transparent' }
                                Node FileLeftt @{Label = 'FileLeftt'; style = $EdgeDebug.style; color = $EdgeDebug.color; shape = 'plain'; fillColor = 'transparent' }
                                Node FileRight @{Label = 'FileRight'; style = $EdgeDebug.style; color = $EdgeDebug.color; shape = 'plain'; fillColor = 'transparent' }
                                Edge FileLeft, FileLeftt, DummyFileProxy, FileRight @{style = $EdgeDebug.style; color = $EdgeDebug.color }
                                Rank FileLeft, FileLeftt, DummyFileProxy, FileRight
                            }
                            foreach ($ProxyObj in $FileBackupProxy) {
                                $PROXYHASHTABLE = @{}
                                $ProxyObj.psobject.properties | ForEach-Object { $PROXYHASHTABLE[$_.Name] = $_.Value }
                                Node $ProxyObj -NodeScript { $_.Name } @{Label = $PROXYHASHTABLE.Label; fontname = "Segoe Ui" }
                                Edge -From DummyFileProxy -To $ProxyObj.Name @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color }
                                Edge -From $ProxyObj.Name -To DummyFileProxyToPG @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color }

                            }
                            Rank $FileBackupProxy.Name
                        }

                        if ($Dir -eq 'LR') {
                            Edge $BackupServerInfo.Name -To DummyFileProxy @{minlen = 3; }
                        } else {
                            Edge $BackupServerInfo.Name -To DummyFileProxy @{minlen = 3; }
                        }
                    }
                }
            } catch {
                $_
            }

            if ($ProtectedGroups) {
                if ($Dir -eq 'LR') {
                    $DiagramLabel = 'Protected Groups'
                    $DiagramDummyLabel = ' '
                } else {
                    $DiagramLabel = ' '
                    $DiagramDummyLabel = 'Protected Groups'
                }

                if ($ProtectedGroups) {
                    SubGraph MainSubGraph -Attributes @{Label = $DiagramLabel; fontsize = 22; penwidth = 1; labelloc = 't'; style = 'dashed,rounded'; color = $SubGraphDebug.color } {
                        # Node used for subgraph centering
                        Node ProtectedGroup @{Label = $DiagramDummyLabel; fontsize = 22; fontname = "Segoe Ui Black"; fontcolor = '#005f4b'; shape = 'plain' }
                        if ($Dir -eq "TB") {
                            Node DummyPGLeft @{Label = 'DummyPGLeft'; style = $EdgeDebug.style; color = $EdgeDebug.color; shape = 'plain'; fillColor = 'transparent' }
                            Node DummyPGLeftt @{Label = 'DummyPGLeftt'; style = $EdgeDebug.style; color = $EdgeDebug.color; shape = 'plain'; fillColor = 'transparent' }
                            Node DummyPGRight @{Label = 'DummyPGRight'; style = $EdgeDebug.style; color = $EdgeDebug.color; shape = 'plain'; fillColor = 'transparent' }
                            Edge DummyPGLeft, DummyPGLeftt, ProtectedGroup, DummyPGRight @{style = $EdgeDebug.style; color = $EdgeDebug.color }
                            Rank DummyPGLeft, DummyPGLeftt, ProtectedGroup, DummyPGRight
                        }
                        if ($ADContainer) {
                            SubGraph ADContainer -Attributes @{Label = (Get-HTMLLabel -Label 'Active Directory Computers' -IconType "VBR_AGENT_AD_Logo" -SubgraphLabel); fontsize = 18; penwidth = 1.5; labelloc = 't'; style = 'dashed,rounded' } {
                                # Node used for subgraph centering
                                Node DummyADContainer @{Label = 'DummyADC'; style = $SubGraphDebug.style; color = $SubGraphDebug.color; shape = 'plain' }
                                if ($ADContainer.count -le 2) {
                                    foreach ($PGOBJ in ($ADContainer | Sort-Object -Property Name)) {
                                        $PGHASHTABLE = @{}
                                        $PGOBJ.psobject.properties | ForEach-Object { $PGHASHTABLE[$_.Name] = $_.Value }

                                        $Ous = @()

                                        $Status = Switch ($PGOBJ.Object.Enabled) {
                                            $true { 'Enabled' }
                                            $false { 'Disabled' }
                                            default { 'Unknown' }
                                        }

                                        $Ous += $PGOBJ.Object.Container.Entity | ForEach-Object {
                                            "<B>OUs</B> : $($_.DistinguishedName)"
                                        }
                                        $Rows = @(
                                            "<B>Type</B>: $($PGOBJ.Object.Type) <B>Status</B>: $($Status) <B>Schedule</B>: $($PGOBJ.Object.ScheduleOptions.PolicyType)"
                                            "<B>Domain</B> : $($PGOBJ.Object.Container.Domain) <B>Distribution Server</B> : $($PGOBJ.Object.DeploymentOptions.DistributionServer.Name)"
                                            $Ous
                                        )

                                        Convert-TableToHTML -Label $PGOBJ.Name -Name $PGOBJ.Name -Row $Rows -HeaderColor "#005f4b" -HeaderFontColor "white" -BorderColor "black" -FontSize 14

                                        Edge -From DummyADContainer -To $PGOBJ.Name @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color }
                                    }
                                } else {
                                    $Group = Split-Array -inArray ($ADContainer | Sort-Object -Property Name) -size 2
                                    $Number = 0
                                    while ($Number -ne $Group.Length) {
                                        $Random = Get-Random
                                        SubGraph "ADGroup$($Number)_$Random" -Attributes @{Label = ' '; style = $SubGraphDebug.style; color = $SubGraphDebug.color; fontsize = 18; penwidth = 1 } {
                                            $Group[$Number] | ForEach-Object {
                                                $PGHASHTABLE = @{}
                                                $_.psobject.properties | ForEach-Object { $PGHASHTABLE[$_.Name] = $_.Value }

                                                $Status = Switch ($_.Object.Enabled) {
                                                    $true { 'Enabled' }
                                                    $false { 'Disabled' }
                                                    default { 'Unknown' }
                                                }

                                                $Ous = @()
                                                $Ous += $_.Object.Container.Entity | ForEach-Object {
                                                    "<B>OUs</B> : $($_.DistinguishedName)"
                                                }
                                                $Rows = @(
                                                    "<B>Type</B>: $($_.Object.Type) <B>Status</B>: $($Status) <B>Schedule</B>: $($_.Object.ScheduleOptions.PolicyType)"
                                                    "<B>Domain</B> : $($_.Object.Container.Domain) <B>Distribution Server</B> : $($_.Object.DeploymentOptions.DistributionServer.Name)"
                                                    $Ous
                                                )

                                                Convert-TableToHTML -Label $_.Name -Name $_.Name -Row $Rows -HeaderColor "#005f4b" -HeaderFontColor "white" -BorderColor "black" -FontSize 14
                                            }
                                        }
                                        $Number++
                                    }

                                    Edge -From DummyADContainer -To $Group[0].Name @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color }
                                    $Start = 0
                                    $LocalPGNum = 1
                                    while ($LocalPGNum -ne $Group.Length) {
                                        Edge -From $Group[$Start].Name -To $Group[$LocalPGNum].Name @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color }
                                        $Start++
                                        $LocalPGNum++
                                    }
                                }
                            }
                            Edge -From ProtectedGroup -To DummyADContainer @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color }
                        }
                        if ($ManualContainer) {
                            SubGraph MCContainer -Attributes @{Label = (Get-HTMLLabel -Label 'Manual Computers' -IconType "VBR_AGENT_MC" -SubgraphLabel); fontsize = 18; penwidth = 1.5; labelloc = 't'; style = 'dashed,rounded' } {
                                # Node used for subgraph centering
                                Node DummyMCContainer @{Label = 'DummyMC'; style = $SubGraphDebug.style; color = $SubGraphDebug.color; shape = 'plain' }
                                if ($ManualContainer.count -le 2) {
                                    foreach ($PGOBJ in ($ManualContainer | Sort-Object -Property Name)) {
                                        $PGHASHTABLE = @{}
                                        $PGOBJ.psobject.properties | ForEach-Object { $PGHASHTABLE[$_.Name] = $_.Value }

                                        $Status = Switch ($PGOBJ.Enabled) {
                                            $true { 'Enabled' }
                                            $false { 'Disabled' }
                                            default { 'Unknown' }
                                        }

                                        $Rows = @(
                                            "<B>Type</B>: $($PGOBJ.Object.Type) <B>Status</B>: $($Status) <B>Schedule</B>: $($PGOBJ.Object.ScheduleOptions.PolicyType)"
                                        )

                                        Convert-TableToHTML -Label $PGOBJ.Name -Name $PGOBJ.Name -Row $Rows -HeaderColor "#005f4b" -HeaderFontColor "white" -BorderColor "black" -FontSize 14

                                        Edge -From DummyMCContainer -To $PGOBJ.Name @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color }
                                    }

                                } else {
                                    $Group = Split-Array -inArray ($ManualContainer | Sort-Object -Property Name) -size 2
                                    $Number = 0
                                    while ($Number -ne $Group.Length) {
                                        $Random = Get-Random
                                        SubGraph "MCGroup$($Number)_$Random" -Attributes @{Label = ' '; style = $SubGraphDebug.style; color = $SubGraphDebug.color; fontsize = 18; penwidth = 1 } {
                                            $Group[$Number] | ForEach-Object {
                                                $PGHASHTABLE = @{}
                                                $_.psobject.properties | ForEach-Object { $PGHASHTABLE[$_.Name] = $_.Value }

                                                $Status = Switch ($_.Object.Enabled) {
                                                    $true { 'Enabled' }
                                                    $false { 'Disabled' }
                                                    default { 'Unknown' }
                                                }

                                                $Rows = @(
                                                    "<B>Type</B>: $($_.Object.Type) <B>Status</B>: $($Status) <B>Schedule</B>: $($_.Object.ScheduleOptions.PolicyType)"
                                                )

                                                Convert-TableToHTML -Label $_.Name -Name $_.Name -Row $Rows -HeaderColor "#005f4b" -HeaderFontColor "white" -BorderColor "black" -FontSize 14
                                            }
                                        }
                                        $Number++
                                    }

                                    Edge -From DummyMCContainer -To $Group[0].Name @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color }
                                    $Start = 0
                                    $LocalPGNum = 1
                                    while ($LocalPGNum -ne $Group.Length) {
                                        Edge -From $Group[$Start].Name -To $Group[$LocalPGNum].Name @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color }
                                        $Start++
                                        $LocalPGNum++
                                    }
                                }
                            }
                            Edge -From ProtectedGroup -To DummyMCContainer @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color }
                        }
                        if ($IndividualContainer) {
                            SubGraph ICContainer -Attributes @{Label = (Get-HTMLLabel -Label 'Individual Computers' -IconType "VBR_AGENT_IC" -SubgraphLabel); fontsize = 18; penwidth = 1.5; labelloc = 't'; style = 'dashed,rounded' } {
                                # Node used for subgraph centering
                                Node DummyICContainer @{Label = 'DummyIC'; style = $SubGraphDebug.style; color = $SubGraphDebug.color; shape = 'plain' }
                                if ($IndividualContainer.count -le 2) {
                                    foreach ($PGOBJ in ($IndividualContainer | Sort-Object -Property Name)) {
                                        $PGHASHTABLE = @{}
                                        $PGOBJ.psobject.properties | ForEach-Object { $PGHASHTABLE[$_.Name] = $_.Value }

                                        $Status = Switch ($PGOBJ.Enabled) {
                                            $true { 'Enabled' }
                                            $false { 'Disabled' }
                                            default { 'Unknown' }
                                        }


                                        $Entities = @()
                                        $Entities += $PGOBJ.Object.Container.CustomCredentials | ForEach-Object {
                                            "<B>Host Name</B> : $($_.HostName)"
                                        }

                                        $Rows = @(
                                            "<B>Type</B>: $($PGOBJ.Object.Type) <B>Status</B>: $($Status) <B>Schedule</B>: $($PGOBJ.Object.ScheduleOptions.PolicyType)"
                                            "<B>Distribution Server</B> : $($PGOBJ.Object.DeploymentOptions.DistributionServer.Name)"
                                            $Entities
                                        )

                                        Convert-TableToHTML -Label $PGOBJ.Name -Name $PGOBJ.Name -Row $Rows -HeaderColor "#005f4b" -HeaderFontColor "white" -BorderColor "black" -FontSize 14

                                        Edge -From DummyICContainer -To $PGOBJ.Name @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color }
                                    }
                                } else {
                                    $Group = Split-Array -inArray ($IndividualContainer | Sort-Object -Property Name) -size 2
                                    $Number = 0
                                    while ($Number -ne $Group.Length) {
                                        $Random = Get-Random
                                        SubGraph "ICGroup$($Number)_$Random" -Attributes @{Label = ' '; style = $SubGraphDebug.style; color = $SubGraphDebug.color; fontsize = 18; penwidth = 1 } {
                                            $Group[$Number] | ForEach-Object {
                                                $PGHASHTABLE = @{}
                                                $_.psobject.properties | ForEach-Object { $PGHASHTABLE[$_.Name] = $_.Value }

                                                $Status = Switch ($_.Object.Enabled) {
                                                    $true { 'Enabled' }
                                                    $false { 'Disabled' }
                                                    default { 'Unknown' }
                                                }

                                                $Entities = @()
                                                $Entities += $_.Object.Container.CustomCredentials | ForEach-Object {
                                                    "$($_.HostName)<br />"
                                                }

                                                $Rows = @(
                                                    "<B>Type</B>: $($_.Object.Type) <B>Status</B>: $($Status) <B>Schedule</B>: $($_.Object.ScheduleOptions.PolicyType)"
                                                    "<B>Distribution Server</B> : $($_.Object.DeploymentOptions.DistributionServer.Name)"
                                                    "<B>Host Name</B>:
                                                    <br /> $Entities"

                                                )

                                                Convert-TableToHTML -Label $_.Name -Name $_.Name -Row $Rows -HeaderColor "#005f4b" -HeaderFontColor "white" -BorderColor "black" -FontSize 14
                                            }
                                        }
                                        $Number++
                                    }

                                    Edge -From DummyICContainer -To $Group[0].Name @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color }
                                    $Start = 0
                                    $LocalPGNum = 1
                                    while ($LocalPGNum -ne $Group.Length) {
                                        Edge -From $Group[$Start].Name -To $Group[$LocalPGNum].Name @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color }
                                        $Start++
                                        $LocalPGNum++
                                    }
                                }
                            }
                            Edge -From ProtectedGroup -To DummyICContainer @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color }
                        }
                        if ($CSVContainer) {
                            SubGraph CSVContainer -Attributes @{Label = (Get-HTMLLabel -Label 'CSV Computers' -IconType "VBR_AGENT_CSV_Logo" -SubgraphLabel); fontsize = 18; penwidth = 1.5; labelloc = 't'; style = 'dashed,rounded' } {
                                # Node used for subgraph centering
                                Node DummyCSVContainer @{Label = 'DummyCSVC'; style = $SubGraphDebug.style; color = $SubGraphDebug.color; shape = 'plain' }
                                if ($CSVContainer.count -le 2) {
                                    foreach ($PGOBJ in ($CSVContainer | Sort-Object -Property Name)) {
                                        $PGHASHTABLE = @{}
                                        $PGOBJ.psobject.properties | ForEach-Object { $PGHASHTABLE[$_.Name] = $_.Value }
                                        $Rows = @(
                                            "<B>Type</B>: $($PGOBJ.Object.Type) <B>Status</B>: $($Status) <B>Schedule</B>: $($PGOBJ.Object.ScheduleOptions.PolicyType)"
                                            "<B>Distribution Server</B> : $($PGOBJ.Object.DeploymentOptions.DistributionServer.Name)"
                                            "<B>CSV File</B> : $($PGOBJ.Object.Container.Path)"
                                            "<B>Credential</B> : $($PGOBJ.Object.Container.MasterCredentials.Name)"
                                        )

                                        Convert-TableToHTML -Label $PGOBJ.Name -Name $PGOBJ.Name -Row $Rows -HeaderColor "#005f4b" -HeaderFontColor "white" -BorderColor "black" -FontSize 14

                                        Edge -From DummyCSVContainer -To $PGOBJ.Name @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color }
                                    }

                                } else {
                                    $Group = Split-Array -inArray ($CSVContainer | Sort-Object -Property Name) -size 2
                                    $Number = 0
                                    while ($Number -ne $Group.Length) {
                                        $Random = Get-Random
                                        SubGraph "CSVGroup$($Number)_$Random" -Attributes @{Label = ' '; style = $SubGraphDebug.style; color = $SubGraphDebug.color; fontsize = 18; penwidth = 1 } {
                                            $Group[$Number] | ForEach-Object {
                                                $PGHASHTABLE = @{}
                                                $_.psobject.properties | ForEach-Object { $PGHASHTABLE[$_.Name] = $_.Value }
                                                $Rows = @(
                                                    "<B>Type</B>: $($_.Object.Type) <B>Status</B>: $($Status) <B>Schedule</B>: $($_.Object.ScheduleOptions.PolicyType)"
                                                    "<B>Distribution Server</B> : $($_.Object.DeploymentOptions.DistributionServer.Name)"
                                                    "<B>CSV File</B> : $($_.Object.Container.Path)"
                                                    "<B>Credential</B> : $($_.Object.Container.MasterCredentials.Name)"
                                                )

                                                Convert-TableToHTML -Label $_.Name -Name $_.Name -Row $Rows -HeaderColor "#005f4b" -HeaderFontColor "white" -BorderColor "black" -FontSize 14
                                            }
                                        }
                                        $Number++
                                    }

                                    Edge -From DummyCSVContainer -To $Group[0].Name @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color }
                                    $Start = 0
                                    $LocalPGNum = 1
                                    while ($LocalPGNum -ne $Group.Length) {
                                        Edge -From $Group[$Start].Name -To $Group[$LocalPGNum].Name @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color }
                                        $Start++
                                        $LocalPGNum++
                                    }
                                }
                            }
                            Edge -From ProtectedGroup -To DummyCSVContainer @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color }
                        }
                    }

                    Edge -From DummyFileProxyToPG -To ProtectedGroup @{minlen = 3 }
                }
            }
        } catch {
            $_
        }
    }
    end {}
}