From d76dae6a008ae916cacb485021c6a4bb9041b8f1 Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Wed, 4 May 2022 13:58:42 -0400 Subject: [PATCH 01/12] Fix for not configured enterprise manager --- AsBuiltReport.Veeam.VBR.psd1 | 2 +- Src/Private/Get-AbrVbrEnterpriseManagerInfo.ps1 | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/AsBuiltReport.Veeam.VBR.psd1 b/AsBuiltReport.Veeam.VBR.psd1 index 3c605f6..4e7cf98 100644 --- a/AsBuiltReport.Veeam.VBR.psd1 +++ b/AsBuiltReport.Veeam.VBR.psd1 @@ -12,7 +12,7 @@ RootModule = 'AsBuiltReport.Veeam.VBR.psm1' # Version number of this module. -ModuleVersion = '0.4.1' +ModuleVersion = '0.5.0' # Supported PSEditions # CompatiblePSEditions = @() diff --git a/Src/Private/Get-AbrVbrEnterpriseManagerInfo.ps1 b/Src/Private/Get-AbrVbrEnterpriseManagerInfo.ps1 index d94656b..128b33f 100644 --- a/Src/Private/Get-AbrVbrEnterpriseManagerInfo.ps1 +++ b/Src/Private/Get-AbrVbrEnterpriseManagerInfo.ps1 @@ -6,7 +6,7 @@ function Get-AbrVbrEnterpriseManagerInfo { .DESCRIPTION Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. .NOTES - Version: 0.4.1 + Version: 0.5.0 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -39,8 +39,14 @@ function Get-AbrVbrEnterpriseManagerInfo { $EMInfo = [Veeam.Backup.Core.SBackupOptions]::GetEnterpriseServerInfo() if ($EMInfo) { $inObj = [ordered] @{ - 'Server Name' = $EMInfo.ServerName - 'Server URL' = $EMInfo.URL + 'Server Name' = Switch ($EMInfo.ServerName) { + $Null {'Not Connected'} + default {$EMInfo.ServerName} + } + 'Server URL' = Switch ($EMInfo.URL) { + $Null {'Not Connected'} + default {$EMInfo.URL} + } 'Skip License Push' = ConvertTo-TextYN $EMInfo.SkipLicensePush 'Is Connected' = ConvertTo-TextYN $EMInfo.IsConnected } From c5240c9dbb36c4fd58c182783c548d9c1dd60ac6 Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Sun, 8 May 2022 20:07:43 -0400 Subject: [PATCH 02/12] Added Replicacion reporting --- AsBuiltreport.Veeam.VBR.json | 4 + CHANGELOG.md | 14 ++ README.md | 7 + Src/Private/Get-AbrVbrReplFailoverPlan.ps1 | 125 ++++++++++++++++++ Src/Private/Get-AbrVbrReplInfraSummary.ps1 | 56 ++++++++ Src/Private/Get-AbrVbrReplReplica.ps1 | 118 +++++++++++++++++ Src/Public/Invoke-AsBuiltReport.Veeam.VBR.ps1 | 22 ++- 7 files changed, 345 insertions(+), 1 deletion(-) create mode 100644 Src/Private/Get-AbrVbrReplFailoverPlan.ps1 create mode 100644 Src/Private/Get-AbrVbrReplInfraSummary.ps1 create mode 100644 Src/Private/Get-AbrVbrReplReplica.ps1 diff --git a/AsBuiltreport.Veeam.VBR.json b/AsBuiltreport.Veeam.VBR.json index afe7430..ec7370e 100644 --- a/AsBuiltreport.Veeam.VBR.json +++ b/AsBuiltreport.Veeam.VBR.json @@ -42,6 +42,10 @@ "ONTAP": 1, "ISILON": 1 }, + "Replication": { + "FailoverPlan": 1, + "Replica": 1 + }, "Jobs": { "Backup": 1, "Tape": 1, diff --git a/CHANGELOG.md b/CHANGELOG.md index f2cfdd4..80697d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # :arrows_clockwise: Veeam VBR As Built Report Changelog +## [0.5.0] - 2022-05-xx + +### Added + +- Added Replication Section @rebelinux + - Replica Information + - Added Optional InfoLevel 2 information (Adv Summary) + - Failover Plan Information + - Added Virtual Machine Boot Order reporting + +### Fixed + +- Fix for not connected Enterprise Manager. + ## [0.4.1] - 2022-05-02 ### Added diff --git a/README.md b/README.md index ea0abea..9051d52 100644 --- a/README.md +++ b/README.md @@ -195,6 +195,13 @@ The table below outlines the default and maximum **InfoLevel** settings for each | Surebackup | 1 | 2 | | Agent | 1 | 2 | +The table below outlines the default and maximum **InfoLevel** settings for each Replication section. + +| Sub-Schema | Default Setting | Maximum Setting | +|--------------|:---------------:|:---------------:| +| Replica | 1 | 2 | +| Failover Plan | 1 | 1 | + ### Healthcheck The **Healthcheck** schema is used to toggle health checks on or off. diff --git a/Src/Private/Get-AbrVbrReplFailoverPlan.ps1 b/Src/Private/Get-AbrVbrReplFailoverPlan.ps1 new file mode 100644 index 0000000..0091cd4 --- /dev/null +++ b/Src/Private/Get-AbrVbrReplFailoverPlan.ps1 @@ -0,0 +1,125 @@ + +function Get-AbrVbrReplFailoverPlan { + <# + .SYNOPSIS + Used by As Built Report to retrieve Veeam VBR Failover Plan Information. + .DESCRIPTION + Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. + .NOTES + Version: 0.5.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + Credits: Iain Brighton (@iainbrighton) - PScribo module + + .LINK + https://github.com/AsBuiltReport/AsBuiltReport.Veeam.VBR + #> + [CmdletBinding()] + param ( + + ) + + begin { + Write-PscriboMessage "Discovering Veeam VBR Failover Plans from $System." + } + + process { + try { + if ((Get-VBRServerSession).Server) { + $FailOverPlans = Get-VBRFailoverPlan + if ($FailOverPlans) { + Section -Style Heading2 'Failover Plans' { + Paragraph "The following section details failover plan information from Veeam Server $(((Get-VBRServerSession).Server))." + $OutObj = @() + foreach ($FailOverPlan in $FailOverPlans) { + try { + Section -Style Heading2 $($FailOverPlan.Name) { + $inObj = [ordered] @{ + 'Platform' = $FailOverPlan.Platform + 'Status' = $FailOverPlan.Status + 'Pre Failover Script Enabled' = ConvertTo-TextYN $FailOverPlan.PreFailoverScriptEnabled + 'Pre Failover Command' = ConvertTo-EmptyToFiller $FailOverPlan.PrefailoverCommand + 'Post Failover Script Enabled' = ConvertTo-TextYN $FailOverPlan.PostFailoverScriptEnabled + 'Post Failover Command' = ConvertTo-EmptyToFiller $FailOverPlan.PostfailoverCommand + 'VM Count' = $FailOverPlan.VmCount + 'Description' = $FailOverPlan.Description + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Failover Plan - $($FailOverPlan.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + if ($InfoLevel.Replication.FailoverPlan -ge 2) { + if ($FailOverPlan) { + try { + Section -Style Heading2 'Virtual Machines' { + Paragraph "The following section details failover plan vms information from Veeam Server $(((Get-VBRServerSession).Server))." + BlankLine + $OutObj = @() + foreach ($FailOverPlansVM in $FailOverPlan.FailoverPlanObject) { + try { + if ($FailOverPlan.Platform -eq 'VMWare') { + Write-PscriboMessage "Discovering $($FailOverPlan.Name) VMware VM information." + $VMInfo = Find-VBRViEntity -Name $FailOverPlansVM + } Else { + Write-PscriboMessage "Discovering $($FailOverPlan.Name) Hyper-V VM information." + $VMInfo = Find-VBRHvEntity -Name $FailOverPlansVM + } + if ($VMInfo) { + Write-PscriboMessage "Discovered $($VMInfo.Name) VM information." + } + $inObj = [ordered] @{ + 'VM Name' = Switch ($VMInfo.Name) { + $Null {'Unknown'} + default {$VMInfo.Name} + } + 'Boot Order' = $FailOverPlansVM.BootOrder + 'Boot Delay' = $FailOverPlansVM.BootDelay + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + + $TableParams = @{ + Name = "Virtual Machines - $($FailOverPlan.Name)" + List = $false + ColumnWidths = 40, 30, 30 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Sort-Object -Property 'Job Name' | Table @TableParams + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + } + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + end {} + +} \ No newline at end of file diff --git a/Src/Private/Get-AbrVbrReplInfraSummary.ps1 b/Src/Private/Get-AbrVbrReplInfraSummary.ps1 new file mode 100644 index 0000000..41c0472 --- /dev/null +++ b/Src/Private/Get-AbrVbrReplInfraSummary.ps1 @@ -0,0 +1,56 @@ + +function Get-AbrVbrReplInfraSummary { + <# + .SYNOPSIS + Used by As Built Report to retrieve Veeam VBR Replication Summary. + .DESCRIPTION + Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. + .NOTES + Version: 0.5.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + Credits: Iain Brighton (@iainbrighton) - PScribo module + + .LINK + https://github.com/AsBuiltReport/AsBuiltReport.Veeam.VBR + #> + [CmdletBinding()] + param ( + + ) + + begin { + Write-PscriboMessage "Discovering Veeam VBR Replication Summary from $System." + } + + process { + try { + $OutObj = @() + if ((Get-VBRServerSession).Server) { + $Replicas = Get-VBRReplica + $FailOverPlans = Get-VBRFailoverPlan + $inObj = [ordered] @{ + 'Number of Replicas' = $Replicas.Count + 'Number of Failover Plans' = $FailOverPlans.Count + } + $OutObj += [pscustomobject]$inobj + + $TableParams = @{ + Name = "Executive Summary - $(((Get-VBRServerSession).Server).ToString().ToUpper().Split(".")[0])" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + end {} + +} \ No newline at end of file diff --git a/Src/Private/Get-AbrVbrReplReplica.ps1 b/Src/Private/Get-AbrVbrReplReplica.ps1 new file mode 100644 index 0000000..41d7595 --- /dev/null +++ b/Src/Private/Get-AbrVbrReplReplica.ps1 @@ -0,0 +1,118 @@ + +function Get-AbrVbrReplReplica { + <# + .SYNOPSIS + Used by As Built Report to retrieve Veeam VBR Replica Information. + .DESCRIPTION + Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. + .NOTES + Version: 0.5.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + Credits: Iain Brighton (@iainbrighton) - PScribo module + + .LINK + https://github.com/AsBuiltReport/AsBuiltReport.Veeam.VBR + #> + [CmdletBinding()] + param ( + + ) + + begin { + Write-PscriboMessage "Discovering Veeam VBR Replicas from $System." + } + + process { + try { + if ((Get-VBRServerSession).Server) { + try { + $Replicas = Get-VBRReplica + if ($Replicas) { + if ($InfoLevel.Replication.Replica -eq 1) { + Section -Style Heading2 'Replicas' { + Paragraph "The following section details replica information from Veeam Server $(((Get-VBRServerSession).Server))." + BlankLine + $OutObj = @() + foreach ($Replica in $Replicas) { + foreach ($VM in $Replica.GetBackupReplicas()) { + $inObj = [ordered] @{ + 'VM Name' = $VM.VmName + 'Job Name' = $Replica.JobName + 'Type' = $Replica.TypeToString + 'Restore Points' = ($VM | Get-VBRRestorePoint).count + } + $OutObj += [pscustomobject]$inobj + } + } + + $TableParams = @{ + Name = "Replicas - $(((Get-VBRServerSession).Server).ToString().ToUpper().Split(".")[0])" + List = $false + ColumnWidths = 34, 34, 22, 10 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Sort-Object -Property 'Job Name' | Table @TableParams + } + } + if ($InfoLevel.Replication.Replica -ge 2) { + try { + Section -Style Heading2 'Replicas' { + Paragraph "The following section details replica information from Veeam Server $(((Get-VBRServerSession).Server))." + BlankLine + $OutObj = @() + foreach ($Replica in $Replicas) { + try { + foreach ($VM in $Replica.GetBackupReplicas()) { + $inObj = [ordered] @{ + 'VM Name' = $VM.VmName + 'Target Vm Name' = $VM.TargetVmName + 'Original Location' = $VM.info.SourceLocation + 'Destination Location' = $VM.info.TargetLocation + 'Job Name' = $Replica.JobName + 'State' = $VM.State + 'Type' = $Replica.TypeToString + 'Restore Points' = ($VM | Get-VBRRestorePoint).count + 'Creation Time' = $Replica.CreationTime + + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "$($Replica.JobName) - $($VM.VmName)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + end {} + +} \ No newline at end of file diff --git a/Src/Public/Invoke-AsBuiltReport.Veeam.VBR.ps1 b/Src/Public/Invoke-AsBuiltReport.Veeam.VBR.ps1 index 038d72b..2558f2f 100644 --- a/Src/Public/Invoke-AsBuiltReport.Veeam.VBR.ps1 +++ b/Src/Public/Invoke-AsBuiltReport.Veeam.VBR.ps1 @@ -5,7 +5,7 @@ function Invoke-AsBuiltReport.Veeam.VBR { .DESCRIPTION Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. .NOTES - Version: 0.4.1 + Version: 0.5.0 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -166,6 +166,26 @@ function Invoke-AsBuiltReport.Veeam.VBR { } } #---------------------------------------------------------------------------------------------# + # Replication Section # + #---------------------------------------------------------------------------------------------# + if ($InfoLevel.Replication.PSObject.Properties.Value -ne 0) { + if ((Get-VBRReplica).count -gt 0 -or ((Get-VBRFailoverPlan).count -gt 0)) { + Section -Style Heading2 'Replication Summary' { + Paragraph "The following section provides replication managed by Veeam Server $(((Get-VBRServerSession).Server))." + BlankLine + Get-AbrVbrReplInfraSummary + Write-PScriboMessage "Replica InfoLevel set at $($InfoLevel.Replication.Replica)." + if ($InfoLevel.Replication.Replica -ge 1) { + Get-AbrVbrReplReplica + } + Write-PScriboMessage "Failover Plan InfoLevel set at $($InfoLevel.Replication.FailoverPlan)." + if ($InfoLevel.Replication.FailoverPlan -ge 1) { + Get-AbrVbrReplFailoverPlan + } + } + } + } + #---------------------------------------------------------------------------------------------# # Backup Jobs Section # #---------------------------------------------------------------------------------------------# if ($InfoLevel.Jobs.PSObject.Properties.Value -ne 0) { From 5e31c991133fbccc66140432b65b3e3ddc752875 Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Mon, 9 May 2022 21:58:47 -0400 Subject: [PATCH 03/12] Initial Replication Job Section reporting --- AsBuiltreport.Veeam.VBR.json | 3 +- Src/Private/Get-AbrVbrBackupjobVMware.ps1 | 2 +- Src/Private/Get-AbrVbrRepljob.ps1 | 75 ++ Src/Private/Get-AbrVbrRepljobVMware.ps1 | 726 ++++++++++++++++++ Src/Public/Invoke-AsBuiltReport.Veeam.VBR.ps1 | 10 +- 5 files changed, 812 insertions(+), 4 deletions(-) create mode 100644 Src/Private/Get-AbrVbrRepljob.ps1 create mode 100644 Src/Private/Get-AbrVbrRepljobVMware.ps1 diff --git a/AsBuiltreport.Veeam.VBR.json b/AsBuiltreport.Veeam.VBR.json index ec7370e..0cca6b5 100644 --- a/AsBuiltreport.Veeam.VBR.json +++ b/AsBuiltreport.Veeam.VBR.json @@ -50,7 +50,8 @@ "Backup": 1, "Tape": 1, "Surebackup": 1, - "Agent": 1 + "Agent": 1, + "Replication": 1 } }, "HealthCheck": { diff --git a/Src/Private/Get-AbrVbrBackupjobVMware.ps1 b/Src/Private/Get-AbrVbrBackupjobVMware.ps1 index 35cf400..f09d4fd 100644 --- a/Src/Private/Get-AbrVbrBackupjobVMware.ps1 +++ b/Src/Private/Get-AbrVbrBackupjobVMware.ps1 @@ -28,7 +28,7 @@ function Get-AbrVbrBackupjobVMware { try { $Bkjobs = Get-VBRJob -WarningAction SilentlyContinue | Where-Object {$_.TypeToString -eq "VMware Backup" -or $_.TypeToString -eq "VMware Backup Copy" -or $_.TypeToString -eq "VM Copy"} if (($Bkjobs).count -gt 0) { - Section -Style Heading3 'VMware Backup Configuration' { + Section -Style Heading3 'VMware Backup Jobs Configuration' { Paragraph "The following section details VMware type per backup jobs configuration." BlankLine $OutObj = @() diff --git a/Src/Private/Get-AbrVbrRepljob.ps1 b/Src/Private/Get-AbrVbrRepljob.ps1 new file mode 100644 index 0000000..ae904ef --- /dev/null +++ b/Src/Private/Get-AbrVbrRepljob.ps1 @@ -0,0 +1,75 @@ + +function Get-AbrVbrRepljob { + <# + .SYNOPSIS + Used by As Built Report to returns replication jobs created in Veeam Backup & Replication. + .DESCRIPTION + Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. + .NOTES + Version: 0.5.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + Credits: Iain Brighton (@iainbrighton) - PScribo module + + .LINK + https://github.com/AsBuiltReport/AsBuiltReport.Veeam.VBR + #> + [CmdletBinding()] + param ( + + ) + + begin { + Write-PscriboMessage "Discovering Veeam VBR Replication jobs information from $System." + } + + process { + try { + $Bkjobs = Get-VBRJob -WarningAction SilentlyContinue | Where-object {$_.TypeToString -eq 'VMware Replication' -or $_.TypeToString -eq 'Hyper-V Replication'} + if (($Bkjobs).count -gt 0) { + Section -Style Heading3 'Replication Jobs' { + Paragraph "The following section list replication jobs created in Veeam Backup & Replication." + BlankLine + $OutObj = @() + if ((Get-VBRServerSession).Server) { + foreach ($Bkjob in $Bkjobs) { + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) replication job." + $inObj = [ordered] @{ + 'Name' = $Bkjob.Name + 'Type' = $Bkjob.TypeToString + 'Status' = Switch ($Bkjob.IsScheduleEnabled) { + 'False' {'Disabled'} + 'True' {'Enabled'} + } + 'Latest Result' = $Bkjob.info.LatestStatus + 'Last Run' = $Bkjob.FindLastSession().EndTimeUTC + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + + $TableParams = @{ + Name = "Replication Jobs - $(((Get-VBRServerSession).Server).ToString().ToUpper().Split(".")[0])" + List = $false + ColumnWidths = 25, 20, 15, 15, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Sort-Object -Property Name |Table @TableParams + } + } + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + end {} + +} diff --git a/Src/Private/Get-AbrVbrRepljobVMware.ps1 b/Src/Private/Get-AbrVbrRepljobVMware.ps1 new file mode 100644 index 0000000..e14e0c7 --- /dev/null +++ b/Src/Private/Get-AbrVbrRepljobVMware.ps1 @@ -0,0 +1,726 @@ + +function Get-AbrVbrRepljobVMware { + <# + .SYNOPSIS + Used by As Built Report to returns vmware replication jobs created in Veeam Backup & Replication. + .DESCRIPTION + Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. + .NOTES + Version: 0.5.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + Credits: Iain Brighton (@iainbrighton) - PScribo module + + .LINK + https://github.com/AsBuiltReport/AsBuiltReport.Veeam.VBR + #> + [CmdletBinding()] + param ( + + ) + + begin { + Write-PscriboMessage "Discovering Veeam VBR VMware replication jobs information from $System." + } + + process { + try { + $Bkjobs = Get-VBRJob -WarningAction SilentlyContinue | Where-object {$_.TypeToString -eq 'VMware Replication'} + if (($Bkjobs).count -gt 0) { + Section -Style Heading3 'VMware Replication Jobs Configuration' { + Paragraph "The following section details VMware type per backup jobs configuration." + BlankLine + $OutObj = @() + try { + $VMcounts = Get-VBRJob -WarningAction SilentlyContinue | Where-object {$_.TypeToString -eq 'VMware Replication' -or $_.TypeToString -eq 'Hyper-V Replication'} + if ($VMcounts) { + foreach ($VMcount in $VMcounts) { + try { + Write-PscriboMessage "Discovered $($VMcount.Name) ." + $inObj = [ordered] @{ + 'Name' = $VMcount.Name + 'Creation Time' = $VMcount.CreationTime + 'VM Count' = (Get-VBRReplica | Where-Object {$_.JobName -eq $VMcount.Name}).VMcount + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + + $TableParams = @{ + Name = "VMware Replication Summary - $(((Get-VBRServerSession).Server).ToString().ToUpper().Split(".")[0])" + List = $false + ColumnWidths = 35, 35, 30 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Sort-Object -Property 'Name' | Table @TableParams + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + $OutObj = @() + foreach ($Bkjob in $Bkjobs) { + try { + Section -Style Heading4 "$($Bkjob.Name) Configuration" { + Section -Style Heading5 'Common Information' { + $OutObj = @() + try { + $CommonInfos = (Get-VBRJob -WarningAction SilentlyContinue | Where-object {$_.TypeToString -eq 'VMware Replication'}).Info + foreach ($CommonInfo in $CommonInfos) { + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) common information." + $inObj = [ordered] @{ + 'Name' = $Bkjob.Name + 'Type' = $Bkjob.TypeToString + 'Total Backup Size' = ConvertTo-FileSizeString $CommonInfo.IncludedSize + 'Target Address' = $CommonInfo.TargetDir + 'Target File' = $CommonInfo.TargetFile + 'Description' = $CommonInfo.CommonInfo.Description + 'Modified By' = $CommonInfo.CommonInfo.ModifiedBy.FullName + } + $OutObj = [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + + $TableParams = @{ + Name = "Common Information - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + if ($Bkjob.LinkedJobs) { + Section -Style Heading5 'Linked Backup Jobs' { + $OutObj = @() + try { + foreach ($LinkedBkJob in $Bkjob.LinkedJobs) { + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) linked backup job." + $Job = Get-VBRJob -WarningAction SilentlyContinue| Where-Object {$_.Id -eq $LinkedBkJob.info.LinkedObjectId} + $inObj = [ordered] @{ + 'Name' = $Job.Name + 'Type' = $Job.TypeToString + 'Size' = ConvertTo-FileSizeString $Job.Info.IncludedSize + 'Repository' = $Job.GetTargetRepository().Name + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + + $TableParams = @{ + Name = "Linked Backup Jobs - $($Bkjob.Name)" + List = $false + ColumnWidths = 35, 25, 15, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Sort-Object -Property 'Name' | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($Bkjob.LinkedRepositories) { + Section -Style Heading5 'Linked Repositories' { + $OutObj = @() + try { + foreach ($LinkedRepository in $Bkjob.LinkedRepositories.LinkedRepositoryId) { + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) linked repository." + $Repo = Get-VBRBackupRepository | Where-Object {$_.Id -eq $LinkedRepository} + $ScaleRepo = Get-VBRBackupRepository -ScaleOut | Where-Object {$_.Id -eq $LinkedRepository} + if ($Repo) { + $inObj = [ordered] @{ + 'Name' = $Repo.Name + 'Type' = "Standard" + 'Size' = "$($Repo.GetContainer().CachedTotalSpace.InGigabytes) Gb" + } + } + if ($ScaleRepo) { + $inObj = [ordered] @{ + 'Name' = $ScaleRepo.Name + 'Type' = "ScaleOut" + 'Size' = "$((($ScaleRepo.Extent).Repository).GetContainer().CachedTotalSpace.InGigabytes) GB" + } + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + + $TableParams = @{ + Name = "Linked Repositories - $($Bkjob.Name)" + List = $false + ColumnWidths = 35, 35, 30 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Sort-Object -Property 'Name' | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($Bkjob.GetViOijs()) { + Section -Style Heading5 "Virtual Machines" { + $OutObj = @() + try { + foreach ($OBJ in ($Bkjob.GetViOijs() | Where-Object {$_.Type -eq "Include" -or $_.Type -eq "Exclude"} )) { + Write-PscriboMessage "Discovered $($OBJ.Name) object to backup." + $inObj = [ordered] @{ + 'Name' = $OBJ.Name + 'Resource Type' = $OBJ.TypeDisplayName + 'Role' = $OBJ.Type + 'Location' = $OBJ.Location + 'Approx Size' = $OBJ.ApproxSizeString + 'Disk Filter Mode' = $OBJ.DiskFilterInfo.Mode + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Virtual Machines - $($OBJ.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + Section -Style Heading5 'Job Settings' { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) storage options." + if ($Bkjob.BackupStorageOptions.RetentionType -eq "Days") { + $RetainString = 'Retain Days To Keep' + $Retains = $Bkjob.BackupStorageOptions.RetainDaysToKeep + } + elseif ($Bkjob.BackupStorageOptions.RetentionType -eq "Cycles") { + $RetainString = 'Retain Cycles' + $Retains = $Bkjob.BackupStorageOptions.RetainCycles + } + $inObj = [ordered] @{ + 'Backup Proxy' = Switch (($Bkjob.GetProxy().Name).count) { + 0 {"Unknown"} + {$_ -gt 1} {"Automatic"} + default {$Bkjob.GetProxy().Name} + } + 'Repository for replica metadata' = Switch ($Bkjob.info.TargetRepositoryId) { + '00000000-0000-0000-0000-000000000000' {$Bkjob.TargetDir} + {$Null -eq (Get-VBRBackupRepository | Where-Object {$_.Id -eq $Bkjob.info.TargetRepositoryId}).Name} {(Get-VBRBackupRepository -ScaleOut | Where-Object {$_.Id -eq $Bkjob.info.TargetRepositoryId}).Name} + default {(Get-VBRBackupRepository | Where-Object {$_.Id -eq $Bkjob.info.TargetRepositoryId}).Name} + } + 'Retention Type' = $Bkjob.BackupStorageOptions.RetentionType + $RetainString = $Retains + 'Keep First Full Backup' = ConvertTo-TextYN $Bkjob.BackupStorageOptions.KeepFirstFullBackup + 'Enable Full Backup' = ConvertTo-TextYN $Bkjob.BackupStorageOptions.EnableFullBackup + 'Integrity Checks' = ConvertTo-TextYN $Bkjob.BackupStorageOptions.EnableIntegrityChecks + 'Storage Encryption' = ConvertTo-TextYN $Bkjob.BackupStorageOptions.StorageEncryptionEnabled + 'Backup Mode' = Switch ($Bkjob.Options.BackupTargetOptions.Algorithm) { + 'Syntethic' {"Reverse Incremental"} + 'Increment' {'Incremental'} + } + 'Active Full Backup Schedule Kind' = $Bkjob.Options.BackupTargetOptions.FullBackupScheduleKind + 'Active Full Backup Days' = $Bkjob.Options.BackupTargetOptions.FullBackupDays + 'Transform Full To Syntethic' = ConvertTo-TextYN $Bkjob.Options.BackupTargetOptions.TransformFullToSyntethic + 'Transform Increments To Syntethic' = ConvertTo-TextYN $Bkjob.Options.BackupTargetOptions.TransformIncrementsToSyntethic + 'Transform To Syntethic Days' = $Bkjob.Options.BackupTargetOptions.TransformToSyntethicDays + + + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "$Storage Options - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + if ($InfoLevel.Jobs.Replication -ge 2 -and ($Bkjob.Options.GenerationPolicy.EnableRechek -or $Bkjob.Options.GenerationPolicy.EnableCompactFull)) { + Section -Style Heading6 "Advanced Settings (Maintenance)" { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) maintenance options." + $inObj = [ordered] @{ + 'Storage-Level Corruption Guard (SLCG)' = ConvertTo-TextYN $Bkjob.Options.GenerationPolicy.EnableRechek + 'SLCG Schedule Type' = $Bkjob.Options.GenerationPolicy.RecheckScheduleKind + 'SLCG Schedule Day' = $Bkjob.Options.GenerationPolicy.RecheckDays + 'SLCG Backup Monthly Schedule' = "Day Of Week: $($Bkjob.Options.GenerationPolicy.RecheckBackupMonthlyScheduleOptions.DayOfWeek)`r`nDay Number In Month: $($Bkjob.Options.GenerationPolicy.RecheckBackupMonthlyScheduleOptions.DayNumberInMonth)`r`nDay of Month: $($Bkjob.Options.GenerationPolicy.RecheckBackupMonthlyScheduleOptions.DayOfMonth)`r`nMonths: $($Bkjob.Options.GenerationPolicy.RecheckBackupMonthlyScheduleOptions.Months)" + 'Defragment and Compact Full Backup (DCFB)' = ConvertTo-TextYN $Bkjob.Options.GenerationPolicy.EnableCompactFull + 'DCFB Schedule Type' = $Bkjob.Options.GenerationPolicy.CompactFullBackupScheduleKind + 'DCFB Schedule Day' = $Bkjob.Options.GenerationPolicy.CompactFullBackupDays + 'DCFB Backup Monthly Schedule' = "Day Of Week: $($Bkjob.Options.GenerationPolicy.CompactFullBackupMonthlyScheduleOptions.DayOfWeek)`r`nDay Number In Month: $($Bkjob.Options.GenerationPolicy.CompactFullBackupMonthlyScheduleOptions.DayNumberInMonth)`r`nDay of Month: $($Bkjob.Options.GenerationPolicy.CompactFullBackupMonthlyScheduleOptions.DayOfMonth)`r`nMonths: $($Bkjob.Options.GenerationPolicy.CompactFullBackupMonthlyScheduleOptions.Months)" + 'Remove deleted item data after' = $Bkjob.Options.BackupStorageOptions.RetainDays + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Advanced Settings (Maintenance) - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($InfoLevel.Jobs.Replication -ge 2) { + Section -Style Heading6 "Advanced Settings (Storage)" { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) storage options." + $inObj = [ordered] @{ + 'Inline Data Deduplication' = ConvertTo-TextYN $Bkjob.Options.BackupStorageOptions.EnableDeduplication + 'Exclude Swap Files Block' = ConvertTo-TextYN $Bkjob.ViSourceOptions.ExcludeSwapFile + 'Exclude Deleted Files Block' = ConvertTo-TextYN $Bkjob.ViSourceOptions.DirtyBlocksNullingEnabled + 'Compression Level' = Switch ($Bkjob.Options.BackupStorageOptions.CompressionLevel) { + 0 {'NONE'} + -1 {'AUTO'} + 4 {'DEDUPE_friendly'} + 5 {'OPTIMAL (Default)'} + 6 {'High'} + 9 {'EXTREME'} + } + 'Storage optimization' = Switch ($Bkjob.Options.BackupStorageOptions.StgBlockSize) { + 'KbBlockSize1024' {'Local target'} + 'KbBlockSize512' {'LAN target'} + 'KbBlockSize256' {'WAN target'} + 'KbBlockSize4096' {'Local target (large blocks)'} + default {$Bkjob.Options.BackupStorageOptions.StgBlockSize} + } + 'Enabled Backup File Encryption' = ConvertTo-TextYN $Bkjob.Options.BackupStorageOptions.StorageEncryptionEnabled + 'Encryption Key' = Switch ($Bkjob.Options.BackupStorageOptions.StorageEncryptionEnabled) { + $false {'None'} + default {(Get-VBREncryptionKey | Where-Object { $_.id -eq $Bkjob.Info.PwdKeyId }).Description} + } + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Advanced Settings (Storage) - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($InfoLevel.Jobs.Replication -ge 2 -and ($Bkjob.Options.NotificationOptions.SnmpNotification -or $Bkjob.Options.NotificationOptions.SendEmailNotification2AdditionalAddresses)) { + Section -Style Heading6 "Advanced Settings (Notification)" { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) notification options." + $inObj = [ordered] @{ + 'Send Snmp Notification' = ConvertTo-TextYN $Bkjob.Options.NotificationOptions.SnmpNotification + 'Send Email Notification' = ConvertTo-TextYN $Bkjob.Options.NotificationOptions.SendEmailNotification2AdditionalAddresses + 'Email Notification Additional Addresses' = $Bkjob.Options.NotificationOptions.EmailNotificationAdditionalAddresses + 'Email Notify Time' = $Bkjob.Options.NotificationOptions.EmailNotifyTime.ToShortTimeString() + 'Use Custom Email Notification Options' = ConvertTo-TextYN $Bkjob.Options.NotificationOptions.UseCustomEmailNotificationOptions + 'Use Custom Notification Setting' = $Bkjob.Options.NotificationOptions.EmailNotificationSubject + 'Notify On Success' = ConvertTo-TextYN $Bkjob.Options.NotificationOptions.EmailNotifyOnSuccess + 'Notify On Warning' = ConvertTo-TextYN $Bkjob.Options.NotificationOptions.EmailNotifyOnWarning + 'Notify On Error' = ConvertTo-TextYN $Bkjob.Options.NotificationOptions.EmailNotifyOnError + 'Suppress Notification until Last Retry' = ConvertTo-TextYN $Bkjob.Options.NotificationOptions.EmailNotifyOnLastRetryOnly + 'Set Results To Vm Notes' = ConvertTo-TextYN $Bkjob.Options.ViSourceOptions.SetResultsToVmNotes + 'VM Attribute Note Value' = $Bkjob.Options.ViSourceOptions.VmAttributeName + 'Append to Existing Attribute' = ConvertTo-TextYN $Bkjob.Options.ViSourceOptions.VmNotesAppend + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Advanced Settings (Notification) - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($InfoLevel.Jobs.Replication -ge 2 -and ($Bkjob.Options.ViSourceOptions.VMToolsQuiesce -or $Bkjob.Options.ViSourceOptions.UseChangeTracking)) { + Section -Style Heading6 "Advanced Settings (vSphere)" { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) vSphere options." + $inObj = [ordered] @{ + 'Enable VMware Tools Quiescence' = ConvertTo-TextYN $Bkjob.Options.ViSourceOptions.VMToolsQuiesce + 'Use Change Block Tracking' = ConvertTo-TextYN $Bkjob.Options.ViSourceOptions.UseChangeTracking + 'Enable CBT for all protected VMs' = ConvertTo-TextYN $Bkjob.Options.ViSourceOptions.EnableChangeTracking + 'Reset CBT On each Active Full Backup' = ConvertTo-TextYN $Bkjob.Options.ViSourceOptions.ResetChangeTrackingOnActiveFull + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Advanced Settings (vSphere) - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($InfoLevel.Jobs.Replication -ge 2 -and $Bkjob.Options.SanIntegrationOptions.UseSanSnapshots) { + Section -Style Heading6 "Advanced Settings (Integration)" { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) Integration options." + $inObj = [ordered] @{ + 'Enable Backup from Storage Snapshots' = ConvertTo-TextYN $Bkjob.Options.SanIntegrationOptions.UseSanSnapshots + 'Limit processed VM count per Storage Snapshot' = ConvertTo-TextYN $Bkjob.Options.SanIntegrationOptions.MultipleStorageSnapshotEnabled + 'VM count per Storage Snapshot' = $Bkjob.Options.SanIntegrationOptions.MultipleStorageSnapshotVmsCount + 'Failover to Standard Backup' = ConvertTo-TextYN $Bkjob.Options.SanIntegrationOptions.FailoverFromSan + 'Failover to Primary Storage Snapshot' = ConvertTo-TextYN $Bkjob.Options.SanIntegrationOptions.Failover2StorageSnapshotBackup + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Advanced Settings (Integration) - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($InfoLevel.Jobs.Replication -ge 2 -and ($Bkjob.Options.JobScriptCommand.PreScriptEnabled -or $Bkjob.Options.JobScriptCommand.PostScriptEnabled)) { + Section -Style Heading6 "Advanced Settings (Script)" { + $OutObj = @() + try { + if ($Bkjob.Options.JobScriptCommand.Periodicity -eq 'Days') { + $FrequencyValue = $Bkjob.Options.JobScriptCommand.Days -join "," + $FrequencyText = 'Run Script on the Selected Days' + } + elseif ($Bkjob.Options.JobScriptCommand.Periodicity -eq 'Cycles') { + $FrequencyValue = $Bkjob.Options.JobScriptCommand.Frequency + $FrequencyText = 'Run Script Every Backup Session' + } + Write-PscriboMessage "Discovered $($Bkjob.Name) script options." + $inObj = [ordered] @{ + 'Run the Following Script Before' = ConvertTo-TextYN $Bkjob.Options.JobScriptCommand.PreScriptEnabled + 'Run Script Before the Job' = $Bkjob.Options.JobScriptCommand.PreScriptCommandLine + 'Run the Following Script After' = ConvertTo-TextYN $Bkjob.Options.JobScriptCommand.PostScriptEnabled + 'Run Script After the Job' = $Bkjob.Options.JobScriptCommand.PostScriptCommandLine + 'Run Script Frequency' = $Bkjob.Options.JobScriptCommand.Periodicity + $FrequencyText = $FrequencyValue + + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Advanced Settings (Script) - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($InfoLevel.Jobs.Replication -ge 2 -and ($Bkjob.Options.RpoOptions.Enabled -or $Bkjob.Options.RpoOptions.LogBackupRpoEnabled)) { + Section -Style Heading6 "Advanced Settings (RPO Monitor)" { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) rpo monitor options." + $inObj = [ordered] @{ + 'RPO Monitor Enabled' = ConvertTo-TextYN $Bkjob.Options.RpoOptions.Enabled + 'If Backup is not Copied Within' = "$($Bkjob.Options.RpoOptions.Value) $($Bkjob.Options.RpoOptions.TimeUnit)" + 'Log Backup RPO Monitor Enabled' = ConvertTo-TextYN $Bkjob.Options.RpoOptions.LogBackupRpoEnabled + 'If Log Backup is not Copied Within' = "$($Bkjob.Options.RpoOptions.LogBackupRpoValue) $($Bkjob.Options.RpoOptions.LogBackupRpoTimeUnit)" + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Advanced Settings (RPO Monitor) - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + try { + Section -Style Heading5 'Data Transfer' { + $OutObj = @() + Write-PscriboMessage "Discovered $($Bkjob.Name) data transfer." + $inObj = [ordered] @{ + 'Source Proxy' = Switch (($Bkjob.GetProxy().Name).count) { + 0 {"Unknown"} + {$_ -gt 1} {"Automatic"} + default {$Bkjob.GetProxy().Name} + } + 'Target Proxy' = Switch (($Bkjob.GetTargetProxies().Name).count) { + 0 {"Unknown"} + {$_ -gt 1} {"Automatic"} + default {$Bkjob.GetTargetProxies().Name} + } + 'Use Wan accelerator' = ConvertTo-TextYN $Bkjob.IsWanAcceleratorEnabled() + } + if ($Bkjob.IsWanAcceleratorEnabled()) { + $inObj.add('Source Wan accelerator', $Bkjob.GetSourceWanAccelerator().Name) + $inObj.add('Target Wan accelerator',$Bkjob.GetTargetWanAccelerator().Name) + } + $OutObj += [pscustomobject]$inobj + + $TableParams = @{ + Name = "Data Transfer - $($Bkjob.Name)" + List = $True + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + if ($Bkjob.VssOptions.Enabled) { + Section -Style Heading5 "Guest Processing" { + $OutObj = @() + try { + $VSSObjs = Get-VBRJobObject -Job $Bkjob.Name | Where-Object {$_.Type -eq "Include" -or $_.Type -eq "VssChild"} + foreach ($VSSObj in $VSSObjs) { + Write-PscriboMessage "Discovered $($Bkjob.Name) guest processing." + $inObj = [ordered] @{ + 'Name' = $VSSObj.Name + 'Enabled' = ConvertTo-TextYN $Bkjob.VssOptions.Enabled + 'Resource Type' = ($Bkjob.GetViOijs() | Where-Object {$_.Name -eq $VSSObj.Name -and ($_.Type -eq "Include" -or $_.Type -eq "VssChild")}).TypeDisplayName + 'Ignore Errors' = ConvertTo-TextYN $VSSObj.VssOptions.IgnoreErrors + 'Guest Proxy Auto Detect' = ConvertTo-TextYN $VSSObj.VssOptions.GuestProxyAutoDetect + 'Default Credential' = Switch ((Get-VBRCredentials | Where-Object { $_.Id -eq $Bkjob.VssOptions.WinCredsId.Guid}).count) { + 0 {'None'} + Default {Get-VBRCredentials | Where-Object { $_.Id -eq $Bkjob.VssOptions.WinCredsId.Guid}} + } + 'Object Credential' = Switch ($VSSObj.VssOptions.WinCredsId.Guid) { + '00000000-0000-0000-0000-000000000000' {'Default Credential'} + default {Get-VBRCredentials | Where-Object { $_.Id -eq $VSSObj.VssOptions.WinCredsId.Guid}} + } + 'Application Processing' = ConvertTo-TextYN $VSSObj.VssOptions.VssSnapshotOptions.ApplicationProcessingEnabled + 'Transaction Logs' = Switch ($VSSObj.VssOptions.VssSnapshotOptions.IsCopyOnly) { + 'False' {'Process Transaction Logs'} + 'True' {'Perform Copy Only'} + } + 'Use Persistent Guest Agent' = ConvertTo-TextYN $VSSObj.VssOptions.VssSnapshotOptions.UsePersistentGuestAgent + } + if ($InfoLevel.Jobs.Replication -ge 2) { + if (!$VSSObj.VssOptions.VssSnapshotOptions.IsCopyOnly) { + $TransactionLogsProcessing = Switch ($VSSObj.VssOptions.SqlBackupOptions.TransactionLogsProcessing) { + 'TruncateOnlyOnSuccessJob' {'Truncate logs'} + 'Backup' {'Backup logs periodically'} + 'NeverTruncate' {'Do not truncate logs'} + } + $RetainLogBackups = Switch ($VSSObj.VssOptions.SqlBackupOptions.UseDbBackupRetention) { + 'True' {'Until the corresponding image-level backup is deleted'} + 'False' {"Keep Only Last $($VSSObj.VssOptions.SqlBackupOptions.RetainDays) days of log backups"} + } + $inObj.add('SQL Transaction Logs Processing', ($TransactionLogsProcessing)) + $inObj.add('SQL Backup Log Every', ("$($VSSObj.VssOptions.SqlBackupOptions.BackupLogsFrequencyMin) min")) + $inObj.add('SQL Retain Log Backups', $($RetainLogBackups)) + } + if ($VSSObj.VssOptions.OracleBackupOptions.BackupLogsEnabled -or $VSSObj.VssOptions.OracleBackupOptions.ArchivedLogsTruncation) { + $ArchivedLogsTruncation = Switch ($VSSObj.VssOptions.OracleBackupOptions.ArchivedLogsTruncation) { + 'ByAge' {"Delete Log Older Than $($VSSObj.VssOptions.OracleBackupOptions.ArchivedLogsMaxAgeHours) hours"} + 'BySize' {"Delete Log Over $([Math]::Round($VSSObj.VssOptions.OracleBackupOptions.ArchivedLogsMaxSizeMb / 1024, 0)) GB"} + default {$VSSObj.VssOptions.OracleBackupOptions.ArchivedLogsTruncation} + + } + $SysdbaCredsId = Switch ($VSSObj.VssOptions.OracleBackupOptions.SysdbaCredsId) { + '00000000-0000-0000-0000-000000000000' {'Guest OS Credential'} + default {(Get-VBRCredentials | Where-Object { $_.Id -eq $VSSObj.VssOptions.OracleBackupOptions.SysdbaCredsId}).Description} + } + $RetainLogBackups = Switch ($VSSObj.VssOptions.OracleBackupOptions.UseDbBackupRetention) { + 'True' {'Until the corresponding image-level backup is deleted'} + 'False' {"Keep Only Last $($VSSObj.VssOptions.OracleBackupOptions.RetainDays) days of log backups"} + } + $inObj.add('Oracle Account Type', $VSSObj.VssOptions.OracleBackupOptions.AccountType) + $inObj.add('Oracle Sysdba Creds', $SysdbaCredsId) + if ($VSSObj.VssOptions.OracleBackupOptions.BackupLogsEnabled) { + $inObj.add('Oracle Backup Logs Every', ("$($VSSObj.VssOptions.OracleBackupOptions.BackupLogsFrequencyMin) min")) + } + $inObj.add('Oracle Archive Logs', ($ArchivedLogsTruncation)) + $inObj.add('Oracle Retain Log Backups', $($RetainLogBackups)) + } + if ($VSSObj.VssOptions.GuestFSExcludeOptions.FileExcludeEnabled) { + $inObj.add('File Exclusions', (ConvertTo-TextYN $VSSObj.VssOptions.GuestFSExcludeOptions.FileExcludeEnabled)) + if ($VSSObj.VssOptions.GuestFSExcludeOptions.BackupScope -eq 'ExcludeSpecifiedFolders') { + $inObj.add('Exclude the following file and folders', ($VSSObj.VssOptions.GuestFSExcludeOptions.ExcludeList -join ',')) + } + elseif ($VSSObj.VssOptions.GuestFSExcludeOptions.BackupScope -eq 'IncludeSpecifiedFolders') { + $inObj.add('Include only the following file and folders', ($VSSObj.VssOptions.GuestFSExcludeOptions.IncludeList-join ',')) + } + } + if ($VSSObj.VssOptions.GuestScriptsOptions.ScriptingMode -ne 'Disabled') { + $ScriptingMode = Switch ($VSSObj.VssOptions.GuestScriptsOptions.ScriptingMode) { + 'FailJobOnError' {'Require successfull script execution'} + 'IgnoreErrors' {'Ignore script execution failures'} + 'Disabled' {'Disable script execution'} + } + $inObj.add('Scripts', (ConvertTo-TextYN $VSSObj.VssOptions.GuestScriptsOptions.IsAtLeastOneScriptSet)) + $inObj.add('Scripts Mode', ($ScriptingMode)) + if ($VSSObj.VssOptions.GuestScriptsOptions.WinScriptFiles.IsAtLeastOneScriptSet) { + $inObj.add('Windows Pre-freeze script', ($VSSObj.VssOptions.GuestScriptsOptions.WinScriptFiles.PreScriptFilePath)) + $inObj.add('Windows Post-thaw script', ($VSSObj.VssOptions.GuestScriptsOptions.WinScriptFiles.PostScriptFilePath)) + } + elseif ($VSSObj.VssOptions.GuestScriptsOptions.LinScriptFiles.IsAtLeastOneScriptSet) { + $inObj.add('Linux Pre-freeze script', ($VSSObj.VssOptions.GuestScriptsOptions.LinScriptFiles.PreScriptFilePath)) + $inObj.add('Linux Post-thaw script', ($VSSObj.VssOptions.GuestScriptsOptions.LinScriptFiles.PostScriptFilePath)) + } + } + } + + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Guest Processing Options - $($VSSObj.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($Bkjob.GetScheduleOptions().NextRun -and $Bkjob.ScheduleOptions.OptionsContinuous.Enabled -ne "True") { + Section -Style Heading5 "Schedule" { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) schedule options." + if ($Bkjob.ScheduleOptions.OptionsDaily.Enabled -eq "True") { + $ScheduleType = "Daily" + $Schedule = "Kind: $($Bkjob.ScheduleOptions.OptionsDaily.Kind),`r`nDays: $($Bkjob.ScheduleOptions.OptionsDaily.DaysSrv)" + } + elseif ($Bkjob.ScheduleOptions.OptionsMonthly.Enabled -eq "True") { + $ScheduleType = "Monthly" + $Schedule = "Day Of Month: $($Bkjob.ScheduleOptions.OptionsMonthly.DayOfMonth),`r`nDay Number In Month: $($Bkjob.ScheduleOptions.OptionsMonthly.DayNumberInMonth),`r`nDay Of Week: $($Bkjob.ScheduleOptions.OptionsMonthly.DayOfWeek)" + } + elseif ($Bkjob.ScheduleOptions.OptionsPeriodically.Enabled -eq "True") { + $ScheduleType = "Hours" + $Schedule = "Full Period: $($Bkjob.ScheduleOptions.OptionsPeriodically.FullPeriod),`r`nHourly Offset: $($Bkjob.ScheduleOptions.OptionsPeriodically.HourlyOffset),`r`nUnit: $($Bkjob.ScheduleOptions.OptionsPeriodically.Unit)" + } + $inObj = [ordered] @{ + 'Retry Failed item' = $Bkjob.ScheduleOptions.RetryTimes + 'Wait before each retry' = "$($Bkjob.ScheduleOptions.RetryTimeout)/min" + 'Backup Window' = ConvertTo-TextYN $Bkjob.ScheduleOptions.OptionsBackupWindow.IsEnabled + 'Shedule type' = $ScheduleType + 'Shedule Options' = $Schedule + 'Start Time' = $Bkjob.ScheduleOptions.OptionsDaily.TimeLocal.ToShorttimeString() + 'Latest Run' = $Bkjob.LatestRunLocal + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Schedule Options - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + end {} + +} diff --git a/Src/Public/Invoke-AsBuiltReport.Veeam.VBR.ps1 b/Src/Public/Invoke-AsBuiltReport.Veeam.VBR.ps1 index 2558f2f..e711879 100644 --- a/Src/Public/Invoke-AsBuiltReport.Veeam.VBR.ps1 +++ b/Src/Public/Invoke-AsBuiltReport.Veeam.VBR.ps1 @@ -190,8 +190,8 @@ function Invoke-AsBuiltReport.Veeam.VBR { #---------------------------------------------------------------------------------------------# if ($InfoLevel.Jobs.PSObject.Properties.Value -ne 0) { if (((Get-VBRJob -WarningAction SilentlyContinue).count -gt 0) -or ((Get-VBRTapeJob).count -gt 0) -or ((Get-VBRSureBackupJob).count -gt 0)) { - Section -Style Heading2 'Backup Jobs Summary' { - Paragraph "The following section provides information about backup jobs on Veeam Server: $(((Get-VBRServerSession).Server))." + Section -Style Heading2 'Jobs Summary' { + Paragraph "The following section provides information about configured jobs in Veeam Server: $(((Get-VBRServerSession).Server))." BlankLine Write-PScriboMessage "Backup Jobs InfoLevel set at $($InfoLevel.Jobs.Backup)." if ($InfoLevel.Jobs.Backup -ge 1) { @@ -199,6 +199,12 @@ function Invoke-AsBuiltReport.Veeam.VBR { Get-AbrVbrBackupjobVMware Get-AbrVbrBackupjobHyperV } + Write-PScriboMessage "Replication Jobs InfoLevel set at $($InfoLevel.Jobs.Replication)." + if ($InfoLevel.Jobs.Replication -ge 1) { + Get-AbrVbrRepljob + Get-AbrVbrRepljobVMware + #Get-AbrVbrRepljobHyperV + } Write-PScriboMessage "Tape Jobs InfoLevel set at $($InfoLevel.Jobs.Tape)." if ($InfoLevel.Jobs.Tape -ge 1) { Get-AbrVbrTapejob From ef123fb1276423e68bdf5759e92f78c5e99a27e0 Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Tue, 10 May 2022 21:19:31 -0400 Subject: [PATCH 04/12] Added more replication job configuration fixrs --- README.md | 1 + Src/Private/Get-AbrVbrBackupjobHyperV.ps1 | 28 +- Src/Private/Get-AbrVbrRepljobHyperV.ps1 | 762 ++++++++++++++++++ Src/Private/Get-AbrVbrRepljobVMware.ps1 | 160 ++-- Src/Public/Invoke-AsBuiltReport.Veeam.VBR.ps1 | 2 +- 5 files changed, 877 insertions(+), 76 deletions(-) create mode 100644 Src/Private/Get-AbrVbrRepljobHyperV.ps1 diff --git a/README.md b/README.md index 9051d52..4ee4e95 100644 --- a/README.md +++ b/README.md @@ -194,6 +194,7 @@ The table below outlines the default and maximum **InfoLevel** settings for each | Tape | 1 | 2 | | Surebackup | 1 | 2 | | Agent | 1 | 2 | +| Replication | 1 | 2 | The table below outlines the default and maximum **InfoLevel** settings for each Replication section. diff --git a/Src/Private/Get-AbrVbrBackupjobHyperV.ps1 b/Src/Private/Get-AbrVbrBackupjobHyperV.ps1 index 571f0f8..4d53b39 100644 --- a/Src/Private/Get-AbrVbrBackupjobHyperV.ps1 +++ b/Src/Private/Get-AbrVbrBackupjobHyperV.ps1 @@ -28,7 +28,7 @@ function Get-AbrVbrBackupjobHyperV { try { $Bkjobs = Get-VBRJob -WarningAction SilentlyContinue | Where-Object {$_.TypeToString -eq "Hyper-V Backup" -or $_.TypeToString -eq "Hyper-V Backup Copy"} if (($Bkjobs).count -gt 0) { - Section -Style Heading3 'Hyper-V Backup Configuration' { + Section -Style Heading3 'Hyper-V Backup Jobs Configuration' { Paragraph "The following section details Hyper-V backup jobs configuration." BlankLine $OutObj = @() @@ -300,8 +300,8 @@ function Get-AbrVbrBackupjobHyperV { Write-PscriboMessage "Discovered $($Bkjob.Name) storage options." $inObj = [ordered] @{ 'Inline Data Deduplication' = ConvertTo-TextYN $Bkjob.Options.BackupStorageOptions.EnableDeduplication - 'Exclude Swap Files Block' = ConvertTo-TextYN $Bkjob.ViSourceOptions.ExcludeSwapFile - 'Exclude Deleted Files Block' = ConvertTo-TextYN $Bkjob.ViSourceOptions.DirtyBlocksNullingEnabled + 'Exclude Swap Files Block' = ConvertTo-TextYN $Bkjob.HvSourceOptions.ExcludeSwapFile + 'Exclude Deleted Files Block' = ConvertTo-TextYN $Bkjob.HvSourceOptions.DirtyBlocksNullingEnabled 'Compression Level' = Switch ($Bkjob.Options.BackupStorageOptions.CompressionLevel) { 0 {'NONE'} -1 {'AUTO'} @@ -356,9 +356,9 @@ function Get-AbrVbrBackupjobHyperV { 'Notify On Warning' = ConvertTo-TextYN $Bkjob.Options.NotificationOptions.EmailNotifyOnWarning 'Notify On Error' = ConvertTo-TextYN $Bkjob.Options.NotificationOptions.EmailNotifyOnError 'Suppress Notification until Last Retry' = ConvertTo-TextYN $Bkjob.Options.NotificationOptions.EmailNotifyOnLastRetryOnly - 'Set Results To Vm Notes' = ConvertTo-TextYN $Bkjob.Options.ViSourceOptions.SetResultsToVmNotes - 'VM Attribute Note Value' = $Bkjob.Options.ViSourceOptions.VmAttributeName - 'Append to Existing Attribute' = ConvertTo-TextYN $Bkjob.Options.ViSourceOptions.VmNotesAppend + 'Set Results To Vm Notes' = ConvertTo-TextYN $Bkjob.Options.HvSourceOptions.SetResultsToVmNotes + 'VM Attribute Note Value' = $Bkjob.Options.HvSourceOptions.VmAttributeName + 'Append to Existing Attribute' = ConvertTo-TextYN $Bkjob.Options.HvSourceOptions.VmNotesAppend } $OutObj = [pscustomobject]$inobj @@ -377,21 +377,21 @@ function Get-AbrVbrBackupjobHyperV { } } } - if ($InfoLevel.Jobs.Backup -ge 2 -and ($Bkjob.Options.ViSourceOptions.VMToolsQuiesce -or $Bkjob.Options.ViSourceOptions.UseChangeTracking)) { - Section -Style Heading6 "Advanced Settings (vSphere)" { + if ($InfoLevel.Jobs.Backup -ge 2 -and ($Bkjob.Options.HvSourceOptions.EnableHvQuiescence -or $Bkjob.Options.HvSourceOptions.UseChangeTracking)) { + Section -Style Heading6 "Advanced Settings (Hyper-V)" { $OutObj = @() try { - Write-PscriboMessage "Discovered $($Bkjob.Name) vSphere options." + Write-PscriboMessage "Discovered $($Bkjob.Name) Hyper-V options." $inObj = [ordered] @{ - 'Enable Hyper-V Guest Quiescence' = ConvertTo-TextYN $Bkjob.Options.ViSourceOptions.VMToolsQuiesce - 'Use Change Block Tracking' = ConvertTo-TextYN $Bkjob.Options.ViSourceOptions.UseChangeTracking - 'Enable CBT for all protected VMs' = ConvertTo-TextYN $Bkjob.Options.ViSourceOptions.EnableChangeTracking - 'Reset CBT On each Active Full Backup' = ConvertTo-TextYN $Bkjob.Options.ViSourceOptions.ResetChangeTrackingOnActiveFull + 'Enable Hyper-V Guest Quiescence' = ConvertTo-TextYN $Bkjob.Options.HvSourceOptions.EnableHvQuiescence + 'Crash Consistent Backup' = ConvertTo-TextYN $Bkjob.Options.HvSourceOptions.CanDoCrashConsistent + 'Use Change Block Tracking' = ConvertTo-TextYN $Bkjob.Options.HvSourceOptions.UseChangeTracking + 'Volume Snapshot' = ConvertTo-TextYN $Bkjob.Options.HvSourceOptions.GroupSnapshotProcessing } $OutObj = [pscustomobject]$inobj $TableParams = @{ - Name = "Advanced Settings (vSphere) - $($Bkjob.Name)" + Name = "Advanced Settings (Hyper-V) - $($Bkjob.Name)" List = $true ColumnWidths = 40, 60 } diff --git a/Src/Private/Get-AbrVbrRepljobHyperV.ps1 b/Src/Private/Get-AbrVbrRepljobHyperV.ps1 new file mode 100644 index 0000000..c54ba38 --- /dev/null +++ b/Src/Private/Get-AbrVbrRepljobHyperV.ps1 @@ -0,0 +1,762 @@ + +function Get-AbrVbrRepljobHyperV { + <# + .SYNOPSIS + Used by As Built Report to returns hyper-v replication jobs created in Veeam Backup & Replication. + .DESCRIPTION + Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. + .NOTES + Version: 0.5.0 + Author: Jonathan Colon + Twitter: @jcolonfzenpr + Github: rebelinux + Credits: Iain Brighton (@iainbrighton) - PScribo module + + .LINK + https://github.com/AsBuiltReport/AsBuiltReport.Veeam.VBR + #> + [CmdletBinding()] + param ( + + ) + + begin { + Write-PscriboMessage "Discovering Veeam VBR Hyper-V replication jobs information from $System." + } + + process { + try { + $Bkjobs = Get-VBRJob -WarningAction SilentlyContinue | Where-object {$_.TypeToString -eq 'Hyper-V Replication'} + if (($Bkjobs).count -gt 0) { + Section -Style Heading3 'Hyper-V Replication Jobs Configuration' { + Paragraph "The following section details Hyper-V type per backup jobs configuration." + BlankLine + $OutObj = @() + try { + $VMcounts = Get-VBRJob -WarningAction SilentlyContinue | Where-object {$_.TypeToString -eq 'Hyper-V Replication'} + if ($VMcounts) { + foreach ($VMcount in $VMcounts) { + try { + Write-PscriboMessage "Discovered $($VMcount.Name) ." + $inObj = [ordered] @{ + 'Name' = $VMcount.Name + 'Creation Time' = $VMcount.CreationTime + 'VM Count' = (Get-VBRReplica | Where-Object {$_.JobName -eq $VMcount.Name}).VMcount + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + + $TableParams = @{ + Name = "Hyper-V Replication Summary - $(((Get-VBRServerSession).Server).ToString().ToUpper().Split(".")[0])" + List = $false + ColumnWidths = 35, 35, 30 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Sort-Object -Property 'Name' | Table @TableParams + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + $OutObj = @() + foreach ($Bkjob in $Bkjobs) { + try { + Section -Style Heading4 "$($Bkjob.Name) Configuration" { + Section -Style Heading5 'Common Information' { + $OutObj = @() + try { + $CommonInfos = (Get-VBRJob -WarningAction SilentlyContinue | Where-object {$_.TypeToString -eq 'Hyper-V Replication'}).Info + foreach ($CommonInfo in $CommonInfos) { + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) common information." + $inObj = [ordered] @{ + 'Name' = $Bkjob.Name + 'Type' = $Bkjob.TypeToString + 'Total Backup Size' = ConvertTo-FileSizeString $CommonInfo.IncludedSize + 'Target Address' = $CommonInfo.TargetDir + 'Target File' = $CommonInfo.TargetFile + 'Description' = $CommonInfo.CommonInfo.Description + 'Modified By' = $CommonInfo.CommonInfo.ModifiedBy.FullName + } + $OutObj = [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + + $TableParams = @{ + Name = "Common Information - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + Section -Style Heading5 'Destination' { + $OutObj = @() + try { + foreach ($Destination in $Bkjob.HvReplicaTargetOptions) { + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) destination information." + if (!$Destination.ClusterName) { + $HostorCluster = (Find-VBRHvEntity -ErrorAction SilentlyContinue | Where-Object { $_.Reference -eq $Destination.HostReference}).Name + } else {$HostorCluster = $Destination.ClusterName} + $inObj = [ordered] @{ + 'Host or Cluster' = Switch ($HostorCluster) { + $Null {'Unknown'} + default {$HostorCluster} + } + + 'Path' = $Destination.TargetFolder + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + + $TableParams = @{ + Name = "Destination - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + if ($Bkjob.HvReplicaTargetOptions.UseNetworkMapping) { + Section -Style Heading5 'Network' { + $OutObj = @() + try { + foreach ($NetMapping in $Bkjob.Options.HvNetworkMappingOptions.NetworkMapping) { + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) network mapping information." + $inObj = [ordered] @{ + 'Source Network' = $NetMapping.SourceNetwork.NetworkName + 'Target Network' = $NetMapping.TargetNetwork.NetworkName + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + + $TableParams = @{ + Name = "Network Mappings - $($Bkjob.Name)" + List = $false + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Sort-Object -Property 'Source Network' | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($Bkjob.Options.HvReplicaTargetOptions.UseReIP) { + Section -Style Heading5 'Re-IP Rules' { + $OutObj = @() + try { + foreach ($ReIpRule in $Bkjob.Options.ReIPRulesOptions.Rules) { + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) re-ip rules $($ReIpRule.Source.IPAddress) information." + $inObj = [ordered] @{ + 'Source IP Address' = $ReIpRule.Source.IPAddress + 'Source Subnet Mask' = $ReIpRule.Source.SubnetMask + 'Target P Address' = $ReIpRule.Target.IPAddress + 'Target Subnet Mask' = $ReIpRule.Target.SubnetMask + 'Target Default Gateway' = $ReIpRule.Target.DefaultGateway + 'Target DNS Addresses' = $ReIpRule.Target.DNSAddresses + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + + $TableParams = @{ + Name = "Re-IP Rules - $($Bkjob.Name)" + List = $false + ColumnWidths = 17, 17, 17, 17, 16, 16 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Sort-Object -Property 'Source IP Address' | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($Bkjob.GetHvOijs()) { + Section -Style Heading5 "Virtual Machines" { + $OutObj = @() + try { + foreach ($OBJ in ($Bkjob.GetHvOijs() | Where-Object {$_.Type -eq "Include" -or $_.Type -eq "Exclude"} )) { + Write-PscriboMessage "Discovered $($OBJ.Object.Name) object to replicate." + $inObj = [ordered] @{ + 'Name' = $OBJ.Object.Name + 'Resource Type' = $OBJ.Object.Type + 'Role' = $OBJ.Type + 'Location' = $OBJ.Location + 'Disk Filter Mode' = $OBJ.DiskFilterInfo.Mode + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Virtual Machines - $($OBJ.Object.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + Section -Style Heading5 'Job Settings' { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) storage options." + if ($Bkjob.BackupStorageOptions.RetentionType -eq "Days") { + $RetainString = 'Restore Point To Keep' + $Retains = $Bkjob.BackupStorageOptions.RetainDaysToKeep + } + elseif ($Bkjob.BackupStorageOptions.RetentionType -eq "Cycles") { + $RetainString = 'Retain Cycles' + $Retains = $Bkjob.BackupStorageOptions.RetainCycles + } + $inObj = [ordered] @{ + 'Repository for replica metadata' = Switch ($Bkjob.info.TargetRepositoryId) { + '00000000-0000-0000-0000-000000000000' {$Bkjob.TargetDir} + {$Null -eq (Get-VBRBackupRepository | Where-Object {$_.Id -eq $Bkjob.info.TargetRepositoryId}).Name} {(Get-VBRBackupRepository -ScaleOut | Where-Object {$_.Id -eq $Bkjob.info.TargetRepositoryId}).Name} + default {(Get-VBRBackupRepository | Where-Object {$_.Id -eq $Bkjob.info.TargetRepositoryId}).Name} + } + 'Replica Name Suffix' = $Bkjob.Options.HvReplicaTargetOptions.ReplicaNameSuffix + $RetainString = $Retains + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "$Storage Options - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + if ($InfoLevel.Jobs.Replication -ge 2 -and ($Bkjob.Options.GenerationPolicy.EnableRechek -or $Bkjob.Options.GenerationPolicy.EnableCompactFull)) { + Section -Style Heading6 "Advanced Settings (Maintenance)" { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) maintenance options." + $inObj = [ordered] @{ + 'Storage-Level Corruption Guard (SLCG)' = ConvertTo-TextYN $Bkjob.Options.GenerationPolicy.EnableRechek + 'SLCG Schedule Type' = $Bkjob.Options.GenerationPolicy.RecheckScheduleKind + 'SLCG Schedule Day' = $Bkjob.Options.GenerationPolicy.RecheckDays + 'SLCG Backup Monthly Schedule' = "Day Of Week: $($Bkjob.Options.GenerationPolicy.RecheckBackupMonthlyScheduleOptions.DayOfWeek)`r`nDay Number In Month: $($Bkjob.Options.GenerationPolicy.RecheckBackupMonthlyScheduleOptions.DayNumberInMonth)`r`nDay of Month: $($Bkjob.Options.GenerationPolicy.RecheckBackupMonthlyScheduleOptions.DayOfMonth)`r`nMonths: $($Bkjob.Options.GenerationPolicy.RecheckBackupMonthlyScheduleOptions.Months)" + 'Defragment and Compact Full Backup (DCFB)' = ConvertTo-TextYN $Bkjob.Options.GenerationPolicy.EnableCompactFull + 'DCFB Schedule Type' = $Bkjob.Options.GenerationPolicy.CompactFullBackupScheduleKind + 'DCFB Schedule Day' = $Bkjob.Options.GenerationPolicy.CompactFullBackupDays + 'DCFB Backup Monthly Schedule' = "Day Of Week: $($Bkjob.Options.GenerationPolicy.CompactFullBackupMonthlyScheduleOptions.DayOfWeek)`r`nDay Number In Month: $($Bkjob.Options.GenerationPolicy.CompactFullBackupMonthlyScheduleOptions.DayNumberInMonth)`r`nDay of Month: $($Bkjob.Options.GenerationPolicy.CompactFullBackupMonthlyScheduleOptions.DayOfMonth)`r`nMonths: $($Bkjob.Options.GenerationPolicy.CompactFullBackupMonthlyScheduleOptions.Months)" + 'Remove deleted item data after' = $Bkjob.Options.BackupStorageOptions.RetainDays + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Advanced Settings (Maintenance) - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($InfoLevel.Jobs.Replication -ge 2) { + Section -Style Heading6 "Advanced Settings (Traffic)" { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) traffic options." + $inObj = [ordered] @{ + 'Inline Data Deduplication' = ConvertTo-TextYN $Bkjob.Options.BackupStorageOptions.EnableDeduplication + 'Exclude Swap Files Block' = ConvertTo-TextYN $Bkjob.HvSourceOptions.ExcludeSwapFile + 'Exclude Deleted Files Block' = ConvertTo-TextYN $Bkjob.HvSourceOptions.DirtyBlocksNullingEnabled + 'Compression Level' = Switch ($Bkjob.Options.BackupStorageOptions.CompressionLevel) { + 0 {'NONE'} + -1 {'AUTO'} + 4 {'DEDUPE_friendly'} + 5 {'OPTIMAL (Default)'} + 6 {'High'} + 9 {'EXTREME'} + } + 'Storage optimization' = Switch ($Bkjob.Options.BackupStorageOptions.StgBlockSize) { + 'KbBlockSize1024' {'Local target'} + 'KbBlockSize512' {'LAN target'} + 'KbBlockSize256' {'WAN target'} + 'KbBlockSize4096' {'Local target (large blocks)'} + default {$Bkjob.Options.BackupStorageOptions.StgBlockSize} + } + 'Enabled Backup File Encryption' = ConvertTo-TextYN $Bkjob.Options.BackupStorageOptions.StorageEncryptionEnabled + 'Encryption Key' = Switch ($Bkjob.Options.BackupStorageOptions.StorageEncryptionEnabled) { + $false {'None'} + default {(Get-VBREncryptionKey | Where-Object { $_.id -eq $Bkjob.Info.PwdKeyId }).Description} + } + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Advanced Settings (Traffic) - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($InfoLevel.Jobs.Replication -ge 2 -and ($Bkjob.Options.NotificationOptions.SnmpNotification -or $Bkjob.Options.NotificationOptions.SendEmailNotification2AdditionalAddresses)) { + Section -Style Heading6 "Advanced Settings (Notification)" { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) notification options." + $inObj = [ordered] @{ + 'Send Snmp Notification' = ConvertTo-TextYN $Bkjob.Options.NotificationOptions.SnmpNotification + 'Send Email Notification' = ConvertTo-TextYN $Bkjob.Options.NotificationOptions.SendEmailNotification2AdditionalAddresses + 'Email Notification Additional Addresses' = $Bkjob.Options.NotificationOptions.EmailNotificationAdditionalAddresses + 'Email Notify Time' = $Bkjob.Options.NotificationOptions.EmailNotifyTime.ToShortTimeString() + 'Use Custom Email Notification Options' = ConvertTo-TextYN $Bkjob.Options.NotificationOptions.UseCustomEmailNotificationOptions + 'Use Custom Notification Setting' = $Bkjob.Options.NotificationOptions.EmailNotificationSubject + 'Notify On Success' = ConvertTo-TextYN $Bkjob.Options.NotificationOptions.EmailNotifyOnSuccess + 'Notify On Warning' = ConvertTo-TextYN $Bkjob.Options.NotificationOptions.EmailNotifyOnWarning + 'Notify On Error' = ConvertTo-TextYN $Bkjob.Options.NotificationOptions.EmailNotifyOnError + 'Suppress Notification until Last Retry' = ConvertTo-TextYN $Bkjob.Options.NotificationOptions.EmailNotifyOnLastRetryOnly + 'Set Results To Vm Notes' = ConvertTo-TextYN $Bkjob.Options.HvSourceOptions.SetResultsToVmNotes + 'VM Attribute Note Value' = $Bkjob.Options.HvSourceOptions.VmAttributeName + 'Append to Existing Attribute' = ConvertTo-TextYN $Bkjob.Options.HvSourceOptions.VmNotesAppend + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Advanced Settings (Notification) - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($InfoLevel.Jobs.Replication -ge 2 -and ($Bkjob.Options.HvSourceOptions.EnableHvQuiescence -or $Bkjob.Options.HvSourceOptions.UseChangeTracking)) { + Section -Style Heading6 "Advanced Settings (Hyper-V)" { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) Hyper-V options." + $inObj = [ordered] @{ + 'Enable Hyper-V Guest Quiescence' = ConvertTo-TextYN $Bkjob.Options.HvSourceOptions.EnableHvQuiescence + 'Crash Consistent Backup' = ConvertTo-TextYN $Bkjob.Options.HvSourceOptions.CanDoCrashConsistent + 'Use Change Block Tracking' = ConvertTo-TextYN $Bkjob.Options.HvSourceOptions.UseChangeTracking + 'Volume Snapshot' = ConvertTo-TextYN $Bkjob.Options.HvSourceOptions.GroupSnapshotProcessing + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Advanced Settings (Hyper-V) - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($InfoLevel.Jobs.Replication -ge 2 -and $Bkjob.Options.SanIntegrationOptions.UseSanSnapshots) { + Section -Style Heading6 "Advanced Settings (Integration)" { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) Integration options." + $inObj = [ordered] @{ + 'Enable Backup from Storage Snapshots' = ConvertTo-TextYN $Bkjob.Options.SanIntegrationOptions.UseSanSnapshots + 'Limit processed VM count per Storage Snapshot' = ConvertTo-TextYN $Bkjob.Options.SanIntegrationOptions.MultipleStorageSnapshotEnabled + 'VM count per Storage Snapshot' = $Bkjob.Options.SanIntegrationOptions.MultipleStorageSnapshotVmsCount + 'Failover to Standard Backup' = ConvertTo-TextYN $Bkjob.Options.SanIntegrationOptions.FailoverFromSan + 'Failover to Primary Storage Snapshot' = ConvertTo-TextYN $Bkjob.Options.SanIntegrationOptions.Failover2StorageSnapshotBackup + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Advanced Settings (Integration) - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($InfoLevel.Jobs.Replication -ge 2 -and ($Bkjob.Options.JobScriptCommand.PreScriptEnabled -or $Bkjob.Options.JobScriptCommand.PostScriptEnabled)) { + Section -Style Heading6 "Advanced Settings (Script)" { + $OutObj = @() + try { + if ($Bkjob.Options.JobScriptCommand.Periodicity -eq 'Days') { + $FrequencyValue = $Bkjob.Options.JobScriptCommand.Days -join "," + $FrequencyText = 'Run Script on the Selected Days' + } + elseif ($Bkjob.Options.JobScriptCommand.Periodicity -eq 'Cycles') { + $FrequencyValue = $Bkjob.Options.JobScriptCommand.Frequency + $FrequencyText = 'Run Script Every Backup Session' + } + Write-PscriboMessage "Discovered $($Bkjob.Name) script options." + $inObj = [ordered] @{ + 'Run the Following Script Before' = ConvertTo-TextYN $Bkjob.Options.JobScriptCommand.PreScriptEnabled + 'Run Script Before the Job' = $Bkjob.Options.JobScriptCommand.PreScriptCommandLine + 'Run the Following Script After' = ConvertTo-TextYN $Bkjob.Options.JobScriptCommand.PostScriptEnabled + 'Run Script After the Job' = $Bkjob.Options.JobScriptCommand.PostScriptCommandLine + 'Run Script Frequency' = $Bkjob.Options.JobScriptCommand.Periodicity + $FrequencyText = $FrequencyValue + + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Advanced Settings (Script) - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($InfoLevel.Jobs.Replication -ge 2 -and ($Bkjob.Options.RpoOptions.Enabled -or $Bkjob.Options.RpoOptions.LogBackupRpoEnabled)) { + Section -Style Heading6 "Advanced Settings (RPO Monitor)" { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) rpo monitor options." + $inObj = [ordered] @{ + 'RPO Monitor Enabled' = ConvertTo-TextYN $Bkjob.Options.RpoOptions.Enabled + 'If Backup is not Copied Within' = "$($Bkjob.Options.RpoOptions.Value) $($Bkjob.Options.RpoOptions.TimeUnit)" + 'Log Backup RPO Monitor Enabled' = ConvertTo-TextYN $Bkjob.Options.RpoOptions.LogBackupRpoEnabled + 'If Log Backup is not Copied Within' = "$($Bkjob.Options.RpoOptions.LogBackupRpoValue) $($Bkjob.Options.RpoOptions.LogBackupRpoTimeUnit)" + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Advanced Settings (RPO Monitor) - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + try { + Section -Style Heading5 'Data Transfer' { + $OutObj = @() + Write-PscriboMessage "Discovered $($Bkjob.Name) data transfer." + $inObj = [ordered] @{ + 'Source Proxy' = Switch (($Bkjob.GetProxy().Name).count) { + 0 {"Unknown"} + {$_ -gt 1} {"Automatic"} + default {$Bkjob.GetProxy().Name} + } + 'Target Proxy' = Switch (($Bkjob.GetTargetProxies().Name).count) { + 0 {"Unknown"} + {$_ -gt 1} {"Automatic"} + default {$Bkjob.GetTargetProxies().Name} + } + 'Use Wan accelerator' = ConvertTo-TextYN $Bkjob.IsWanAcceleratorEnabled() + } + if ($Bkjob.IsWanAcceleratorEnabled()) { + $inObj.add('Source Wan accelerator', $Bkjob.GetSourceWanAccelerator().Name) + $inObj.add('Target Wan accelerator',$Bkjob.GetTargetWanAccelerator().Name) + } + $OutObj += [pscustomobject]$inobj + + $TableParams = @{ + Name = "Data Transfer - $($Bkjob.Name)" + List = $True + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + if ($Bkjob.Options.HvReplicaTargetOptions.InitialSeeding) { + try { + Section -Style Heading5 'Seeding' { + $OutObj = @() + Write-PscriboMessage "Discovered $($Bkjob.Name) seeding information." + if ($Bkjob.Options.HvReplicaTargetOptions.EnableInitialPass) { + $SeedRepo = $Bkjob.GetInitialRepository().Name + } else {$SeedRepo = 'Disabled'} + $inObj = [ordered] @{ + 'Seed from Backup Repository' = $SeedRepo + 'Map Replica to Existing VM' = ConvertTo-TextYN $Bkjob.Options.HvReplicaTargetOptions.UseVmMapping + } + + $OutObj += [pscustomobject]$inobj + + $TableParams = @{ + Name = "Seeding - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + if ($Bkjob.VssOptions.Enabled) { + Section -Style Heading5 "Guest Processing" { + $OutObj = @() + try { + $VSSObjs = Get-VBRJobObject -Job $Bkjob.Name | Where-Object {$_.Type -eq "Include" -or $_.Type -eq "VssChild"} + foreach ($VSSObj in $VSSObjs) { + Write-PscriboMessage "Discovered $($Bkjob.Name) guest processing." + $inObj = [ordered] @{ + 'Name' = $VSSObj.Name + 'Enabled' = ConvertTo-TextYN $Bkjob.VssOptions.Enabled + 'Resource Type' = ($Bkjob.GetHvOijs() | Where-Object {$_.Name -eq $VSSObj.Name -and ($_.Type -eq "Include" -or $_.Type -eq "VssChild")}).Object.Type + 'Ignore Errors' = ConvertTo-TextYN $VSSObj.VssOptions.IgnoreErrors + 'Guest Proxy Auto Detect' = ConvertTo-TextYN $VSSObj.VssOptions.GuestProxyAutoDetect + 'Default Credential' = Switch ((Get-VBRCredentials | Where-Object { $_.Id -eq $Bkjob.VssOptions.WinCredsId.Guid}).count) { + 0 {'None'} + Default {Get-VBRCredentials | Where-Object { $_.Id -eq $Bkjob.VssOptions.WinCredsId.Guid}} + } + 'Object Credential' = Switch ($VSSObj.VssOptions.WinCredsId.Guid) { + '00000000-0000-0000-0000-000000000000' {'Default Credential'} + default {Get-VBRCredentials | Where-Object { $_.Id -eq $VSSObj.VssOptions.WinCredsId.Guid}} + } + 'Application Processing' = ConvertTo-TextYN $VSSObj.VssOptions.VssSnapshotOptions.ApplicationProcessingEnabled + 'Transaction Logs' = Switch ($VSSObj.VssOptions.VssSnapshotOptions.IsCopyOnly) { + 'False' {'Process Transaction Logs'} + 'True' {'Perform Copy Only'} + } + 'Use Persistent Guest Agent' = ConvertTo-TextYN $VSSObj.VssOptions.VssSnapshotOptions.UsePersistentGuestAgent + } + if ($InfoLevel.Jobs.Replication -ge 2) { + if (!$VSSObj.VssOptions.VssSnapshotOptions.IsCopyOnly) { + $TransactionLogsProcessing = Switch ($VSSObj.VssOptions.SqlBackupOptions.TransactionLogsProcessing) { + 'TruncateOnlyOnSuccessJob' {'Truncate logs'} + 'Backup' {'Backup logs periodically'} + 'NeverTruncate' {'Do not truncate logs'} + } + $RetainLogBackups = Switch ($VSSObj.VssOptions.SqlBackupOptions.UseDbBackupRetention) { + 'True' {'Until the corresponding image-level backup is deleted'} + 'False' {"Keep Only Last $($VSSObj.VssOptions.SqlBackupOptions.RetainDays) days of log backups"} + } + $inObj.add('SQL Transaction Logs Processing', ($TransactionLogsProcessing)) + $inObj.add('SQL Backup Log Every', ("$($VSSObj.VssOptions.SqlBackupOptions.BackupLogsFrequencyMin) min")) + $inObj.add('SQL Retain Log Backups', $($RetainLogBackups)) + } + if ($VSSObj.VssOptions.OracleBackupOptions.BackupLogsEnabled -or $VSSObj.VssOptions.OracleBackupOptions.ArchivedLogsTruncation) { + $ArchivedLogsTruncation = Switch ($VSSObj.VssOptions.OracleBackupOptions.ArchivedLogsTruncation) { + 'ByAge' {"Delete Log Older Than $($VSSObj.VssOptions.OracleBackupOptions.ArchivedLogsMaxAgeHours) hours"} + 'BySize' {"Delete Log Over $([Math]::Round($VSSObj.VssOptions.OracleBackupOptions.ArchivedLogsMaxSizeMb / 1024, 0)) GB"} + default {$VSSObj.VssOptions.OracleBackupOptions.ArchivedLogsTruncation} + + } + $SysdbaCredsId = Switch ($VSSObj.VssOptions.OracleBackupOptions.SysdbaCredsId) { + '00000000-0000-0000-0000-000000000000' {'Guest OS Credential'} + default {(Get-VBRCredentials | Where-Object { $_.Id -eq $VSSObj.VssOptions.OracleBackupOptions.SysdbaCredsId}).Description} + } + $RetainLogBackups = Switch ($VSSObj.VssOptions.OracleBackupOptions.UseDbBackupRetention) { + 'True' {'Until the corresponding image-level backup is deleted'} + 'False' {"Keep Only Last $($VSSObj.VssOptions.OracleBackupOptions.RetainDays) days of log backups"} + } + $inObj.add('Oracle Account Type', $VSSObj.VssOptions.OracleBackupOptions.AccountType) + $inObj.add('Oracle Sysdba Creds', $SysdbaCredsId) + if ($VSSObj.VssOptions.OracleBackupOptions.BackupLogsEnabled) { + $inObj.add('Oracle Backup Logs Every', ("$($VSSObj.VssOptions.OracleBackupOptions.BackupLogsFrequencyMin) min")) + } + $inObj.add('Oracle Archive Logs', ($ArchivedLogsTruncation)) + $inObj.add('Oracle Retain Log Backups', $($RetainLogBackups)) + } + if ($VSSObj.VssOptions.GuestFSExcludeOptions.FileExcludeEnabled) { + $inObj.add('File Exclusions', (ConvertTo-TextYN $VSSObj.VssOptions.GuestFSExcludeOptions.FileExcludeEnabled)) + if ($VSSObj.VssOptions.GuestFSExcludeOptions.BackupScope -eq 'ExcludeSpecifiedFolders') { + $inObj.add('Exclude the following file and folders', ($VSSObj.VssOptions.GuestFSExcludeOptions.ExcludeList -join ',')) + } + elseif ($VSSObj.VssOptions.GuestFSExcludeOptions.BackupScope -eq 'IncludeSpecifiedFolders') { + $inObj.add('Include only the following file and folders', ($VSSObj.VssOptions.GuestFSExcludeOptions.IncludeList-join ',')) + } + } + if ($VSSObj.VssOptions.GuestScriptsOptions.ScriptingMode -ne 'Disabled') { + $ScriptingMode = Switch ($VSSObj.VssOptions.GuestScriptsOptions.ScriptingMode) { + 'FailJobOnError' {'Require successfull script execution'} + 'IgnoreErrors' {'Ignore script execution failures'} + 'Disabled' {'Disable script execution'} + } + $inObj.add('Scripts', (ConvertTo-TextYN $VSSObj.VssOptions.GuestScriptsOptions.IsAtLeastOneScriptSet)) + $inObj.add('Scripts Mode', ($ScriptingMode)) + if ($VSSObj.VssOptions.GuestScriptsOptions.WinScriptFiles.IsAtLeastOneScriptSet) { + $inObj.add('Windows Pre-freeze script', ($VSSObj.VssOptions.GuestScriptsOptions.WinScriptFiles.PreScriptFilePath)) + $inObj.add('Windows Post-thaw script', ($VSSObj.VssOptions.GuestScriptsOptions.WinScriptFiles.PostScriptFilePath)) + } + elseif ($VSSObj.VssOptions.GuestScriptsOptions.LinScriptFiles.IsAtLeastOneScriptSet) { + $inObj.add('Linux Pre-freeze script', ($VSSObj.VssOptions.GuestScriptsOptions.LinScriptFiles.PreScriptFilePath)) + $inObj.add('Linux Post-thaw script', ($VSSObj.VssOptions.GuestScriptsOptions.LinScriptFiles.PostScriptFilePath)) + } + } + } + + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Guest Processing Options - $($VSSObj.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($Bkjob.GetScheduleOptions().NextRun -and $Bkjob.ScheduleOptions.OptionsContinuous.Enabled -ne "True") { + Section -Style Heading5 "Schedule" { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) schedule options." + if ($Bkjob.ScheduleOptions.OptionsDaily.Enabled -eq "True") { + $ScheduleType = "Daily" + $Schedule = "Kind: $($Bkjob.ScheduleOptions.OptionsDaily.Kind),`r`nDays: $($Bkjob.ScheduleOptions.OptionsDaily.DaysSrv)" + } + elseif ($Bkjob.ScheduleOptions.OptionsMonthly.Enabled -eq "True") { + $ScheduleType = "Monthly" + $Schedule = "Day Of Month: $($Bkjob.ScheduleOptions.OptionsMonthly.DayOfMonth),`r`nDay Number In Month: $($Bkjob.ScheduleOptions.OptionsMonthly.DayNumberInMonth),`r`nDay Of Week: $($Bkjob.ScheduleOptions.OptionsMonthly.DayOfWeek)" + } + elseif ($Bkjob.ScheduleOptions.OptionsPeriodically.Enabled -eq "True") { + $ScheduleType = "Hours" + $Schedule = "Full Period: $($Bkjob.ScheduleOptions.OptionsPeriodically.FullPeriod),`r`nHourly Offset: $($Bkjob.ScheduleOptions.OptionsPeriodically.HourlyOffset),`r`nUnit: $($Bkjob.ScheduleOptions.OptionsPeriodically.Unit)" + } + $inObj = [ordered] @{ + 'Retry Failed item' = $Bkjob.ScheduleOptions.RetryTimes + 'Wait before each retry' = "$($Bkjob.ScheduleOptions.RetryTimeout)/min" + 'Backup Window' = ConvertTo-TextYN $Bkjob.ScheduleOptions.OptionsBackupWindow.IsEnabled + 'Shedule type' = $ScheduleType + 'Shedule Options' = $Schedule + 'Start Time' = $Bkjob.ScheduleOptions.OptionsDaily.TimeLocal.ToShorttimeString() + 'Latest Run' = $Bkjob.LatestRunLocal + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Schedule Options - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + end {} + +} diff --git a/Src/Private/Get-AbrVbrRepljobVMware.ps1 b/Src/Private/Get-AbrVbrRepljobVMware.ps1 index e14e0c7..ea6c2b4 100644 --- a/Src/Private/Get-AbrVbrRepljobVMware.ps1 +++ b/Src/Private/Get-AbrVbrRepljobVMware.ps1 @@ -33,7 +33,7 @@ function Get-AbrVbrRepljobVMware { BlankLine $OutObj = @() try { - $VMcounts = Get-VBRJob -WarningAction SilentlyContinue | Where-object {$_.TypeToString -eq 'VMware Replication' -or $_.TypeToString -eq 'Hyper-V Replication'} + $VMcounts = Get-VBRJob -WarningAction SilentlyContinue | Where-object {$_.TypeToString -eq 'VMware Replication'} if ($VMcounts) { foreach ($VMcount in $VMcounts) { try { @@ -105,19 +105,55 @@ function Get-AbrVbrRepljobVMware { Write-PscriboMessage -IsWarning $_.Exception.Message } } - if ($Bkjob.LinkedJobs) { - Section -Style Heading5 'Linked Backup Jobs' { + Section -Style Heading5 'Destination' { + $OutObj = @() + try { + foreach ($Destination in $Bkjob.ViReplicaTargetOptions) { + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) destination information." + if (!$Destination.ClusterName) { + $HostorCluster = (Find-VBRViEntity -ErrorAction SilentlyContinue | Where-Object { $_.Reference -eq $Destination.HostReference}).Name + } else {$HostorCluster = $Destination.ClusterName} + $inObj = [ordered] @{ + 'Host or Cluster' = Switch ($HostorCluster) { + $Null {'Unknown'} + default {$HostorCluster} + } + 'Resources Pool' = $Destination.ReplicaTargetResourcePoolName + 'VM Folder' = $Destination.ReplicaTargetVmFolderName + 'Datastore' = $Destination.DatastoreName + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + + $TableParams = @{ + Name = "Destination - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + if ($Bkjob.ViReplicaTargetOptions.UseNetworkMapping) { + Section -Style Heading5 'Network' { $OutObj = @() try { - foreach ($LinkedBkJob in $Bkjob.LinkedJobs) { + foreach ($NetMapping in $Bkjob.Options.ViNetworkMappingOptions.NetworkMapping) { try { - Write-PscriboMessage "Discovered $($Bkjob.Name) linked backup job." - $Job = Get-VBRJob -WarningAction SilentlyContinue| Where-Object {$_.Id -eq $LinkedBkJob.info.LinkedObjectId} + Write-PscriboMessage "Discovered $($Bkjob.Name) network mapping information." $inObj = [ordered] @{ - 'Name' = $Job.Name - 'Type' = $Job.TypeToString - 'Size' = ConvertTo-FileSizeString $Job.Info.IncludedSize - 'Repository' = $Job.GetTargetRepository().Name + 'Source Network' = $NetMapping.SourceNetwork + 'Target Network' = $NetMapping.TargetNetwork } $OutObj += [pscustomobject]$inobj } @@ -127,42 +163,34 @@ function Get-AbrVbrRepljobVMware { } $TableParams = @{ - Name = "Linked Backup Jobs - $($Bkjob.Name)" + Name = "Network Mappings - $($Bkjob.Name)" List = $false - ColumnWidths = 35, 25, 15, 25 + ColumnWidths = 50, 50 } if ($Report.ShowTableCaptions) { $TableParams['Caption'] = "- $($TableParams.Name)" } - $OutObj | Sort-Object -Property 'Name' | Table @TableParams + $OutObj | Sort-Object -Property 'Source Network' | Table @TableParams } catch { Write-PscriboMessage -IsWarning $_.Exception.Message } } } - if ($Bkjob.LinkedRepositories) { - Section -Style Heading5 'Linked Repositories' { + if ($Bkjob.Options.ViReplicaTargetOptions.UseReIP) { + Section -Style Heading5 'Re-IP Rules' { $OutObj = @() try { - foreach ($LinkedRepository in $Bkjob.LinkedRepositories.LinkedRepositoryId) { + foreach ($ReIpRule in $Bkjob.Options.ReIPRulesOptions.Rules) { try { - Write-PscriboMessage "Discovered $($Bkjob.Name) linked repository." - $Repo = Get-VBRBackupRepository | Where-Object {$_.Id -eq $LinkedRepository} - $ScaleRepo = Get-VBRBackupRepository -ScaleOut | Where-Object {$_.Id -eq $LinkedRepository} - if ($Repo) { - $inObj = [ordered] @{ - 'Name' = $Repo.Name - 'Type' = "Standard" - 'Size' = "$($Repo.GetContainer().CachedTotalSpace.InGigabytes) Gb" - } - } - if ($ScaleRepo) { - $inObj = [ordered] @{ - 'Name' = $ScaleRepo.Name - 'Type' = "ScaleOut" - 'Size' = "$((($ScaleRepo.Extent).Repository).GetContainer().CachedTotalSpace.InGigabytes) GB" - } + Write-PscriboMessage "Discovered $($Bkjob.Name) re-ip rules $($ReIpRule.Source.IPAddress) information." + $inObj = [ordered] @{ + 'Source IP Address' = $ReIpRule.Source.IPAddress + 'Source Subnet Mask' = $ReIpRule.Source.SubnetMask + 'Target P Address' = $ReIpRule.Target.IPAddress + 'Target Subnet Mask' = $ReIpRule.Target.SubnetMask + 'Target Default Gateway' = $ReIpRule.Target.DefaultGateway + 'Target DNS Addresses' = $ReIpRule.Target.DNSAddresses } $OutObj += [pscustomobject]$inobj } @@ -172,14 +200,14 @@ function Get-AbrVbrRepljobVMware { } $TableParams = @{ - Name = "Linked Repositories - $($Bkjob.Name)" + Name = "Re-IP Rules - $($Bkjob.Name)" List = $false - ColumnWidths = 35, 35, 30 + ColumnWidths = 17, 17, 17, 17, 16, 16 } if ($Report.ShowTableCaptions) { $TableParams['Caption'] = "- $($TableParams.Name)" } - $OutObj | Sort-Object -Property 'Name' | Table @TableParams + $OutObj | Sort-Object -Property 'Source IP Address' | Table @TableParams } catch { Write-PscriboMessage -IsWarning $_.Exception.Message @@ -191,7 +219,7 @@ function Get-AbrVbrRepljobVMware { $OutObj = @() try { foreach ($OBJ in ($Bkjob.GetViOijs() | Where-Object {$_.Type -eq "Include" -or $_.Type -eq "Exclude"} )) { - Write-PscriboMessage "Discovered $($OBJ.Name) object to backup." + Write-PscriboMessage "Discovered $($OBJ.Name) object to replicate." $inObj = [ordered] @{ 'Name' = $OBJ.Name 'Resource Type' = $OBJ.TypeDisplayName @@ -223,7 +251,7 @@ function Get-AbrVbrRepljobVMware { try { Write-PscriboMessage "Discovered $($Bkjob.Name) storage options." if ($Bkjob.BackupStorageOptions.RetentionType -eq "Days") { - $RetainString = 'Retain Days To Keep' + $RetainString = 'Restore Point To Keep' $Retains = $Bkjob.BackupStorageOptions.RetainDaysToKeep } elseif ($Bkjob.BackupStorageOptions.RetentionType -eq "Cycles") { @@ -231,33 +259,13 @@ function Get-AbrVbrRepljobVMware { $Retains = $Bkjob.BackupStorageOptions.RetainCycles } $inObj = [ordered] @{ - 'Backup Proxy' = Switch (($Bkjob.GetProxy().Name).count) { - 0 {"Unknown"} - {$_ -gt 1} {"Automatic"} - default {$Bkjob.GetProxy().Name} - } 'Repository for replica metadata' = Switch ($Bkjob.info.TargetRepositoryId) { '00000000-0000-0000-0000-000000000000' {$Bkjob.TargetDir} {$Null -eq (Get-VBRBackupRepository | Where-Object {$_.Id -eq $Bkjob.info.TargetRepositoryId}).Name} {(Get-VBRBackupRepository -ScaleOut | Where-Object {$_.Id -eq $Bkjob.info.TargetRepositoryId}).Name} default {(Get-VBRBackupRepository | Where-Object {$_.Id -eq $Bkjob.info.TargetRepositoryId}).Name} } - 'Retention Type' = $Bkjob.BackupStorageOptions.RetentionType + 'Replica Name Suffix' = $Bkjob.Options.ViReplicaTargetOptions.ReplicaNameSuffix $RetainString = $Retains - 'Keep First Full Backup' = ConvertTo-TextYN $Bkjob.BackupStorageOptions.KeepFirstFullBackup - 'Enable Full Backup' = ConvertTo-TextYN $Bkjob.BackupStorageOptions.EnableFullBackup - 'Integrity Checks' = ConvertTo-TextYN $Bkjob.BackupStorageOptions.EnableIntegrityChecks - 'Storage Encryption' = ConvertTo-TextYN $Bkjob.BackupStorageOptions.StorageEncryptionEnabled - 'Backup Mode' = Switch ($Bkjob.Options.BackupTargetOptions.Algorithm) { - 'Syntethic' {"Reverse Incremental"} - 'Increment' {'Incremental'} - } - 'Active Full Backup Schedule Kind' = $Bkjob.Options.BackupTargetOptions.FullBackupScheduleKind - 'Active Full Backup Days' = $Bkjob.Options.BackupTargetOptions.FullBackupDays - 'Transform Full To Syntethic' = ConvertTo-TextYN $Bkjob.Options.BackupTargetOptions.TransformFullToSyntethic - 'Transform Increments To Syntethic' = ConvertTo-TextYN $Bkjob.Options.BackupTargetOptions.TransformIncrementsToSyntethic - 'Transform To Syntethic Days' = $Bkjob.Options.BackupTargetOptions.TransformToSyntethicDays - - } $OutObj = [pscustomobject]$inobj @@ -304,10 +312,10 @@ function Get-AbrVbrRepljobVMware { } } if ($InfoLevel.Jobs.Replication -ge 2) { - Section -Style Heading6 "Advanced Settings (Storage)" { + Section -Style Heading6 "Advanced Settings (Traffic)" { $OutObj = @() try { - Write-PscriboMessage "Discovered $($Bkjob.Name) storage options." + Write-PscriboMessage "Discovered $($Bkjob.Name) traffic options." $inObj = [ordered] @{ 'Inline Data Deduplication' = ConvertTo-TextYN $Bkjob.Options.BackupStorageOptions.EnableDeduplication 'Exclude Swap Files Block' = ConvertTo-TextYN $Bkjob.ViSourceOptions.ExcludeSwapFile @@ -336,7 +344,7 @@ function Get-AbrVbrRepljobVMware { $OutObj = [pscustomobject]$inobj $TableParams = @{ - Name = "Advanced Settings (Storage) - $($Bkjob.Name)" + Name = "Advanced Settings (Traffic) - $($Bkjob.Name)" List = $true ColumnWidths = 40, 60 } @@ -553,6 +561,36 @@ function Get-AbrVbrRepljobVMware { catch { Write-PscriboMessage -IsWarning $_.Exception.Message } + if ($Bkjob.Options.ViReplicaTargetOptions.InitialSeeding) { + try { + Section -Style Heading5 'Seeding' { + $OutObj = @() + Write-PscriboMessage "Discovered $($Bkjob.Name) seeding information." + if ($Bkjob.Options.ViReplicaTargetOptions.EnableInitialPass) { + $SeedRepo = $Bkjob.GetInitialRepository().Name + } else {$SeedRepo = 'Disabled'} + $inObj = [ordered] @{ + 'Seed from Backup Repository' = $SeedRepo + 'Map Replica to Existing VM' = ConvertTo-TextYN $Bkjob.Options.ViReplicaTargetOptions.UseVmMapping + } + + $OutObj += [pscustomobject]$inobj + + $TableParams = @{ + Name = "Seeding - $($Bkjob.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } if ($Bkjob.VssOptions.Enabled) { Section -Style Heading5 "Guest Processing" { $OutObj = @() diff --git a/Src/Public/Invoke-AsBuiltReport.Veeam.VBR.ps1 b/Src/Public/Invoke-AsBuiltReport.Veeam.VBR.ps1 index e711879..16742d5 100644 --- a/Src/Public/Invoke-AsBuiltReport.Veeam.VBR.ps1 +++ b/Src/Public/Invoke-AsBuiltReport.Veeam.VBR.ps1 @@ -203,7 +203,7 @@ function Invoke-AsBuiltReport.Veeam.VBR { if ($InfoLevel.Jobs.Replication -ge 1) { Get-AbrVbrRepljob Get-AbrVbrRepljobVMware - #Get-AbrVbrRepljobHyperV + Get-AbrVbrRepljobHyperV } Write-PScriboMessage "Tape Jobs InfoLevel set at $($InfoLevel.Jobs.Tape)." if ($InfoLevel.Jobs.Tape -ge 1) { From 8b78cc9f5e15c440c748b19515e940aa5b0da9cc Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Tue, 10 May 2022 23:29:32 -0400 Subject: [PATCH 05/12] Better filter backup jobs (remove replication jobs) --- Src/Private/Get-AbrVbrBackupjob.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Src/Private/Get-AbrVbrBackupjob.ps1 b/Src/Private/Get-AbrVbrBackupjob.ps1 index 075dcb1..17671c9 100644 --- a/Src/Private/Get-AbrVbrBackupjob.ps1 +++ b/Src/Private/Get-AbrVbrBackupjob.ps1 @@ -32,7 +32,7 @@ function Get-AbrVbrBackupjob { BlankLine $OutObj = @() if ((Get-VBRServerSession).Server) { - $Bkjobs = Get-VBRJob -WarningAction SilentlyContinue | Where-object {$_.TypeToString -ne 'Windows Agent Backup'} + $Bkjobs = Get-VBRJob -WarningAction SilentlyContinue | Where-object {$_.TypeToString -ne 'Windows Agent Backup' -and $_.TypeToString -ne 'Hyper-V Replication' -and $_.TypeToString -ne 'VMware Replication'} foreach ($Bkjob in $Bkjobs) { try { Write-PscriboMessage "Discovered $($Bkjob.Name) backup job." From a5c66a6706c9e7c0d357c6fc1018408f0b2e594a Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Tue, 10 May 2022 23:29:50 -0400 Subject: [PATCH 06/12] Update changelog with latest changes --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80697d7..0e99664 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,13 @@ - Added Optional InfoLevel 2 information (Adv Summary) - Failover Plan Information - Added Virtual Machine Boot Order reporting +- Added Replication Job Configuration information @rebelinux + - Added Optional InfoLevel 2 information (Adv Summary) + - Advanced Settings (Traffic) + - Advanced Settings (Notification) + - Advanced Settings (vSphere) + - Advanced Settings (Integration) + - Advanced Settings (Script) ### Fixed From 6e087a3cb609524f64d98ce48f9c9c9990ea5dea Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Wed, 11 May 2022 09:34:44 -0400 Subject: [PATCH 07/12] Bump file version to v0.5.0 --- Src/Private/Get-AbrVbrBackupjob.ps1 | 2 +- Src/Private/Get-AbrVbrBackupjobHyperV.ps1 | 2 +- Src/Private/Get-AbrVbrBackupjobVMware.ps1 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Src/Private/Get-AbrVbrBackupjob.ps1 b/Src/Private/Get-AbrVbrBackupjob.ps1 index 17671c9..f733e8d 100644 --- a/Src/Private/Get-AbrVbrBackupjob.ps1 +++ b/Src/Private/Get-AbrVbrBackupjob.ps1 @@ -6,7 +6,7 @@ function Get-AbrVbrBackupjob { .DESCRIPTION Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. .NOTES - Version: 0.4.0 + Version: 0.5.0 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux diff --git a/Src/Private/Get-AbrVbrBackupjobHyperV.ps1 b/Src/Private/Get-AbrVbrBackupjobHyperV.ps1 index 4d53b39..a7948e5 100644 --- a/Src/Private/Get-AbrVbrBackupjobHyperV.ps1 +++ b/Src/Private/Get-AbrVbrBackupjobHyperV.ps1 @@ -6,7 +6,7 @@ function Get-AbrVbrBackupjobHyperV { .DESCRIPTION Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. .NOTES - Version: 0.4.1 + Version: 0.5.0 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux diff --git a/Src/Private/Get-AbrVbrBackupjobVMware.ps1 b/Src/Private/Get-AbrVbrBackupjobVMware.ps1 index f09d4fd..1eceeb7 100644 --- a/Src/Private/Get-AbrVbrBackupjobVMware.ps1 +++ b/Src/Private/Get-AbrVbrBackupjobVMware.ps1 @@ -6,7 +6,7 @@ function Get-AbrVbrBackupjobVMware { .DESCRIPTION Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. .NOTES - Version: 0.4.1 + Version: 0.5.0 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux From 01a7e8b865bc0e20f57d8d648f27b443a0f28160 Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Wed, 11 May 2022 09:39:49 -0400 Subject: [PATCH 08/12] Bump AsbuiltReport.core to v1.2.0 --- AsBuiltReport.Veeam.VBR.psd1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AsBuiltReport.Veeam.VBR.psd1 b/AsBuiltReport.Veeam.VBR.psd1 index 4e7cf98..20883ef 100644 --- a/AsBuiltReport.Veeam.VBR.psd1 +++ b/AsBuiltReport.Veeam.VBR.psd1 @@ -55,7 +55,7 @@ PowerShellVersion = '5.1' RequiredModules = @( @{ ModuleName = 'AsBuiltReport.Core'; - ModuleVersion = '1.1.0' + ModuleVersion = '1.2.0' } ) From 51b6a93b337aebd42f544629d8e8c980d426b712 Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Wed, 11 May 2022 09:41:00 -0400 Subject: [PATCH 09/12] Added VeeamLegend to the tweet-message list --- .github/workflows/Release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index 4f86712..6bf5d74 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -35,7 +35,7 @@ jobs: with: # GitHub event payload # https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#release - tweet-message: "[New Release] ${{ github.event.repository.name }} ${{ github.event.release.tag_name }}! Check out what's new! ${{ github.event.release.html_url }} #Veeam #AsBuiltReport #PowerShell #VeeamVanguard" + tweet-message: "[New Release] ${{ github.event.repository.name }} ${{ github.event.release.tag_name }}! Check out what's new! ${{ github.event.release.html_url }} #Veeam #AsBuiltReport #PowerShell #VeeamVanguard #VeeamLegend" env: TWITTER_CONSUMER_API_KEY: ${{ secrets.TWITTER_CONSUMER_API_KEY }} TWITTER_CONSUMER_API_SECRET: ${{ secrets.TWITTER_CONSUMER_API_SECRET }} From 1fa379117270b1e6668cb24b040cfeddfa148b0e Mon Sep 17 00:00:00 2001 From: Jonathan Colon Date: Wed, 11 May 2022 12:45:11 -0400 Subject: [PATCH 10/12] Update Sample Veeam VBR As Built Report.html --- Samples/Sample Veeam VBR As Built Report.html | 3229 ++++++++++++----- 1 file changed, 2291 insertions(+), 938 deletions(-) diff --git a/Samples/Sample Veeam VBR As Built Report.html b/Samples/Sample Veeam VBR As Built Report.html index 9d86852..96e510d 100644 --- a/Samples/Sample Veeam VBR As Built Report.html +++ b/Samples/Sample Veeam VBR As Built Report.html @@ -1,4 +1,4 @@ - + Veeam VBR As Built Report