diff --git a/CHANGELOG.md b/CHANGELOG.md index b2612f5..5e1f44e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.6.7] - 2024-09-16 + +### Fixed + +- Fix Backup Server section if Enterprise Manager is collocated with the Backup Server +- Fix a issue in the SOBR diagram if there are multiple CapacityExtend configured +- Fix a issue in the SOBR diagram if there are multiple Extend configured + ## [0.6.6] - 2024-09-12 ### Fixed diff --git a/Src/Private/Get-DiagBackupServer.ps1 b/Src/Private/Get-DiagBackupServer.ps1 index c8b7e25..625ef67 100644 --- a/Src/Private/Get-DiagBackupServer.ps1 +++ b/Src/Private/Get-DiagBackupServer.ps1 @@ -22,7 +22,16 @@ function Get-DiagBackupServer { try { SubGraph BackupServers -Attributes @{Label = 'Management'; labelloc = 'b'; labeljust = "r"; style = "rounded"; bgcolor = "#ceedc4"; fontcolor = '#696969'; fontsize = 14; penwidth = 2 } { SubGraph BackupServer -Attributes @{Label = 'Backup Server'; style = "rounded"; bgcolor = "#ceedc4"; fontsize = 18; fontcolor = '#005f4b'; penwidth = 0; labelloc = 't'; labeljust = "c"; } { - if (($DatabaseServerInfo.Name -ne $BackupServerInfo.Name) -and $EMServerInfo) { + if (( -Not $DatabaseServerInfo.Name ) -and ( -Not $EMServerInfo.Name )) { + Write-Verbose -Message "Collecting Backup Server Information." + $BSHASHTABLE = @{} + $BackupServerInfo.psobject.properties | ForEach-Object { $BSHASHTABLE[$_.Name] = $_.Value } + Node Left @{Label = 'Left'; style = $EdgeDebug.style; color = $EdgeDebug.color; shape = 'plain'; fillColor = 'transparent' } + Node Right @{Label = 'Right'; style = $EdgeDebug.style; color = $EdgeDebug.color; shape = 'plain'; fillColor = 'transparent' } + Node $BackupServerInfo.Name -Attributes @{Label = $BSHASHTABLE.Label; fillColor = '#ceedc4'; shape = 'plain' } + Edge Left, $BackupServerInfo.Name, Right @{style = $EdgeDebug.style; color = $EdgeDebug.color } + Rank Left, $BackupServerInfo.Name, Right + } elseif (($DatabaseServerInfo.Name -ne $BackupServerInfo.Name) -and ($EMServerInfo.Name -ne $BackupServerInfo.Name )) { Write-Verbose -Message "Collecting Backup Server, Database Server and Enterprise Manager Information." $BSHASHTABLE = @{} $DBHASHTABLE = @{} @@ -63,6 +72,38 @@ function Get-DiagBackupServer { Rank $BackupServerInfo.Name, $DatabaseServerInfo.Name Edge -From $BackupServerInfo.Name -To $DatabaseServerInfo.Name @{arrowtail = "normal"; arrowhead = "normal"; minlen = 3; xlabel = $DatabaseServerInfo.DBPort } } + } elseif (($EMServerInfo.Name -eq $BackupServerInfo.Name) -and ($DatabaseServerInfo.Name -eq $BackupServerInfo.Name)) { + Write-Verbose -Message "Database and Enterprise Maneger server colocated with Backup Server: Collecting Backup Server and Enterprise Manager Information." + $BSHASHTABLE = @{} + + $BackupServerInfo.psobject.properties | ForEach-Object { $BSHASHTABLE[$_.Name] = $_.Value } + + Node $BackupServerInfo.Name -Attributes @{Label = $BSHASHTABLE.Label; fillColor = '#ceedc4'; shape = 'plain' } + + Node Left @{Label = 'Left'; style = $EdgeDebug.style; color = $EdgeDebug.color; shape = 'plain'; fillColor = 'transparent' } + Node Right @{Label = 'Right'; style = $EdgeDebug.style; color = $EdgeDebug.color; shape = 'plain'; fillColor = 'transparent' } + Edge Left, $BackupServerInfo.Name, Right @{style = $EdgeDebug.style; color = $EdgeDebug.color } + Rank Left, $BackupServerInfo.Name, Right + + } elseif (($EMServerInfo.Name -eq $BackupServerInfo.Name) -and ($DatabaseServerInfo.Name -ne $BackupServerInfo.Name)) { + Write-Verbose -Message "Enterprise Maneger server colocated with Backup Server: Collecting Backup Server and Enterprise Manager Information." + $BSHASHTABLE = @{} + $DBHASHTABLE = @{} + + $BackupServerInfo.psobject.properties | ForEach-Object { $BSHASHTABLE[$_.Name] = $_.Value } + $DatabaseServerInfo.psobject.properties | ForEach-Object { $DBHASHTABLE[$_.Name] = $_.Value } + + Node $BackupServerInfo.Name -Attributes @{Label = $BSHASHTABLE.Label; fillColor = '#ceedc4'; shape = 'plain' } + Node $DatabaseServerInfo.Name -Attributes @{Label = $DBHASHTABLE.Label; fillColor = '#ceedc4'; shape = 'plain' } + + if ($Dir -eq 'LR') { + Rank $BackupServerInfo.Name, $DatabaseServerInfo.Name + Edge -From $DatabaseServerInfo.Name -To $BackupServerInfo.Name @{arrowtail = "normal"; arrowhead = "normal"; minlen = 3; xlabel = $DatabaseServerInfo.DBPort } + } else { + Rank $BackupServerInfo.Name, $DatabaseServerInfo.Name + Edge -From $BackupServerInfo.Name -To $DatabaseServerInfo.Name @{arrowtail = "normal"; arrowhead = "normal"; minlen = 3; xlabel = $DatabaseServerInfo.DBPort } + } + } elseif ($EMServerInfo -and ($DatabaseServerInfo.Name -eq $BackupServerInfo.Name)) { Write-Verbose -Message "Database server colocated with Backup Server: Collecting Backup Server and Enterprise Manager Information." $BSHASHTABLE = @{} @@ -82,15 +123,14 @@ function Get-DiagBackupServer { Edge -From $BackupServerInfo.Name -To $EMServerInfo.Name @{arrowtail = "normal"; arrowhead = "normal"; minlen = 3; } } } else { - Write-Verbose -Message "Database server colocated with Backup Server and no Enterprise Manager found: Collecting Backup Server Information." + Write-Verbose -Message "Collecting Backup Server Information." $BSHASHTABLE = @{} $BackupServerInfo.psobject.properties | ForEach-Object { $BSHASHTABLE[$_.Name] = $_.Value } Node Left @{Label = 'Left'; style = $EdgeDebug.style; color = $EdgeDebug.color; shape = 'plain'; fillColor = 'transparent' } - Node Leftt @{Label = 'Leftt'; style = $EdgeDebug.style; color = $EdgeDebug.color; shape = 'plain'; fillColor = 'transparent' } Node Right @{Label = 'Right'; style = $EdgeDebug.style; color = $EdgeDebug.color; shape = 'plain'; fillColor = 'transparent' } Node $BackupServerInfo.Name -Attributes @{Label = $BSHASHTABLE.Label; fillColor = '#ceedc4'; shape = 'plain' } - Edge Left, Leftt, $BackupServerInfo.Name, Right @{style = $EdgeDebug.style; color = $EdgeDebug.color } - Rank Left, Leftt, $BackupServerInfo.Name, Right + Edge Left, $BackupServerInfo.Name, Right @{style = $EdgeDebug.style; color = $EdgeDebug.color } + Rank Left, $BackupServerInfo.Name, Right } } } diff --git a/Src/Private/Get-DiagBackupToSobr.ps1 b/Src/Private/Get-DiagBackupToSobr.ps1 index 80e52db..4dc9ce5 100644 --- a/Src/Private/Get-DiagBackupToSobr.ps1 +++ b/Src/Private/Get-DiagBackupToSobr.ps1 @@ -34,19 +34,17 @@ function Get-DiagBackupToSobr { foreach ($SOBROBJ in $SobrRepo) { $SubGraphName = Remove-SpecialChar -String $SOBROBJ.Name -SpecialChars '\- ' SubGraph $SubGraphName -Attributes @{Label = $SOBROBJ.Name; fontsize = 18; penwidth = 1.5; labelloc = 't'; style = 'dashed,rounded' } { - $SOBRHASHTABLE = @{} - $SOBROBJ.psobject.properties | ForEach-Object { $SOBRHASHTABLE[$_.Name] = $_.Value } - Node $SOBROBJ -NodeScript { $_.Name } @{Label = $SOBRHASHTABLE.Label; fontname = "Segoe Ui"; shape = "plain"; } + $SOBROBJ | ForEach-Object { Node $_.Name @{Label = $_.Label; fontname = "Segoe Ui"; shape = "plain"; }} if ($SOBROBJ.Performance) { SubGraph "$($SubGraphName)Performance" -Attributes @{Label = "Performance Extent"; fontsize = 18; penwidth = 1.5; labelloc = 'b'; style = "dashed,rounded"; } { - $SOBROBJ.Performance | ForEach-Object { Node $_.Name @{Label = Get-DiaNodeIcon -Name $_.Name -IconType $_.Icon -Align "Center" -Rows $_.Rows -ImagesObj $Images -IconDebug $IconDebug; fontname = "Segoe Ui"; shape = "plain" } } + $SOBROBJ.Performance | ForEach-Object { Node $_.Name @{Label = Get-DiaNodeIcon -Name $_.Name -IconType $_.IconType -Align "Center" -Rows $_.AditionalInfo -ImagesObj $Images -IconDebug $IconDebug; fontname = "Segoe Ui"; shape = "plain" } } } } if ($SOBROBJ.Capacity) { SubGraph "$($SubGraphName)Capacity" -Attributes @{Label = "Capacity Extent"; fontsize = 18; penwidth = 1.5; labelloc = 'b'; style = "dashed,rounded" } { - $SOBROBJ.Capacity | ForEach-Object { Node $_.Name @{Label = Get-DiaNodeIcon -Name $_.Name -IconType $_.Icon -Align "Center" -Rows $_.Rows -ImagesObj $Images -IconDebug $IconDebug; fontname = "Segoe Ui"; shape = "plain" } } + $SOBROBJ.Capacity | ForEach-Object { Node $_.Name @{Label = Get-DiaNodeIcon -Name $_.Name -IconType $_.IconType -Align "Center" -Rows $_.AditionalInfo -ImagesObj $Images -IconDebug $IconDebug; fontname = "Segoe Ui"; shape = "plain" } } } } if ($SOBROBJ.Archive) { @@ -59,7 +57,11 @@ function Get-DiagBackupToSobr { if ($SOBROBJ.Archive) { $SOBROBJ.Performance | ForEach-Object { Edge -From $SOBROBJ.Name -To $SOBROBJ.Archive.Name, $SOBROBJ.Capacity.Name, $_.Name @{minlen = 2 } } | Select-Object -Unique - } else { $SOBROBJ.Performance | ForEach-Object { Edge -From $SOBROBJ.Name -To $SOBROBJ.Capacity.Name, $_.Name @{minlen = 2 } } | Select-Object -Unique } + } else { + $SOBROBJ.Performance | ForEach-Object { Edge -From $SOBROBJ.Name -To $_.Name @{minlen = 2 } } | Select-Object -Unique + $SOBROBJ.Capacity | ForEach-Object { Edge -From $SOBROBJ.Name -To $_.Name @{minlen = 2 } } | Select-Object -Unique + + } } Edge -From MainSubGraph:s -To $SOBROBJ.Name @{minlen = 1; style = $EdgeDebug.style; color = $EdgeDebug.color } } diff --git a/Src/Private/Get-VbrBackupServerInfo.ps1 b/Src/Private/Get-VbrBackupServerInfo.ps1 index 06cde0d..acce17e 100644 --- a/Src/Private/Get-VbrBackupServerInfo.ps1 +++ b/Src/Private/Get-VbrBackupServerInfo.ps1 @@ -20,8 +20,14 @@ function Get-VbrBackupServerInfo { ) process { try { - $CimSession = New-CimSession $VBRServer.Name -Credential $Credential -Authentication Negotiate - $PssSession = New-PSSession $VBRServer.Name -Credential $Credential -Authentication Negotiate + $CimSession = try { New-CimSession $VBRServer.Name -Credential $Credential -Authentication Negotiate -Name 'CIMBackupServerDiagram' -ErrorAction Stop } catch { Write-Verbose "Backup Server Section: New-CimSession: Unable to connect to $($VBRServer.Name): $($_.Exception.MessageId)" } + + $PssSession = try { New-PSSession $VBRServer.Name -Credential $Credential -Authentication Negotiate -ErrorAction Stop -Name 'PSSBackupServerDiagram' } catch { + if (-Not $_.Exception.MessageId) { + $ErrorMessage = $_.FullyQualifiedErrorId + } else { $ErrorMessage = $_.Exception.MessageId } + Write-Verbose "Backup Server Section: New-PSSession: Unable to connect to $($VBRServer.Name): $ErrorMessage" + } Write-Verbose -Message "Collecting Backup Server information from $($VBRServer.Name)." try { $VeeamVersion = Invoke-Command -Session $PssSession -ErrorAction SilentlyContinue -ScriptBlock { Get-ChildItem -Recurse HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall | Get-ItemProperty | Where-Object { $_.DisplayName -match 'Veeam Backup & Replication Server' } | Select-Object -Property DisplayVersion } @@ -61,7 +67,7 @@ function Get-VbrBackupServerInfo { $Rows = @{ Role = $Roles - IP = Get-NodeIP -HostName $VBRServer.Name + IP = Get-NodeIP -Hostname $VBRServer.Name } if ($VeeamVersion) { @@ -89,7 +95,7 @@ function Get-VbrBackupServerInfo { } if ($DatabaseServer) { - $DatabaseServerIP = Get-NodeIP -HostName $DatabaseServer + $DatabaseServerIP = Get-NodeIP -Hostname $DatabaseServer $Rows = @{ Role = 'Database Server' @@ -122,7 +128,7 @@ function Get-VbrBackupServerInfo { try { $EMServer = [Veeam.Backup.Core.SBackupOptions]::GetEnterpriseServerInfo() if ($EMServer.ServerName) { - $EMServerIP = Get-NodeIP -HostName $EMServer.ServerName + $EMServerIP = Get-NodeIP -Hostname $EMServer.ServerName $Rows = @{ Role = 'Enterprise Manager Server' diff --git a/Src/Private/Get-VbrBackupSobrInfo.ps1 b/Src/Private/Get-VbrBackupSobrInfo.ps1 index 3e50a17..7b1403d 100644 --- a/Src/Private/Get-VbrBackupSobrInfo.ps1 +++ b/Src/Private/Get-VbrBackupSobrInfo.ps1 @@ -35,53 +35,69 @@ function Get-VbrBackupSobrInfo { $SobrRows.add('Encryption Key', $Sobr.EncryptionKey.Description) } - if ($Sobr.CapacityExtent.Repository.AmazonS3Folder) { - $Folder = $Sobr.CapacityExtent.Repository.AmazonS3Folder - } elseif ($Sobr.CapacityExtent.Repository.AzureBlobFolder) { - $Folder = $Sobr.CapacityExtent.Repository.AzureBlobFolder - } elseif ($Sobr.ArchiveExtent.Repository.AzureBlobFolder) { - $Folder = $Sobr.ArchiveExtent.Repository.AzureBlobFolder - } else { $Folder = 'Unknown' } - + $SobrsExtents = @() foreach ($Extent in $Sobr.Extent) { - $PerformanceRows = [pscustomobject]@{ + $PerformanceRows = @{ 'Path' = $Extent.Repository.FriendlyPath 'Total Space' = "$((($Extent).Repository).GetContainer().CachedTotalSpace.InGigabytes) GB" 'Used Space' = "$((($Extent).Repository).GetContainer().CachedFreeSpace.InGigabytes) GB" } + + $SobrsExtents += [ordered]@{ + Name = Remove-SpecialChar -String $Extent.Name -SpecialChars '\' + IconType = Get-IconType -String $Extent.Repository.Type + AditionalInfo = $PerformanceRows + } } - $SOBRPERFHASHTABLE = @{} - $PerformanceRows.psobject.properties | ForEach-Object { $SOBRPERFHASHTABLE[$_.Name] = $_.Value } + $SobrsCapacityExtents = @() - $CapacityRows = @{ - Type = $Sobr.CapacityExtent.Repository.Type - Folder = "/$($Folder)" - Gateway = & { - if (-Not $Sobr.CapacityExtent.Repository.UseGatewayServer) { - Switch ($Sobr.CapacityExtent.Repository.ConnectionType) { - 'Gateway' { - switch (($Sobr.CapacityExtent.Repository.GatewayServer | Measure-Object).count) { - 0 { "Disable" } - 1 { $Sobr.CapacityExtent.Repository.GatewayServer.Name.Split('.')[0] } - Default { 'Automatic' } + foreach ($CapacityExtent in $Sobr.CapacityExtents) { + if ($CapacityExtent.Repository.AmazonS3Folder) { + $CapacityFolder = $CapacityExtent.Repository.AmazonS3Folder + } elseif ($CapacityExtent.Repository.AzureBlobFolder) { + $CapacityFolder = $CapacityExtent.Repository.AzureBlobFolder + } + + $CapacityRows = @{ + Type = $CapacityExtent.Repository.Type + Folder = "/$($Folder)" + Gateway = & { + if (-Not $CapacityExtent.Repository.UseGatewayServer) { + Switch ($CapacityExtent.Repository.ConnectionType) { + 'Gateway' { + switch (($CapacityExtent.Repository.GatewayServer | Measure-Object).count) { + 0 { "Disable" } + 1 { $CapacityExtent.Repository.GatewayServer.Name.Split('.')[0] } + Default { 'Automatic' } + } } + 'Direct' { 'Direct' } + default { 'Unknown' } + } + } else { + switch (($CapacityExtent.Repository.GatewayServer | Measure-Object).count) { + 0 { "Disable" } + 1 { $CapacityExtent.Repository.GatewayServer.Name.Split('.')[0] } + Default { 'Automatic' } } - 'Direct' { 'Direct' } - default { 'Unknown' } - } - } else { - switch (($Sobr.CapacityExtent.Repository.GatewayServer | Measure-Object).count) { - 0 { "Disable" } - 1 { $Sobr.CapacityExtent.Repository.GatewayServer.Name.Split('.')[0] } - Default { 'Automatic' } } } } + + $SobrsCapacityExtents += [ordered]@{ + Name = Remove-SpecialChar -String $CapacityExtent.Repository.Name -SpecialChars '\' + IconType = Get-IconType -String $CapacityExtent.Repository.Type + AditionalInfo = $CapacityRows + } } + if ($Sobr.ArchiveExtent.Repository.AzureBlobFolder) { + $ArchiveFolder = $Sobr.ArchiveExtent.Repository.AzureBlobFolder + } else { $ArchiveFolder = 'Unknown' } + $ArchiveRows = [ordered]@{ Type = $Sobr.ArchiveExtent.Repository.ArchiveType Gateway = & { @@ -108,19 +124,19 @@ function Get-VbrBackupSobrInfo { } if ($Sobr.ArchiveExtent.Repository.AzureBlobFolder) { - $ArchiveRows.add('Folder', "/$($Folder.Name)") - $ArchiveRows.add('Container', $($Folder.Container)) + $ArchiveRows.add('Folder', "/$($ArchiveFolder.Name)") + $ArchiveRows.add('Container', $($ArchiveFolder.Container)) } $TempSobrInfo = [PSCustomObject]@{ Name = "$($Sobr.Name.toUpper())" Label = Get-DiaNodeIcon -Name "$($Sobr.Name)" -IconType "VBR_SOBR_Repo" -Align "Center" -Rows $SobrRows -ImagesObj $Images -IconDebug $IconDebug - Capacity = $Sobr.CapacityExtent.Repository | Select-Object -Property @{Name = 'Name'; Expression = { Remove-SpecialChar -String $_.Name -SpecialChars '\' } }, @{Name = 'Rows'; Expression = { $CapacityRows } }, @{Name = 'Icon'; Expression = { Get-IconType -String $_.Type } } + Capacity = $SobrsCapacityExtents Archive = $Sobr.ArchiveExtent.Repository | Select-Object -Property @{Name = 'Name'; Expression = { Remove-SpecialChar -String $_.Name -SpecialChars '\' } }, @{Name = 'Rows'; Expression = { $ArchiveRows } }, @{Name = 'Icon'; Expression = { Get-IconType -String $_.ArchiveType } } - Performance = $Sobr.Extent | Select-Object -Property @{Name = 'Name'; Expression = { Remove-SpecialChar -String $_.Name -SpecialChars '\' } }, @{Name = 'Rows'; Expression = { $SOBRPERFHASHTABLE } }, @{Name = 'Icon'; Expression = { Get-IconType -String $_.Repository.Type } } + Performance = $SobrsExtents } $SobrInfo += $TempSobrInfo } diff --git a/Src/Private/Get-VbrDiagramObjects.ps1 b/Src/Private/Get-VbrDiagramObjects.ps1 index 75dcf09..715c5c9 100644 --- a/Src/Private/Get-VbrDiagramObjects.ps1 +++ b/Src/Private/Get-VbrDiagramObjects.ps1 @@ -1,263 +1,3 @@ -function Get-VbrBackupServerObj { - <# - .SYNOPSIS - Function to extract veeam backup & replication server information. - .DESCRIPTION - Build a diagram of the configuration of Veeam VBR in PDF/PNG/SVG formats using Psgraph. - .NOTES - Version: 0.6.5 - Author: Jonathan Colon - Twitter: @jcolonfzenpr - Github: rebelinux - .LINK - https://github.com/rebelinux/Veeam.Diagrammer - #> - [CmdletBinding()] - - Param - ( - - ) - process { - try { - # $CimSession = New-CimSession $VBRServer.Name -Credential $Credential -Authentication Negotiate - # $PssSession = New-PSSession $VBRServer.Name -Credential $Credential -Authentication Negotiate - $CimSession = try { New-CimSession $VBRServer.Name -Credential $Credential -Authentication Negotiate -Name 'CIMBackupServerDiagram' -ErrorAction Stop } catch { Write-Verbose "Backup Server Section: New-CimSession: Unable to connect to $($VBRServer.Name): $($_.Exception.MessageId)" } - - $PssSession = try { New-PSSession $VBRServer.Name -Credential $Credential -Authentication Negotiate -ErrorAction Stop -Name 'PSSBackupServerDiagram' } catch { - if (-Not $_.Exception.MessageId) { - $ErrorMessage = $_.FullyQualifiedErrorId - } else { $ErrorMessage = $_.Exception.MessageId } - Write-Verbose "Backup Server Section: New-PSSession: Unable to connect to $($VBRServer.Name): $ErrorMessage" - } - Write-Verbose "Collecting Backup Server information from $($VBRServer.Name)." - try { - $VeeamVersion = Invoke-Command -Session $PssSession -ErrorAction SilentlyContinue -ScriptBlock { Get-ChildItem -Recurse HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall | Get-ItemProperty | Where-Object { $_.DisplayName -match 'Veeam Backup & Replication Server' } | Select-Object -Property DisplayVersion } - } catch { $_ } - try { - $VeeamDBFlavor = Invoke-Command -Session $PssSession -ErrorAction SilentlyContinue -ScriptBlock { Get-ItemProperty -Path 'HKLM:\SOFTWARE\Veeam\Veeam Backup and Replication\DatabaseConfigurations' } - } catch { $_ } - try { - $VeeamDBInfo12 = Invoke-Command -Session $PssSession -ErrorAction SilentlyContinue -ScriptBlock { Get-ItemProperty -Path "HKLM:\SOFTWARE\Veeam\Veeam Backup and Replication\DatabaseConfigurations\$(($Using:VeeamDBFlavor).SqlActiveConfiguration)" } - } catch { $_ } - try { - $VeeamDBInfo11 = Invoke-Command -Session $PssSession -ErrorAction SilentlyContinue -ScriptBlock { Get-ItemProperty -Path 'HKLM:\SOFTWARE\Veeam\Veeam Backup and Replication' } - } catch { $_ } - - if ($VeeamDBInfo11.SqlServerName) { - $VeeamDBInfo = $VeeamDBInfo11.SqlServerName - } elseif ($VeeamDBInfo12.SqlServerName) { - $VeeamDBInfo = $VeeamDBInfo12.SqlServerName - } elseif ($VeeamDBInfo12.SqlHostName) { - $VeeamDBInfo = Switch ($VeeamDBInfo12.SqlHostName) { - 'localhost' { $VBRServer.Name } - default { $VeeamDBInfo12.SqlHostName } - } - } else { - $VeeamDBInfo = $VBRServer.Name - } - - try { - if ($VBRServer) { - - if ($VeeamDBInfo -eq $VBRServer.Name) { - $Roles = 'Backup and Database' - $DBType = $VeeamDBFlavor.SqlActiveConfiguration - } else { - $Roles = 'Backup Server' - } - - $Rows = @{ - Role = $Roles - IP = Get-NodeIP -Hostname $VBRServer.Name - } - - if ($VeeamVersion) { - $Rows.add('Version', $VeeamVersion.DisplayVersion) - } - - if ($VeeamDBInfo -eq $VBRServer.Name) { - $Rows.add('DB Type', $DBType) - } - - $script:BackupServerInfo = [PSCustomObject]@{ - Name = $VBRServer.Name.split(".")[0] - Label = Get-DiaNodeIcon -Name "$($VBRServer.Name.split(".")[0])" -IconType "VBR_Server" -Align "Center" -Rows $Rows -ImagesObj $Images -IconDebug $IconDebug - } - } - } catch { - $_ - } - try { - $DatabaseServer = $VeeamDBInfo - if ($VeeamDBFlavor.SqlActiveConfiguration -eq "PostgreSql") { - $DBPort = "$($VeeamDBInfo12.SqlHostPort)/TCP" - } else { - $DBPort = "1433/TCP" - } - - if ($DatabaseServer) { - $DatabaseServerIP = Get-NodeIP -Hostname $DatabaseServer - - $Rows = @{ - Role = 'Database Server' - IP = $DatabaseServerIP - } - - if ($VeeamDBInfo.SqlInstanceName) { - $Rows.add('Instance', $VeeamDBInfo.SqlInstanceName) - } - if ($VeeamDBInfo.SqlDatabaseName) { - $Rows.add('Database', $VeeamDBInfo.SqlDatabaseName) - } - - if ($VeeamDBFlavor.SqlActiveConfiguration -eq "PostgreSql") { - $DBIconType = "VBR_Server_DB_PG" - } else { - $DBIconType = "VBR_Server_DB" - } - - $script:DatabaseServerInfo = [PSCustomObject]@{ - Name = $DatabaseServer.split(".")[0] - Label = Get-DiaNodeIcon -Name "$($DatabaseServer.split(".")[0])" -IconType $DBIconType -Align "Center" -Rows $Rows -ImagesObj $Images -IconDebug $IconDebug - DBPort = $DBPort - } - } - } catch { - $_ - } - - try { - $EMServer = [Veeam.Backup.Core.SBackupOptions]::GetEnterpriseServerInfo() - if ($EMServer.ServerName) { - $EMServerIP = Get-NodeIP -Hostname $EMServer.ServerName - - $Rows = @{ - Role = 'Enterprise Manager Server' - IP = $EMServerIP - } - - $script:EMServerInfo = [PSCustomObject]@{ - Name = $EMServer.ServerName.split(".")[0] - Label = Get-DiaNodeIcon -Name "$($EMServer.ServerName.split(".")[0])" -IconType "VBR_Server_EM" -Align "Center" -Rows $Rows -ImagesObj $Images -IconDebug $IconDebug - } - } - } catch { - $_ - } - } catch { - $_ - } - } - end { - Remove-CimSession $CimSession - Remove-PSSession $PssSession - } -} - -function Get-VbrBackupSvrDiagramObj { - <# - .SYNOPSIS - Function to build Backup Server object. - .DESCRIPTION - Build a diagram of the configuration of Veeam VBR in PDF/PNG/SVG formats using Psgraph. - .NOTES - Version: 0.6.5 - Author: Jonathan Colon - Twitter: @jcolonfzenpr - Github: rebelinux - .LINK - https://github.com/rebelinux/Veeam.Diagrammer - #> - [CmdletBinding()] - - Param - ( - - ) - process { - try { - SubGraph BackupServers -Attributes @{Label = 'Management'; labelloc = 'b'; labeljust = "r"; style = "rounded"; bgcolor = "#ceedc4"; fontcolor = '#005f4b'; fontsize = 18; penwidth = 2; } { - SubGraph BackupServer -Attributes @{Label = 'Backup Server'; style = "rounded"; bgcolor = "#ceedc4"; fontsize = 18; fontcolor = '#565656'; penwidth = 0; labelloc = 't'; labeljust = "c"; } { - if (($DatabaseServerInfo.Name -ne $BackupServerInfo.Name) -and $EMServerInfo) { - Write-Verbose "Collecting Backup Server, Database Server and Enterprise Manager Information." - $BSHASHTABLE = @{} - $DBHASHTABLE = @{} - $EMHASHTABLE = @{} - - $BackupServerInfo.psobject.properties | ForEach-Object { $BSHASHTABLE[$_.Name] = $_.Value } - $DatabaseServerInfo.psobject.properties | ForEach-Object { $DBHASHTABLE[$_.Name] = $_.Value } - $EMServerInfo.psobject.properties | ForEach-Object { $EMHASHTABLE[$_.Name] = $_.Value } - - Node $BackupServerInfo.Name -Attributes @{Label = $BSHASHTABLE.Label; fillColor = '#ceedc4'; shape = 'plain'; fontsize = 14; fontname = "Segoe Ui" } - Node $DatabaseServerInfo.Name -Attributes @{Label = $DBHASHTABLE.Label; fillColor = '#ceedc4'; shape = 'plain'; fontsize = 14; fontname = "Segoe Ui" } - Node $EMServerInfo.Name -Attributes @{Label = $EMHASHTABLE.Label; fillColor = '#ceedc4'; shape = 'plain'; fontsize = 14; fontname = "Segoe Ui" } - - if ($Dir -eq 'LR') { - Rank $EMServerInfo.Name, $DatabaseServerInfo.Name - Edge -From $EMServerInfo.Name -To $BackupServerInfo.Name @{arrowtail = "normal"; arrowhead = "normal"; minlen = 3; } - Edge -From $DatabaseServerInfo.Name -To $BackupServerInfo.Name @{arrowtail = "normal"; arrowhead = "normal"; minlen = 3; xlabel = $DatabaseServerInfo.DBPort } - } else { - Rank $EMServerInfo.Name, $BackupServerInfo.Name, $DatabaseServerInfo.Name - Edge -From $EMServerInfo.Name -To $BackupServerInfo.Name @{arrowtail = "normal"; arrowhead = "normal"; minlen = 3; } - Edge -From $BackupServerInfo.Name -To $DatabaseServerInfo.Name @{arrowtail = "normal"; arrowhead = "normal"; minlen = 3; xlabel = $DatabaseServerInfo.DBPort } - } - } elseif (($DatabaseServerInfo.Name -ne $BackupServerInfo.Name) -and (-Not $EMServerInfo)) { - Write-Verbose "Not Enterprise Manager Found: Collecting Backup Server and Database server Information." - $BSHASHTABLE = @{} - $DBHASHTABLE = @{} - - $BackupServerInfo.psobject.properties | ForEach-Object { $BSHASHTABLE[$_.Name] = $_.Value } - $DatabaseServerInfo.psobject.properties | ForEach-Object { $DBHASHTABLE[$_.Name] = $_.Value } - - Node $BackupServerInfo.Name -Attributes @{Label = $BSHASHTABLE.Label; fillColor = '#ceedc4'; shape = 'plain'; fontsize = 14; fontname = "Segoe Ui" } - Node $DatabaseServerInfo.Name -Attributes @{Label = $DBHASHTABLE.Label; fillColor = '#ceedc4'; shape = 'plain'; fontsize = 14; fontname = "Segoe Ui" } - - if ($Dir -eq 'LR') { - Rank $BackupServerInfo.Name, $DatabaseServerInfo.Name - Edge -From $DatabaseServerInfo.Name -To $BackupServerInfo.Name @{arrowtail = "normal"; arrowhead = "normal"; minlen = 3; xlabel = $DatabaseServerInfo.DBPort } - } else { - Rank $BackupServerInfo.Name, $DatabaseServerInfo.Name - Edge -From $BackupServerInfo.Name -To $DatabaseServerInfo.Name @{arrowtail = "normal"; arrowhead = "normal"; minlen = 3; xlabel = $DatabaseServerInfo.DBPort } - } - } elseif ($EMServerInfo -and ($DatabaseServerInfo.Name -eq $BackupServerInfo.Name)) { - Write-Verbose "Database server colocated with Backup Server: Collecting Backup Server and Enterprise Manager Information." - $BSHASHTABLE = @{} - $EMHASHTABLE = @{} - - $BackupServerInfo.psobject.properties | ForEach-Object { $BSHASHTABLE[$_.Name] = $_.Value } - $EMServerInfo.psobject.properties | ForEach-Object { $EMHASHTABLE[$_.Name] = $_.Value } - - Node $BackupServerInfo.Name -Attributes @{Label = $BSHASHTABLE.Label; fillColor = '#ceedc4'; shape = 'plain'; fontsize = 14; fontname = "Segoe Ui" } - Node $EMServerInfo.Name -Attributes @{Label = $EMHASHTABLE.Label; fillColor = '#ceedc4'; shape = 'plain'; fontsize = 14; fontname = "Segoe Ui" } - - if ($Dir -eq 'LR') { - Rank $EMServerInfo.Name, $BackupServerInfo.Name - Edge -From $EMServerInfo.Name -To $BackupServerInfo.Name @{arrowtail = "normal"; arrowhead = "normal"; minlen = 3; } - } else { - Rank $EMServerInfo.Name, $BackupServerInfo.Name - Edge -From $BackupServerInfo.Name -To $EMServerInfo.Name @{arrowtail = "normal"; arrowhead = "normal"; minlen = 3; } - } - } else { - Write-Verbose "Database server colocated with Backup Server and no Enterprise Manager found: Collecting Backup Server Information." - $BSHASHTABLE = @{} - $BackupServerInfo.psobject.properties | ForEach-Object { $BSHASHTABLE[$_.Name] = $_.Value } - Node Left @{Label = 'Left'; style = $EdgeDebug.style; color = $EdgeDebug.color; shape = 'plain'; fillColor = 'transparent'; fontsize = 14; fontname = "Segoe Ui" } - Node Leftt @{Label = 'Leftt'; style = $EdgeDebug.style; color = $EdgeDebug.color; shape = 'plain'; fillColor = 'transparent'; fontsize = 14; fontname = "Segoe Ui" } - Node Right @{Label = 'Right'; style = $EdgeDebug.style; color = $EdgeDebug.color; shape = 'plain'; fillColor = 'transparent'; fontsize = 14; fontname = "Segoe Ui" } - Node $BackupServerInfo.Name -Attributes @{Label = $BSHASHTABLE.Label; fillColor = '#ceedc4'; shape = 'plain'; fontsize = 14; fontname = "Segoe Ui" } - Edge Left, Leftt, $BackupServerInfo.Name, Right @{style = $EdgeDebug.style; color = $EdgeDebug.color } - Rank Left, Leftt, $BackupServerInfo.Name, Right - } - } - } - } catch { - $_ - } - } - end {} -} - # Proxy Graphviz Cluster function Get-VbrProxyInfo { param ( @@ -269,9 +9,6 @@ function Get-VbrProxyInfo { $Proxies += Get-VBRHvProxy if ($Proxies) { - if ($Options.DiagramObjDebug) { - $Proxies = $ProxiesDebug - } $ProxiesInfo = @() @@ -315,9 +52,6 @@ function Get-VbrWanAccelInfo { $WanAccels = Get-VBRWANAccelerator if ($WanAccels) { - if ($Options.DiagramObjDebug) { - $WanAccels = $WanAccelsDebug - } $WanAccelsInfo = @() @@ -506,30 +240,31 @@ function Get-VbrSOBRInfo { $SOBR = Get-VBRBackupRepository -ScaleOut | Sort-Object -Property Name if ($SOBR) { - if ($Options.DiagramObjDebug) { - $SOBR = $SOBRDebug - } $SOBRInfo = @() $SOBR | ForEach-Object { - $inobj = [ordered] @{ - 'Placement Policy' = $_.PolicyType - 'Encryption Enabled' = switch ($_.EncryptionEnabled) { - "" { "--" } - $Null { "--" } - "True" { "Yes"; break } - "False" { "No"; break } - default { $_.EncryptionEnabled } + try { + $inobj = [ordered] @{ + 'Placement Policy' = $_.PolicyType + 'Encryption Enabled' = switch ($_.EncryptionEnabled) { + "" { "--" } + $Null { "--" } + "True" { "Yes"; break } + "False" { "No"; break } + default { $_.EncryptionEnabled } + } } - } - $TempSOBRInfo = [PSCustomObject]@{ - Name = $_.Name - AditionalInfo = $inobj - } + $TempSOBRInfo = [PSCustomObject]@{ + Name = $_.Name + AditionalInfo = $inobj + } - $SOBRInfo += $TempSOBRInfo + $SOBRInfo += $TempSOBRInfo + } catch { + Write-Verbose "Error: Unable to process $($_.Name) from SOBR table: $($_.Exception.Message)" + } } } diff --git a/Src/Private/Get-VbrInfraDiagram.ps1 b/Src/Private/Get-VbrInfraDiagram.ps1 index 75ddb0d..3a3021b 100644 --- a/Src/Private/Get-VbrInfraDiagram.ps1 +++ b/Src/Private/Get-VbrInfraDiagram.ps1 @@ -35,10 +35,10 @@ function Get-VbrInfraDiagram { # Get Veeam Backup Server Infrastructure Information # This create the Backup Server, Database and Enterprise Manager Objects # Here Veeam Pwershell Module are used to retreive the information - Get-VBRBackupServerObj + Get-VBRBackupServerInfo # Build Backup Server Graphviz Cluster - Get-VbrBackupSvrDiagramObj + Get-DiagBackupServer # Proxy Graphviz Cluster if ($Proxies = Get-VbrProxyInfo) { diff --git a/Veeam.Diagrammer.psd1 b/Veeam.Diagrammer.psd1 index 5fef18f..c33384b 100644 --- a/Veeam.Diagrammer.psd1 +++ b/Veeam.Diagrammer.psd1 @@ -12,7 +12,7 @@ RootModule = 'Veeam.Diagrammer.psm1' # Version number of this module. - ModuleVersion = '0.6.6' + ModuleVersion = '0.6.7' # Supported PSEditions # CompatiblePSEditions = @()