diff --git a/AsBuiltReport.Veeam.VBR.psd1 b/AsBuiltReport.Veeam.VBR.psd1 index 1f5c862..76f7dfa 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.5.3' +ModuleVersion = '0.5.4' # Supported PSEditions # CompatiblePSEditions = @() diff --git a/AsBuiltreport.Veeam.VBR.json b/AsBuiltreport.Veeam.VBR.json index 4973af7..8acff59 100644 --- a/AsBuiltreport.Veeam.VBR.json +++ b/AsBuiltreport.Veeam.VBR.json @@ -52,6 +52,7 @@ "Tape": 1, "Surebackup": 1, "Agent": 1, + "FileShare": 1, "Replication": 1 } }, diff --git a/CHANGELOG.md b/CHANGELOG.md index 459c97c..8aac82f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # :arrows_clockwise: Veeam VBR As Built Report Changelog +## [0.5.4] - 2022-09-17 + +### Added + +- Added support for File Share Backup Job information +- Added support for Backup Jobs GFS Policy information +- Added Simple Chart support + +### Fixed + +- Fixes [#49](https://github.com/AsBuiltReport/AsBuiltReport.Veeam.VBR/issues/49) +- Fixes [#50](https://github.com/AsBuiltReport/AsBuiltReport.Veeam.VBR/issues/50) + ## [0.5.3] - 2022-08-21 ### Changed diff --git a/README.md b/README.md index 6e8b41f..ecf503c 100644 --- a/README.md +++ b/README.md @@ -200,6 +200,7 @@ The table below outlines the default and maximum **InfoLevel** settings for each | Tape | 1 | 2 | | Surebackup | 1 | 2 | | Agent | 1 | 2 | +| FileShare | 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-AbrVbrBackupRepository.ps1 b/Src/Private/Get-AbrVbrBackupRepository.ps1 index e988cb3..5ad0fc1 100644 --- a/Src/Private/Get-AbrVbrBackupRepository.ps1 +++ b/Src/Private/Get-AbrVbrBackupRepository.ps1 @@ -6,7 +6,7 @@ function Get-AbrVbrBackupRepository { .DESCRIPTION Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. .NOTES - Version: 0.5.3 + Version: 0.5.4 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -27,118 +27,166 @@ function Get-AbrVbrBackupRepository { process { try { if ((Get-VBRBackupRepository).count -gt 0) { - Section -Style Heading3 'Backup Repository' { - Paragraph "The following section provides Backup Repository summary information." - BlankLine - $OutObj = @() - try { - [Array]$BackupRepos = Get-VBRBackupRepository | Where-Object {$_.Type -ne "SanSnapshotOnly"} - [Array]$ScaleOuts = Get-VBRBackupRepository -ScaleOut - if ($ScaleOuts) { - $Extents = Get-VBRRepositoryExtent -Repository $ScaleOuts - $BackupRepos += $Extents.Repository - } - foreach ($BackupRepo in $BackupRepos) { - Write-PscriboMessage "Discovered $($BackupRepo.Name) Repository." - $PercentFree = 0 - if (@($($BackupRepo.GetContainer().CachedTotalSpace.InGigabytes),$($BackupRepo.GetContainer().CachedFreeSpace.InGigabytes)) -ne 0) { - $UsedSpace = ($($BackupRepo.GetContainer().CachedTotalSpace.InGigabytes-$($BackupRepo.GetContainer().CachedFreeSpace.InGigabytes))) - if ($UsedSpace -ne 0) { - $PercentFree = ($UsedSpace/$($BackupRepo.GetContainer().CachedTotalSpace.InGigabytes)).tostring("P") - } + $OutObj = @() + try { + [Array]$BackupRepos = Get-VBRBackupRepository | Where-Object {$_.Type -ne "SanSnapshotOnly"} + [Array]$ScaleOuts = Get-VBRBackupRepository -ScaleOut + if ($ScaleOuts) { + $Extents = Get-VBRRepositoryExtent -Repository $ScaleOuts + $BackupRepos += $Extents.Repository + } + foreach ($BackupRepo in $BackupRepos) { + Write-PscriboMessage "Discovered $($BackupRepo.Name) Repository." + $PercentFree = 0 + if (@($($BackupRepo.GetContainer().CachedTotalSpace.InGigabytes),$($BackupRepo.GetContainer().CachedFreeSpace.InGigabytes)) -ne 0) { + $UsedSpace = ($($BackupRepo.GetContainer().CachedTotalSpace.InGigabytes-$($BackupRepo.GetContainer().CachedFreeSpace.InGigabytes))) + if ($UsedSpace -ne 0) { + $PercentFree = $([Math]::Round($UsedSpace/$($BackupRepo.GetContainer().CachedTotalSpace.InGigabytes) * 100)) } - $inObj = [ordered] @{ - 'Name' = $BackupRepo.Name - 'Total Space' = "$($BackupRepo.GetContainer().CachedTotalSpace.InGigabytes) Gb" - 'Free Space' = "$($BackupRepo.GetContainer().CachedFreeSpace.InGigabytes) Gb" - 'Space Used' = $PercentFree - 'Status' = Switch ($BackupRepo.IsUnavailable) { - 'False' {'Available'} - 'True' {'Unavailable'} - default {$BackupRepo.IsUnavailable} - } + } + $inObj = [ordered] @{ + 'Name' = $BackupRepo.Name + 'Total Space' = "$($BackupRepo.GetContainer().CachedTotalSpace.InGigabytes) Gb" + 'Free Space' = "$($BackupRepo.GetContainer().CachedFreeSpace.InGigabytes) Gb" + 'Used Space %' = $PercentFree + 'Status' = Switch ($BackupRepo.IsUnavailable) { + 'False' {'Available'} + 'True' {'Unavailable'} + default {$BackupRepo.IsUnavailable} } - $OutObj += [pscustomobject]$inobj } + $OutObj += [pscustomobject]$inobj } - catch { - Write-PscriboMessage -IsWarning $_.Exception.Message - } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } - if ($HealthCheck.Infrastructure.BR) { - $OutObj | Where-Object { $_.'Status' -eq 'Unavailable'} | Set-Style -Style Warning -Property 'Status' - if ([int]([regex]::Matches($OutObj.'Space Used', "\d+(?!.*\d+)").value) -ge 75) { $OutObj | Set-Style -Style Warning -Property 'Space Used' } - if ([int]([regex]::Matches($OutObj.'Space Used', "\d+(?!.*\d+)").value) -ge 90) { $OutObj | Set-Style -Style Critical -Property 'Space Used' } + if ($HealthCheck.Infrastructure.BR) { + $OutObj | Where-Object { $_.'Status' -eq 'Unavailable'} | Set-Style -Style Warning -Property 'Status' + if ([int]([regex]::Matches($OutObj.'Space Used', "\d+(?!.*\d+)").value) -ge 75) { $OutObj | Set-Style -Style Warning -Property 'Space Used' } + if ([int]([regex]::Matches($OutObj.'Space Used', "\d+(?!.*\d+)").value) -ge 90) { $OutObj | Set-Style -Style Critical -Property 'Space Used' } + } + + $TableParams = @{ + Name = "Backup Repository - $VeeamBackupServer" + List = $false + ColumnWidths = 30, 18, 18, 19, 15 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + try { + $sampleData = $OutObj | Select-Object -Property 'Name','Used Space %' + + $exampleChart = New-Chart -Name BackupRepository -Width 600 -Height 400 + + $addChartAreaParams = @{ + Chart = $exampleChart + Name = 'exampleChartArea' } + $exampleChartArea = Add-ChartArea @addChartAreaParams -PassThru - $TableParams = @{ - Name = "Backup Repository - $VeeamBackupServer" - List = $false - ColumnWidths = 30, 18, 18, 19, 15 + $addChartSeriesParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = 'exampleChartSeries' + XField = 'Name' + YField = 'Used Space %' + Palette = 'Green' + ColorPerDataPoint = $true } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" + $exampleChartSeries = $sampleData | Add-PieChartSeries @addChartSeriesParams -PassThru + + $addChartLegendParams = @{ + Chart = $exampleChart + Name = 'Backup Repository' + TitleAlignment = 'Center' } - $OutObj | Sort-Object -Property 'Name' | Table @TableParams - #---------------------------------------------------------------------------------------------# - # Backup Repository Configuration Section # - #---------------------------------------------------------------------------------------------# - if ($InfoLevel.Infrastructure.BR -ge 2) { - try { - Section -Style Heading4 "Backup Repository Configuration" { - Paragraph "The following section provides a detailed information of the Veeam Backup Repository Configuration." - BlankLine - foreach ($BackupRepo in $BackupRepos) { - try { - Section -Style NOTOCHeading5 -ExcludeFromTOC $($BackupRepo.Name) { - $OutObj = @() - Write-PscriboMessage "Discovered $($BackupRepo.Name) Backup Repository." - $inObj = [ordered] @{ - 'Extent of ScaleOut Backup Repository' = (($ScaleOuts | Where-Object {($Extents | Where-Object {$_.name -eq $BackupRepo.Name}).ParentId -eq $_.Id}).Name) - 'Backup Proxy' = ($BackupRepo.Host).Name - 'Integration Type' = $BackupRepo.TypeDisplay - 'Path' = $BackupRepo.Path - 'Connection Type' = $BackupRepo.Type - 'Max Task Count' = $BackupRepo.Options.MaxTaskCount - 'Use Nfs On Mount Host' = ConvertTo-TextYN $BackupRepo.UseNfsOnMountHost - 'San Snapshot Only' = ConvertTo-TextYN $BackupRepo.IsSanSnapshotOnly - 'Dedup Storage' = ConvertTo-TextYN $BackupRepo.IsDedupStorage - 'Split Storages Per Vm' = ConvertTo-TextYN $BackupRepo.SplitStoragesPerVm - 'Immutability Supported' = ConvertTo-TextYN $BackupRepo.IsImmutabilitySupported - 'Immutability Enabled' = ConvertTo-TextYN $BackupRepo.GetImmutabilitySettings().IsEnabled - 'Immutability Interval' = $BackupRepo.GetImmutabilitySettings().IntervalDays - 'Version Of Creation' = $BackupRepo.VersionOfCreation - 'Has Backup Chain Length Limitation' = ConvertTo-TextYN $BackupRepo.HasBackupChainLengthLimitation - } - if ($null -eq $inObj.'Extent of ScaleOut Backup Repository') { - $inObj.Remove('Extent of ScaleOut Backup Repository') - } - $OutObj += [pscustomobject]$inobj + Add-ChartLegend @addChartLegendParams - if ($HealthCheck.Infrastructure.BR) { - $OutObj | Where-Object { $_.'Immutability Supported' -eq 'Yes' -and $_.'Immutability Enabled' -eq 'No' } | Set-Style -Style Warning -Property 'Immutability Enabled' - } + $addChartTitleParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = 'UsedSpace' + Text = 'Percentage of Used Space' + Font = New-Object -TypeName 'System.Drawing.Font' -ArgumentList @('Arial', '12', [System.Drawing.FontStyle]::Bold) + } + Add-ChartTitle @addChartTitleParams - $TableParams = @{ - Name = "Backup Repository - $($BackupRepo.Name)" - List = $true - ColumnWidths = 40, 60 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" + $chartFileItem = Export-Chart -Chart $exampleChart -Path (Get-Location).Path -Format "PNG" -PassThru + } + catch { + Write-PscriboMessage -IsWarning $($_.Exception.Message) + } + if ($OutObj) { + Section -Style Heading3 'Backup Repository' { + Paragraph "The following section provides Backup Repository summary information." + BlankLine + if ($chartFileItem) { + Image -Text 'Backup Repository - Diagram' -Align 'Center' -Percent 100 -Path $chartFileItem + } + $OutObj | Sort-Object -Property 'Name' | Table @TableParams + #---------------------------------------------------------------------------------------------# + # Backup Repository Configuration Section # + #---------------------------------------------------------------------------------------------# + if ($InfoLevel.Infrastructure.BR -ge 2) { + try { + Section -Style Heading4 "Backup Repository Configuration" { + Paragraph "The following section provides a detailed information of the Veeam Backup Repository Configuration." + BlankLine + foreach ($BackupRepo in $BackupRepos) { + try { + Section -Style NOTOCHeading5 -ExcludeFromTOC $($BackupRepo.Name) { + $OutObj = @() + Write-PscriboMessage "Discovered $($BackupRepo.Name) Backup Repository." + $inObj = [ordered] @{ + 'Extent of ScaleOut Backup Repository' = (($ScaleOuts | Where-Object {($Extents | Where-Object {$_.name -eq $BackupRepo.Name}).ParentId -eq $_.Id}).Name) + 'Backup Proxy' = ($BackupRepo.Host).Name + 'Integration Type' = $BackupRepo.TypeDisplay + 'Path' = $BackupRepo.Path + 'Connection Type' = $BackupRepo.Type + 'Max Task Count' = $BackupRepo.Options.MaxTaskCount + 'Use Nfs On Mount Host' = ConvertTo-TextYN $BackupRepo.UseNfsOnMountHost + 'San Snapshot Only' = ConvertTo-TextYN $BackupRepo.IsSanSnapshotOnly + 'Dedup Storage' = ConvertTo-TextYN $BackupRepo.IsDedupStorage + 'Split Storages Per Vm' = ConvertTo-TextYN $BackupRepo.SplitStoragesPerVm + 'Immutability Supported' = ConvertTo-TextYN $BackupRepo.IsImmutabilitySupported + 'Immutability Enabled' = ConvertTo-TextYN $BackupRepo.GetImmutabilitySettings().IsEnabled + 'Immutability Interval' = $BackupRepo.GetImmutabilitySettings().IntervalDays + 'Version Of Creation' = $BackupRepo.VersionOfCreation + 'Has Backup Chain Length Limitation' = ConvertTo-TextYN $BackupRepo.HasBackupChainLengthLimitation + } + if ($null -eq $inObj.'Extent of ScaleOut Backup Repository') { + $inObj.Remove('Extent of ScaleOut Backup Repository') + } + $OutObj += [pscustomobject]$inobj + + if ($HealthCheck.Infrastructure.BR) { + $OutObj | Where-Object { $_.'Immutability Supported' -eq 'Yes' -and $_.'Immutability Enabled' -eq 'No' } | Set-Style -Style Warning -Property 'Immutability Enabled' + } + + $TableParams = @{ + Name = "Backup Repository - $($BackupRepo.Name)" + List = $true + ColumnWidths = 40, 60 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams } - $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 + } } } } diff --git a/Src/Private/Get-AbrVbrBackupjob.ps1 b/Src/Private/Get-AbrVbrBackupjob.ps1 index 4270e96..228f50c 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.5.3 + Version: 0.5.4 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -27,44 +27,103 @@ function Get-AbrVbrBackupjob { process { try { if ((Get-VBRJob -WarningAction SilentlyContinue).count -gt 0) { - Section -Style Heading3 'Backup Jobs' { - Paragraph "The following section list backup jobs created in Veeam Backup & Replication." - BlankLine - $OutObj = @() - $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." - $inObj = [ordered] @{ - 'Name' = $Bkjob.Name - 'Type' = $Bkjob.TypeToString - 'Status' = Switch ($Bkjob.IsScheduleEnabled) { - 'False' {'Disabled'} - 'True' {'Enabled'} - } - 'Latest Result' = $Bkjob.info.LatestStatus - 'Target Repository' = 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} - } + $OutObj = @() + $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." + $inObj = [ordered] @{ + 'Name' = $Bkjob.Name + 'Type' = $Bkjob.TypeToString + 'Status' = Switch ($Bkjob.IsScheduleEnabled) { + 'False' {'Disabled'} + 'True' {'Enabled'} + } + 'Latest Result' = $Bkjob.info.LatestStatus + 'Target Repository' = 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} } - $OutObj += [pscustomobject]$inobj - } - catch { - Write-PscriboMessage -IsWarning $_.Exception.Message } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + + $TableParams = @{ + Name = "Backup Jobs - $VeeamBackupServer" + List = $false + ColumnWidths = 25, 20, 15, 15, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + try { + $Alljobs = @() + if ($Bkjobs.info.LatestStatus) { + $Alljobs += $Bkjobs.info.LatestStatus + } + if ((Get-VBRTapeJob -ErrorAction SilentlyContinue).LastResult) { + $Alljobs += (Get-VBRTapeJob).LastResult + } + if ((Get-VSBJob -ErrorAction SilentlyContinue).GetLastResult()) { + $Alljobs += (Get-VSBJob).GetLastResult() } + $sampleData = $Alljobs | Group-Object + $exampleChart = New-Chart -Name BackupJobs -Width 600 -Height 400 - $TableParams = @{ - Name = "Backup Jobs - $VeeamBackupServer" - List = $false - ColumnWidths = 25, 20, 15, 15, 25 + $addChartAreaParams = @{ + Chart = $exampleChart + Name = 'BackupJobs' + AxisXTitle = 'Status' + AxisYTitle = 'Count' + NoAxisXMajorGridLines = $true + NoAxisYMajorGridLines = $true + } + $exampleChartArea = Add-ChartArea @addChartAreaParams -PassThru + + $addChartSeriesParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = 'exampleChartSeries' + XField = 'Name' + YField = 'Count' + Palette = 'Green' + ColorPerDataPoint = $true + } + $sampleData | Add-ColumnChartSeries @addChartSeriesParams + + $addChartTitleParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = 'BackupJob' + Text = 'Jobs Latest Result' + Font = New-Object -TypeName 'System.Drawing.Font' -ArgumentList @('Arial', '12', [System.Drawing.FontStyle]::Bold) + } + Add-ChartTitle @addChartTitleParams + + $chartFileItem = Export-Chart -Chart $exampleChart -Path (Get-Location).Path -Format "PNG" -PassThru + + if ($PassThru) + { + Write-Output -InputObject $chartFileItem + } + } + catch { + Write-PscriboMessage -IsWarning "$($_.Exception.Message) (Account Security Assessment Table)" + } + if ($OutObj) { + if ($chartFileItem) { + Image -Text 'Backup Repository - Diagram' -Align 'Center' -Percent 100 -Path $chartFileItem } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" + Section -Style Heading3 'Backup Jobs' { + Paragraph "The following section list backup jobs created in Veeam Backup & Replication." + BlankLine + $OutObj | Sort-Object -Property Name |Table @TableParams } - $OutObj | Sort-Object -Property Name |Table @TableParams } } } diff --git a/Src/Private/Get-AbrVbrBackupjobHyperV.ps1 b/Src/Private/Get-AbrVbrBackupjobHyperV.ps1 index fd33c19..01e3426 100644 --- a/Src/Private/Get-AbrVbrBackupjobHyperV.ps1 +++ b/Src/Private/Get-AbrVbrBackupjobHyperV.ps1 @@ -266,6 +266,24 @@ function Get-AbrVbrBackupjobHyperV { 'Transform To Syntethic Days' = $Bkjob.Options.BackupTargetOptions.TransformToSyntethicDays + } + if ($Bkjob.Options.GfsPolicy.IsEnabled) { + $inObj.add('Keep certain full backup longer for archival purposes (GFS)',(ConvertTo-TextYN $Bkjob.Options.GfsPolicy.IsEnabled)) + if (-Not $Bkjob.Options.GfsPolicy.Weekly.IsEnabled) { + $inObj.add('Keep Weekly full backup', ('Disabled')) + } else { + $inObj.add('Keep Weekly full backup for', ("$($Bkjob.Options.GfsPolicy.Weekly.KeepBackupsForNumberOfWeeks) weeks,`r`nIf multiple backup exist use the one from: $($Bkjob.Options.GfsPolicy.Weekly.DesiredTime)")) + } + if (-Not $Bkjob.Options.GfsPolicy.Monthly.IsEnabled) { + $inObj.add('Keep Monthly full backup', ('Disabled')) + } else { + $inObj.add('Keep Monthly full backup for', ("$($Bkjob.Options.GfsPolicy.Monthly.KeepBackupsForNumberOfMonths) months,`r`nUse weekly full backup from the following week of the month: $($Bkjob.Options.GfsPolicy.Monthly.DesiredTime)")) + } + if (-Not $Bkjob.Options.GfsPolicy.Yearly.IsEnabled) { + $inObj.add('Keep Yearly full backup', ('Disabled')) + } else { + $inObj.add('Keep Yearly full backup for', ("$($Bkjob.Options.GfsPolicy.Yearly.KeepBackupsForNumberOfYears) years,`r`nUse monthly full backup from the following month: $($Bkjob.Options.GfsPolicy.Yearly.DesiredTime)")) + } } $OutObj = [pscustomobject]$inobj @@ -568,7 +586,7 @@ function Get-AbrVbrBackupjobHyperV { Write-PscriboMessage "Discovered $($Bkjob.Name) guest processing." $inObj = [ordered] @{ 'Name' = $VSSObj.Name - 'Enabled' = ConvertTo-TextYN $Bkjob.VssOptions.Enabled + 'Enabled' = ConvertTo-TextYN $VSSObj.VssOptions.Enabled 'Resource Type' = ($Bkjob.GetHvOijs() | 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 diff --git a/Src/Private/Get-AbrVbrBackupjobVMware.ps1 b/Src/Private/Get-AbrVbrBackupjobVMware.ps1 index 56410e0..594f7e6 100644 --- a/Src/Private/Get-AbrVbrBackupjobVMware.ps1 +++ b/Src/Private/Get-AbrVbrBackupjobVMware.ps1 @@ -311,6 +311,24 @@ function Get-AbrVbrBackupjobVMware { 'Transform To Syntethic Days' = $Bkjob.Options.BackupTargetOptions.TransformToSyntethicDays + } + if ($Bkjob.Options.GfsPolicy.IsEnabled) { + $inObj.add('Keep certain full backup longer for archival purposes (GFS)',(ConvertTo-TextYN $Bkjob.Options.GfsPolicy.IsEnabled)) + if (-Not $Bkjob.Options.GfsPolicy.Weekly.IsEnabled) { + $inObj.add('Keep Weekly full backup', ('Disabled')) + } else { + $inObj.add('Keep Weekly full backup for', ("$($Bkjob.Options.GfsPolicy.Weekly.KeepBackupsForNumberOfWeeks) weeks,`r`nIf multiple backup exist use the one from: $($Bkjob.Options.GfsPolicy.Weekly.DesiredTime)")) + } + if (-Not $Bkjob.Options.GfsPolicy.Monthly.IsEnabled) { + $inObj.add('Keep Monthly full backup', ('Disabled')) + } else { + $inObj.add('Keep Monthly full backup for', ("$($Bkjob.Options.GfsPolicy.Monthly.KeepBackupsForNumberOfMonths) months,`r`nUse weekly full backup from the following week of the month: $($Bkjob.Options.GfsPolicy.Monthly.DesiredTime)")) + } + if (-Not $Bkjob.Options.GfsPolicy.Yearly.IsEnabled) { + $inObj.add('Keep Yearly full backup', ('Disabled')) + } else { + $inObj.add('Keep Yearly full backup for', ("$($Bkjob.Options.GfsPolicy.Yearly.KeepBackupsForNumberOfYears) years,`r`nUse monthly full backup from the following month: $($Bkjob.Options.GfsPolicy.Yearly.DesiredTime)")) + } } $OutObj = [pscustomobject]$inobj @@ -613,7 +631,7 @@ function Get-AbrVbrBackupjobVMware { Write-PscriboMessage "Discovered $($Bkjob.Name) guest processing." $inObj = [ordered] @{ 'Name' = $VSSObj.Name - 'Enabled' = ConvertTo-TextYN $Bkjob.VssOptions.Enabled + 'Enabled' = ConvertTo-TextYN $VSSObj.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 @@ -774,4 +792,4 @@ function Get-AbrVbrBackupjobVMware { } end {} -} +} \ No newline at end of file diff --git a/Src/Private/Get-AbrVbrFileShareBackupjob.ps1 b/Src/Private/Get-AbrVbrFileShareBackupjob.ps1 new file mode 100644 index 0000000..6fe2617 --- /dev/null +++ b/Src/Private/Get-AbrVbrFileShareBackupjob.ps1 @@ -0,0 +1,76 @@ + +function Get-AbrVbrFileShareBackupjob { + <# + .SYNOPSIS + Used by As Built Report to returns file share jobs created in Veeam Backup & Replication. + .DESCRIPTION + Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. + .NOTES + Version: 0.5.4 + 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 File Share Backup jobs information from $System." + } + + process { + try { + $FSBkjobs = Get-VBRJob -WarningAction SilentlyContinue | Where-Object {$_.TypeToString -like 'File Backup'} + if ($FSBkjobs.count -gt 0) { + Section -Style Heading3 'File Share Backup Jobs' { + Paragraph "The following section list file share backup jobs created in Veeam Backup & Replication." + BlankLine + $OutObj = @() + foreach ($FSBkjob in $FSBkjobs) { + try { + Write-PscriboMessage "Discovered $($FSBkjob.Name) file share." + $inObj = [ordered] @{ + 'Name' = $FSBkjob.Name + 'Type' = $FSBkjob.TypeToString + 'Status' = Switch ($FSBkjob.IsScheduleEnabled) { + 'False' {'Disabled'} + 'True' {'Enabled'} + } + 'Latest Result' = $FSBkjob.info.LatestStatus + 'Last Run' = Switch ($FSBkjob.FindLastSession()) { + $Null {'Unknown'} + default {$FSBkjob.FindLastSession().EndTimeUTC} + } + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + + $TableParams = @{ + Name = "File Share Backup Jobs - $VeeamBackupServer" + 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-AbrVbrFileShareBackupjobConf.ps1 b/Src/Private/Get-AbrVbrFileShareBackupjobConf.ps1 new file mode 100644 index 0000000..4b88f70 --- /dev/null +++ b/Src/Private/Get-AbrVbrFileShareBackupjobConf.ps1 @@ -0,0 +1,424 @@ + +function Get-AbrVbrFileShareBackupjobConf { + <# + .SYNOPSIS + Used by As Built Report to returns file share backup jobs created in Veeam Backup & Replication. + .DESCRIPTION + Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. + .NOTES + Version: 0.5.4 + 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 File Share Backup jobs information from $System." + } + + process { + try { + $Bkjobs = Get-VBRJob -WarningAction SilentlyContinue | Where-Object {$_.TypeToString -like 'File Backup'} + if (($Bkjobs).count -gt 0) { + Section -Style Heading3 'File Share Backup Jobs Configuration' { + Paragraph "The following section details the configuration of File Share type backup jobs." + BlankLine + foreach ($Bkjob in $Bkjobs) { + try { + Section -Style Heading4 $($Bkjob.Name) { + Section -Style NOTOCHeading4 -ExcludeFromTOC 'Common Information' { + $OutObj = @() + try { + $CommonInfos = (Get-VBRJob -WarningAction SilentlyContinue -Name $Bkjob.Name | Where-object {$_.TypeToString -ne 'Windows Agent Backup'}).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.GetObjectsInJob()) { + Section -Style NOTOCHeading5 -ExcludeFromTOC "Files and Folders" { + $OutObj = @() + try { + foreach ($OBJ in ($Bkjob.GetObjectsInJob() | 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 + 'File Filter Include Masks' = $OBJ.ExtendedOptions.FileSourceOptions.IncludeMasks + 'File Filter Exclude Masks' = $OBJ.ExtendedOptions.FileSourceOptions.ExcludeMasks + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Files and Folders - $($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 NOTOCHeading5 -ExcludeFromTOC 'Storage' { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) storage options." + $inObj = [ordered] @{ + 'Backup Repository' = 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} + } + 'Keep all file versions for the last' = "$($Bkjob.Options.NasBackupRetentionPolicy.ShortTermRetention) $($Bkjob.Options.NasBackupRetentionPolicy.ShortTermRetentionUnit)" + } + + $FiletoArchive = Switch ($Bkjob.Options.NasBackupRetentionPolicy.ArchiveFileExtensionsScope) { + 'ExceptSpecified' {"All file exept the following extension: $($Bkjob.Options.NasBackupRetentionPolicy.ExcludedFileExtensions)"} + 'Any' {'All Files: *.*'} + 'Specified' {"File with the following extension only: $($Bkjob.Options.NasBackupRetentionPolicy.IncludedFileExtensions)"} + } + + if ($Bkjob.Options.NasBackupRetentionPolicy.LongTermEnabled) { + $inObj.add('Keep previous file versions for', "$($Bkjob.Options.NasBackupRetentionPolicy.LongTermRetention) $($Bkjob.Options.NasBackupRetentionPolicy.LongTermRetentionUnit)") + $inObj.add('Archive repository', (Get-VBRBackupRepository | Where-Object {$_.id -eq $BKjob.FindNasBackupJobInfo().LongTermRepositoryId.Guid}).Name) + $inObj.add('File to Archive', $FiletoArchive) + } + + $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.FileShare -ge 2) { + Section -Style NOTOCHeading6 -ExcludeFromTOC "Advanced Settings (File Version)" { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) File Version options." + $FileVersionsRetentionScope = Switch ($Bkjob.Options.NasBackupRetentionPolicy.FileVersionsRetentionScope) { + 'LongTermOnly' {'Limit the number of archived file versions only'} + 'None' {'Keep all file versions'} + 'All' {'Limit the number of both recent and archived file versions'} + } + $inObj = [ordered] @{ + 'File version to keep' = $FileVersionsRetentionScope + } + if ($Bkjob.Options.NasBackupRetentionPolicy.LimitMaxActiveFileVersionsCount) { + $inObj.add('Active file version limit', $Bkjob.Options.NasBackupRetentionPolicy.MaxActiveFileVersionsCount) + } + if ($Bkjob.Options.NasBackupRetentionPolicy.LimitMaxDeletedFileVersionsCount) { + $inObj.add('Delete file version limit', $Bkjob.Options.NasBackupRetentionPolicy.MaxDeletedFileVersionsCount) + } + $OutObj = [pscustomobject]$inobj + + $TableParams = @{ + Name = "Advanced Settings (File Version) - $($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.FileShare -ge 2) { + Section -Style NOTOCHeading6 -ExcludeFromTOC "Advanced Settings (Storage)" { + $OutObj = @() + try { + Write-PscriboMessage "Discovered $($Bkjob.Name) storage options." + $inObj = [ordered] @{ + 'Inline Data Deduplication' = ConvertTo-TextYN $Bkjob.Options.BackupStorageOptions.EnableDeduplication + 'Compression Level' = Switch ($Bkjob.Options.BackupStorageOptions.CompressionLevel) { + 0 {'NONE'} + -1 {'AUTO'} + 4 {'DEDUPE_friendly'} + 5 {'OPTIMAL (Default)'} + 6 {'High'} + 9 {'EXTREME'} + } + '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.FileShare -ge 2 -and $Bkjob.Options.GenerationPolicy.EnableRechek) { + Section -Style NOTOCHeading6 -ExcludeFromTOC "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 + } + + if ($Bkjob.Options.GenerationPolicy.RecheckScheduleKind -eq 'Daily') { + $inObj.add('SLCG Schedule Day', $Bkjob.Options.GenerationPolicy.RecheckDays) + } + if ($Bkjob.Options.GenerationPolicy.RecheckScheduleKind -eq 'Monthly') { + $inObj.add('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)") + } + $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.FileShare -ge 2 -and ($Bkjob.Options.NotificationOptions.SnmpNotification -or $Bkjob.Options.NotificationOptions.SendEmailNotification2AdditionalAddresses)) { + Section -Style NOTOCHeading6 -ExcludeFromTOC "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.FileShare -ge 2 -and ($Bkjob.Options.JobScriptCommand.PreScriptEnabled -or $Bkjob.Options.JobScriptCommand.PostScriptEnabled)) { + Section -Style NOTOCHeading6 -ExcludeFromTOC "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 + } + } + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + $SecondaryTargets = [Veeam.Backup.Core.CBackupJob]::GetSecondDestinationJobs($Bkjob.Id) | Where-Object {$_.JobType -ne 'SimpleBackupCopyWorker'} + if ($SecondaryTargets) { + Section -Style NOTOCHeading5 -ExcludeFromTOC "Secondary Target" { + $OutObj = @() + try { + foreach ($SecondaryTarget in $SecondaryTargets) { + Write-PscriboMessage "Discovered $($Bkjob.Name) secondary target." + try { + $inObj = [ordered] @{ + 'Job Name' = $SecondaryTarget.Name + 'Type' = $SecondaryTarget.TypeToString + 'State' = $SecondaryTarget.info.LatestStatus + 'Description' = $SecondaryTarget.Description + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + $TableParams = @{ + Name = "Secondary Destination Jobs - $($Bkjob.Name)" + List = $false + ColumnWidths = 25, 25, 15, 35 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Sort-Object -Property 'Job Name' | Table @TableParams + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + } + } + if ($Bkjob.GetScheduleOptions().NextRun -and $Bkjob.ScheduleOptions.OptionsContinuous.Enabled -ne "True") { + Section -Style NOTOCHeading5 -ExcludeFromTOC "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 {} + +} \ No newline at end of file diff --git a/Src/Private/Get-AbrVbrInfrastructureSummary.ps1 b/Src/Private/Get-AbrVbrInfrastructureSummary.ps1 index 50ba983..9ce9aa7 100644 --- a/Src/Private/Get-AbrVbrInfrastructureSummary.ps1 +++ b/Src/Private/Get-AbrVbrInfrastructureSummary.ps1 @@ -6,7 +6,7 @@ function Get-AbrVbrInfrastructureSummary { .DESCRIPTION Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. .NOTES - Version: 0.5.3 + Version: 0.5.4 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -26,7 +26,6 @@ function Get-AbrVbrInfrastructureSummary { process { try { - Section -Style NOTOCHeading3 -ExcludeFromTOC 'Backup Infrastructure' { $OutObj = @() try { $BackupServers = (Get-VBRServer).Count @@ -48,16 +47,16 @@ function Get-AbrVbrInfrastructureSummary { Write-PscriboMessage -IsWarning $_.Exception.Message } $inObj = [ordered] @{ - 'Number of Backup Proxies' = $BackupProxies - 'Number of Managed Servers' = $BackupServers - 'Number of Backup Repositories' = $BackupRepo - 'Number of SOBR Repositories' = $SOBRRepo - 'Number of Object Repository' = $ObjectStorageRepo - 'Number of WAN Accelerator' = $WANAccels - 'Number of Cloud Service Providers' = $ServiceProviders - 'Number of SureBackup Application Group' = $SureBackupAGs - 'Number of SureBackup Virtual Lab' = $SureBackupVLs - 'Number of Locations' = $Locations + 'Backup Proxies' = $BackupProxies + 'Managed Servers' = $BackupServers + 'Backup Repositories' = $BackupRepo + 'SOBR Repositories' = $SOBRRepo + 'Object Repository' = $ObjectStorageRepo + 'WAN Accelerator' = $WANAccels + 'Cloud Service Providers' = $ServiceProviders + 'SureBackup Application Group' = $SureBackupAGs + 'SureBackup Virtual Lab' = $SureBackupVLs + 'Locations' = $Locations 'Instance Licenses (Total/Used)' = "$($InstanceLicenses.LicensedInstancesNumber)/$($InstanceLicenses.UsedInstancesNumber)" 'Socket Licenses (Total/Used)' = "$($SocketLicenses.LicensedSocketsNumber)/$($SocketLicenses.UsedSocketsNumber)" 'Capacity Licenses (Total/Used)' = "$($CapacityLicenses.LicensedCapacityTb)TB/$($CapacityLicenses.UsedCapacityTb)TB" @@ -69,14 +68,66 @@ function Get-AbrVbrInfrastructureSummary { } $TableParams = @{ - Name = "Backup Infrastructure Summary - $VeeamBackupServer" + Name = "Backup Infrastructure Inventory - $VeeamBackupServer" List = $true ColumnWidths = 50, 50 } if ($Report.ShowTableCaptions) { $TableParams['Caption'] = "- $($TableParams.Name)" } - $OutObj | Table @TableParams + try { + $inObj.Remove('Instance Licenses (Total/Used)') + $inObj.Remove('Socket Licenses (Total/Used)') + $inObj.Remove('Capacity Licenses (Total/Used)') + $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Category'; Expression = {$_.key}},@{ Name = 'Value'; Expression = {$_.value}} | Sort-Object -Property 'Category' + + $exampleChart = New-Chart -Name BackupInfrastructure -Width 600 -Height 400 + + $addChartAreaParams = @{ + Chart = $exampleChart + Name = 'exampleChartArea' + } + $exampleChartArea = Add-ChartArea @addChartAreaParams -PassThru + + $addChartSeriesParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = 'exampleChartSeries' + XField = 'Category' + YField = 'Value' + Palette = 'Green' + ColorPerDataPoint = $true + } + $exampleChartSeries = $sampleData | Add-PieChartSeries @addChartSeriesParams -PassThru + + $addChartLegendParams = @{ + Chart = $exampleChart + Name = 'Infrastructure' + TitleAlignment = 'Center' + } + Add-ChartLegend @addChartLegendParams + + $addChartTitleParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = ' ' + Text = ' ' + Font = New-Object -TypeName 'System.Drawing.Font' -ArgumentList @('Arial', '12', [System.Drawing.FontStyle]::Bold) + } + Add-ChartTitle @addChartTitleParams + + $chartFileItem = Export-Chart -Chart $exampleChart -Path (Get-Location).Path -Format "PNG" -PassThru + } + catch { + Write-PscriboMessage -IsWarning $($_.Exception.Message) + } + if ($OutObj) { + Section -Style NOTOCHeading3 -ExcludeFromTOC 'Backup Infrastructure Inventory' { + if ($chartFileItem -and ($inObj.Values | Measure-Object -Sum).Sum -ne 0) { + Image -Text 'Backup Infrastructure - Diagram' -Align 'Center' -Percent 100 -Path $chartFileItem + } + $OutObj | Table @TableParams + } } } catch { diff --git a/Src/Private/Get-AbrVbrInstalledLicense.ps1 b/Src/Private/Get-AbrVbrInstalledLicense.ps1 index 5603168..030378a 100644 --- a/Src/Private/Get-AbrVbrInstalledLicense.ps1 +++ b/Src/Private/Get-AbrVbrInstalledLicense.ps1 @@ -6,7 +6,7 @@ function Get-AbrVbrInstalledLicense { .DESCRIPTION Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. .NOTES - Version: 0.5.3 + Version: 0.5.4 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -85,72 +85,120 @@ function Get-AbrVbrInstalledLicense { #---------------------------------------------------------------------------------------------# try { $Licenses = Get-VBRInstalledLicense | Select-Object -ExpandProperty InstanceLicenseSummary - if ($Licenses) { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Instance License Usage' { - $OutObj = @() - try { - foreach ($License in $Licenses) { - Write-PscriboMessage "Discovered $($Licenses.LicensedInstancesNumber) Instance licenses." - $inObj = [ordered] @{ - 'Instances Capacity' = $License.LicensedInstancesNumber - 'Used Instances' = $License.UsedInstancesNumber - 'New Instances' = $License.NewInstancesNumber - 'Rental Instances' = $License.RentalInstancesNumber - } - $OutObj += [pscustomobject]$inobj + if ($Licenses.LicensedInstancesNumber -gt 0) { + $OutObj = @() + try { + foreach ($License in $Licenses) { + Write-PscriboMessage "Discovered $($Licenses.LicensedInstancesNumber) Instance licenses." + $inObj = [ordered] @{ + 'Instances Capacity' = $License.LicensedInstancesNumber + 'Used Instances' = $License.UsedInstancesNumber + 'New Instances' = $License.NewInstancesNumber + 'Rental Instances' = $License.RentalInstancesNumber } + $OutObj += [pscustomobject]$inobj + } + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + + $TableParams = @{ + Name = "Instance License Usage - $VeeamBackupServer" + List = $false + ColumnWidths = 25, 25, 25, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + try { + $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Category'; Expression = {$_.key}},@{ Name = 'Value'; Expression = {$_.value}} | Sort-Object -Property 'Category' + + $exampleChart = New-Chart -Name InstanceLicenseUsage -Width 600 -Height 400 + + $addChartAreaParams = @{ + Chart = $exampleChart + Name = 'exampleChartArea' + } + $exampleChartArea = Add-ChartArea @addChartAreaParams -PassThru + + $addChartSeriesParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = 'exampleChartSeries' + XField = 'Category' + YField = 'Value' + Palette = 'Green' + ColorPerDataPoint = $true + } + $exampleChartSeries = $sampleData | Add-PieChartSeries @addChartSeriesParams -PassThru + + $addChartLegendParams = @{ + Chart = $exampleChart + Name = 'Category' + TitleAlignment = 'Center' + } + Add-ChartLegend @addChartLegendParams + + $addChartTitleParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = ' ' + Text = ' ' + Font = New-Object -TypeName 'System.Drawing.Font' -ArgumentList @('Arial', '12', [System.Drawing.FontStyle]::Bold) } - catch { - Write-PscriboMessage -IsWarning $_.Exception.Message - } - - $TableParams = @{ - Name = "Instance License Usage - $VeeamBackupServer" - List = $false - ColumnWidths = 25, 25, 25, 25 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" - } - $OutObj | Table @TableParams - #---------------------------------------------------------------------------------------------# - # Per Instance Section # - #---------------------------------------------------------------------------------------------# - try { - $Licenses = (Get-VBRInstalledLicense | Select-Object -ExpandProperty InstanceLicenseSummary).Object - if ($Licenses) { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Per Instance Type License Usage' { - $OutObj = @() - try { - foreach ($License in $Licenses) { - Write-PscriboMessage "Discovered $($Licenses.Type) Instance licenses." - $inObj = [ordered] @{ - 'Type' = $License.Type - 'Count' = $License.Count - 'Multiplier' = $License.Multiplier - 'Used Instances' = $License.UsedInstancesNumber + Add-ChartTitle @addChartTitleParams + + $chartFileItem = Export-Chart -Chart $exampleChart -Path (Get-Location).Path -Format "PNG" -PassThru + } + catch { + Write-PscriboMessage -IsWarning $($_.Exception.Message) + } + if ($OutObj) { + Section -Style NOTOCHeading5 -ExcludeFromTOC 'Instance License Usage' { + if ($chartFileItem -and ($inObj.Values | Measure-Object -Sum).Sum -ne 0) { + Image -Text 'Instance License Usage - Diagram' -Align 'Center' -Percent 100 -Path $chartFileItem + } + $OutObj | Table @TableParams + #---------------------------------------------------------------------------------------------# + # Per Instance Section # + #---------------------------------------------------------------------------------------------# + try { + $Licenses = (Get-VBRInstalledLicense | Select-Object -ExpandProperty InstanceLicenseSummary).Object + if ($Licenses) { + Section -Style NOTOCHeading5 -ExcludeFromTOC 'Per Instance Type License Usage' { + $OutObj = @() + try { + foreach ($License in $Licenses) { + Write-PscriboMessage "Discovered $($Licenses.Type) Instance licenses." + $inObj = [ordered] @{ + 'Type' = $License.Type + 'Count' = $License.Count + 'Multiplier' = $License.Multiplier + 'Used Instances' = $License.UsedInstancesNumber + } + $OutObj += [pscustomobject]$inobj } - $OutObj += [pscustomobject]$inobj } - } - catch { - Write-PscriboMessage -IsWarning $_.Exception.Message - } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } - $TableParams = @{ - Name = "Per Instance Type - $VeeamBackupServer" - List = $false - ColumnWidths = 25, 25, 25, 25 - } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" + $TableParams = @{ + Name = "Per Instance Type - $VeeamBackupServer" + List = $false + ColumnWidths = 25, 25, 25, 25 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + $OutObj | Table @TableParams } - $OutObj | Table @TableParams } } - } - catch { - Write-PscriboMessage -IsWarning $_.Exception.Message + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } } } } @@ -163,33 +211,81 @@ function Get-AbrVbrInstalledLicense { #---------------------------------------------------------------------------------------------# try { $Licenses = Get-VBRInstalledLicense | Select-Object -ExpandProperty SocketLicenseSummary - if ($Licenses) { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'CPU Socket License Usage' { - $OutObj = @() - try { - foreach ($License in $Licenses) { - Write-PscriboMessage "Discovered $($Licenses.LicensedSocketsNumber) CPU Socket licenses." - $inObj = [ordered] @{ - 'Licensed Sockets' = $License.LicensedSocketsNumber - 'Used Sockets Licenses' = $License.UsedSocketsNumber - 'Remaining Sockets Licenses' = $License.RemainingSocketsNumber - } - $OutObj += [pscustomobject]$inobj + if ($Licenses.LicensedSocketsNumber -gt 0) { + $OutObj = @() + try { + foreach ($License in $Licenses) { + Write-PscriboMessage "Discovered $($Licenses.LicensedSocketsNumber) CPU Socket licenses." + $inObj = [ordered] @{ + 'Licensed Sockets' = $License.LicensedSocketsNumber + 'Used Sockets Licenses' = $License.UsedSocketsNumber + 'Remaining Sockets Licenses' = $License.RemainingSocketsNumber } + $OutObj += [pscustomobject]$inobj } - catch { - Write-PscriboMessage -IsWarning $_.Exception.Message + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + + $TableParams = @{ + Name = "CPU Socket Usage - $VeeamBackupServer" + List = $false + ColumnWidths = 33, 33, 34 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + try { + $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Category'; Expression = {$_.key}},@{ Name = 'Value'; Expression = {$_.value}} | Sort-Object -Property 'Category' + + $exampleChart = New-Chart -Name CPUSocketUsage -Width 600 -Height 400 + + $addChartAreaParams = @{ + Chart = $exampleChart + Name = 'exampleChartArea' + } + $exampleChartArea = Add-ChartArea @addChartAreaParams -PassThru + + $addChartSeriesParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = 'exampleChartSeries' + XField = 'Category' + YField = 'Value' + Palette = 'Green' + ColorPerDataPoint = $true } + $exampleChartSeries = $sampleData | Add-PieChartSeries @addChartSeriesParams -PassThru - $TableParams = @{ - Name = "CPU Socket Usage - $VeeamBackupServer" - List = $false - ColumnWidths = 33, 33, 34 + $addChartLegendParams = @{ + Chart = $exampleChart + Name = 'Category' + TitleAlignment = 'Center' } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" + Add-ChartLegend @addChartLegendParams + + $addChartTitleParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = ' ' + Text = ' ' + Font = New-Object -TypeName 'System.Drawing.Font' -ArgumentList @('Arial', '12', [System.Drawing.FontStyle]::Bold) + } + Add-ChartTitle @addChartTitleParams + + $chartFileItem = Export-Chart -Chart $exampleChart -Path (Get-Location).Path -Format "PNG" -PassThru + } + catch { + Write-PscriboMessage -IsWarning $($_.Exception.Message) + } + if ($OutObj) { + Section -Style NOTOCHeading5 -ExcludeFromTOC 'CPU Socket License Usage' { + if ($chartFileItem -and ($inObj.Values | Measure-Object -Sum).Sum -ne 0) { + Image -Text 'CPU Socket License Usage - Diagram' -Align 'Center' -Percent 100 -Path $chartFileItem + } + $OutObj | Table @TableParams } - $OutObj | Table @TableParams } } } @@ -201,32 +297,80 @@ function Get-AbrVbrInstalledLicense { #---------------------------------------------------------------------------------------------# try { $Licenses = Get-VBRInstalledLicense | Select-Object -ExpandProperty CapacityLicenseSummary - if ($Licenses) { - Section -Style NOTOCHeading5 -ExcludeFromTOC 'Capacity License Usage' { - $OutObj = @() - try { - foreach ($License in $Licenses) { - Write-PscriboMessage "Discovered $($Licenses.LicensedCapacityTb) Capacity licenses." - $inObj = [ordered] @{ - 'Licensed Capacity in Tb' = $License.LicensedCapacityTb - 'Used Capacity in Tb' = $License.UsedCapacityTb - } - $OutObj += [pscustomobject]$inobj + if ($Licenses.LicensedCapacityTb -gt 0) { + $OutObj = @() + try { + foreach ($License in $Licenses) { + Write-PscriboMessage "Discovered $($Licenses.LicensedCapacityTb) Capacity licenses." + $inObj = [ordered] @{ + 'Licensed Capacity in TB' = $License.LicensedCapacityTb + 'Used Capacity in TB' = $License.UsedCapacityTb } + $OutObj += [pscustomobject]$inobj } - catch { - Write-PscriboMessage -IsWarning $_.Exception.Message + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + + $TableParams = @{ + Name = "Capacity License Usage - $VeeamBackupServer" + List = $false + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + try { + $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Category'; Expression = {$_.key}},@{ Name = 'Value'; Expression = {$_.value}} | Sort-Object -Property 'Category' + + $exampleChart = New-Chart -Name CapacityLicenseUsage -Width 600 -Height 400 + + $addChartAreaParams = @{ + Chart = $exampleChart + Name = 'exampleChartArea' + } + $exampleChartArea = Add-ChartArea @addChartAreaParams -PassThru + + $addChartSeriesParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = 'exampleChartSeries' + XField = 'Category' + YField = 'Value' + Palette = 'Green' + ColorPerDataPoint = $true + } + $exampleChartSeries = $sampleData | Add-PieChartSeries @addChartSeriesParams -PassThru + + $addChartLegendParams = @{ + Chart = $exampleChart + Name = 'Category' + TitleAlignment = 'Center' } + Add-ChartLegend @addChartLegendParams - $TableParams = @{ - Name = "Capacity License Usage - $VeeamBackupServer" - List = $false - ColumnWidths = 50, 50 + $addChartTitleParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = ' ' + Text = ' ' + Font = New-Object -TypeName 'System.Drawing.Font' -ArgumentList @('Arial', '12', [System.Drawing.FontStyle]::Bold) } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" + Add-ChartTitle @addChartTitleParams + + $chartFileItem = Export-Chart -Chart $exampleChart -Path (Get-Location).Path -Format "PNG" -PassThru + } + catch { + Write-PscriboMessage -IsWarning $($_.Exception.Message) + } + if ($OutObj) { + Section -Style NOTOCHeading5 -ExcludeFromTOC 'Capacity License Usage' { + if ($chartFileItem -and ($inObj.Values | Measure-Object -Sum).Sum -ne 0) { + Image -Text 'Capacity License Usage - Diagram' -Align 'Center' -Percent 100 -Path $chartFileItem + } + $OutObj | Table @TableParams } - $OutObj | Table @TableParams } } } diff --git a/Src/Private/Get-AbrVbrInventorySummary.ps1 b/Src/Private/Get-AbrVbrInventorySummary.ps1 index ca09509..7c688f2 100644 --- a/Src/Private/Get-AbrVbrInventorySummary.ps1 +++ b/Src/Private/Get-AbrVbrInventorySummary.ps1 @@ -6,7 +6,7 @@ function Get-AbrVbrInventorySummary { .DESCRIPTION Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. .NOTES - Version: 0.5.3 + Version: 0.5.4 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -26,38 +26,86 @@ function Get-AbrVbrInventorySummary { process { try { - Section -Style NOTOCHeading3 -ExcludeFromTOC 'Inventory' { - $OutObj = @() - try { - $vCenter = Get-VBRServer | Where-Object {$_.Type -eq 'VC'} - $ESXi = Get-VBRServer | Where-Object {$_.Type -eq 'ESXi'} - $HvCluster = Get-VBRServer | Where-Object {$_.Type -eq 'HvCluster'} - $HvServer = Get-VBRServer | Where-Object {$_.Type -eq 'HvServer'} - $ProtectionGroups = Get-VBRProtectionGroup - $Shares = Get-VBRNASServer - $inObj = [ordered] @{ - 'Number of vCenter Servers' = $vCenter.Count - 'Number of ESXi Servers' = $ESXi.Count - 'Number of Hyper-V Clusters' = $HvCluster.Count - 'Number of Hyper-V Servers' = $HvServer.Count - 'Number of Protection Groups' = $ProtectionGroups.Count - 'Number of File Shares' = $Shares.Count - } - $OutObj += [pscustomobject]$inobj + $OutObj = @() + try { + $vCenter = Get-VBRServer | Where-Object {$_.Type -eq 'VC'} + $ESXi = Get-VBRServer | Where-Object {$_.Type -eq 'ESXi'} + $HvCluster = Get-VBRServer | Where-Object {$_.Type -eq 'HvCluster'} + $HvServer = Get-VBRServer | Where-Object {$_.Type -eq 'HvServer'} + $ProtectionGroups = Get-VBRProtectionGroup + $Shares = Get-VBRNASServer + $inObj = [ordered] @{ + 'vCenter Servers' = $vCenter.Count + 'ESXi Servers' = $ESXi.Count + 'Hyper-V Clusters' = $HvCluster.Count + 'Hyper-V Servers' = $HvServer.Count + 'Protection Groups' = $ProtectionGroups.Count + 'File Shares' = $Shares.Count + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + + $TableParams = @{ + Name = "Inventory Summary - $VeeamBackupServer" + List = $true + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + try { + $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Category'; Expression = {$_.key}},@{ Name = 'Value'; Expression = {$_.value}} | Sort-Object -Property 'Category' + + $exampleChart = New-Chart -Name Inventory -Width 600 -Height 400 + + $addChartAreaParams = @{ + Chart = $exampleChart + Name = 'exampleChartArea' + } + $exampleChartArea = Add-ChartArea @addChartAreaParams -PassThru + + $addChartSeriesParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = 'exampleChartSeries' + XField = 'Category' + YField = 'Value' + Palette = 'Green' + ColorPerDataPoint = $true } - catch { - Write-PscriboMessage -IsWarning $_.Exception.Message + $exampleChartSeries = $sampleData | Add-PieChartSeries @addChartSeriesParams -PassThru + + $addChartLegendParams = @{ + Chart = $exampleChart + Name = 'Infrastructure' + TitleAlignment = 'Center' } + Add-ChartLegend @addChartLegendParams - $TableParams = @{ - Name = "Inventory Summary - $VeeamBackupServer" - List = $true - ColumnWidths = 50, 50 + $addChartTitleParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = ' ' + Text = ' ' + Font = New-Object -TypeName 'System.Drawing.Font' -ArgumentList @('Arial', '12', [System.Drawing.FontStyle]::Bold) } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" + Add-ChartTitle @addChartTitleParams + + $chartFileItem = Export-Chart -Chart $exampleChart -Path (Get-Location).Path -Format "PNG" -PassThru + } + catch { + Write-PscriboMessage -IsWarning $($_.Exception.Message) + } + if ($OutObj) { + Section -Style NOTOCHeading3 -ExcludeFromTOC 'Inventory' { + if ($chartFileItem -and ($inObj.Values | Measure-Object -Sum).Sum -ne 0) { + Image -Text 'Inventory - Diagram' -Align 'Center' -Percent 100 -Path $chartFileItem + } + $OutObj | Table @TableParams } - $OutObj | Table @TableParams } } catch { diff --git a/Src/Private/Get-AbrVbrReplInfraSummary.ps1 b/Src/Private/Get-AbrVbrReplInfraSummary.ps1 index 2ad3db0..60e99a3 100644 --- a/Src/Private/Get-AbrVbrReplInfraSummary.ps1 +++ b/Src/Private/Get-AbrVbrReplInfraSummary.ps1 @@ -6,7 +6,7 @@ function Get-AbrVbrReplInfraSummary { .DESCRIPTION Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. .NOTES - Version: 0.5.3 + Version: 0.5.4 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -26,25 +26,73 @@ function Get-AbrVbrReplInfraSummary { process { try { - Section -Style NOTOCHeading3 -ExcludeFromTOC 'Replication' { - $OutObj = @() - $Replicas = Get-VBRReplica - $FailOverPlans = Get-VBRFailoverPlan - $inObj = [ordered] @{ - 'Number of Replicas' = $Replicas.Count - 'Number of Failover Plans' = $FailOverPlans.Count + $OutObj = @() + $Replicas = Get-VBRReplica + $FailOverPlans = Get-VBRFailoverPlan + $inObj = [ordered] @{ + 'Replicas' = $Replicas.Count + 'Failover Plans' = $FailOverPlans.Count + } + $OutObj += [pscustomobject]$inobj + + $TableParams = @{ + Name = "Replication Inventory - $VeeamBackupServer" + List = $true + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + try { + $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Category'; Expression = {$_.key}},@{ Name = 'Value'; Expression = {$_.value}} | Sort-Object -Property 'Category' + + $exampleChart = New-Chart -Name ReplicationInventory -Width 600 -Height 400 + + $addChartAreaParams = @{ + Chart = $exampleChart + Name = 'exampleChartArea' } - $OutObj += [pscustomobject]$inobj + $exampleChartArea = Add-ChartArea @addChartAreaParams -PassThru - $TableParams = @{ - Name = "Replication Summary - $VeeamBackupServer" - List = $true - ColumnWidths = 40, 60 + $addChartSeriesParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = 'exampleChartSeries' + XField = 'Category' + YField = 'Value' + Palette = 'Green' + ColorPerDataPoint = $true } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" + $exampleChartSeries = $sampleData | Add-PieChartSeries @addChartSeriesParams -PassThru + + $addChartLegendParams = @{ + Chart = $exampleChart + Name = 'Infrastructure' + TitleAlignment = 'Center' + } + Add-ChartLegend @addChartLegendParams + + $addChartTitleParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = ' ' + Text = ' ' + Font = New-Object -TypeName 'System.Drawing.Font' -ArgumentList @('Arial', '12', [System.Drawing.FontStyle]::Bold) + } + Add-ChartTitle @addChartTitleParams + + $chartFileItem = Export-Chart -Chart $exampleChart -Path (Get-Location).Path -Format "PNG" -PassThru + } + catch { + Write-PscriboMessage -IsWarning $($_.Exception.Message) + } + if ($OutObj) { + Section -Style NOTOCHeading3 -ExcludeFromTOC 'Replication Inventory' { + if ($chartFileItem -and ($inObj.Values | Measure-Object -Sum).Sum -ne 0) { + Image -Text 'Replication Inventory - Diagram' -Align 'Center' -Percent 100 -Path $chartFileItem + } + $OutObj | Table @TableParams } - $OutObj | Table @TableParams } } catch { diff --git a/Src/Private/Get-AbrVbrRepljobHyperV.ps1 b/Src/Private/Get-AbrVbrRepljobHyperV.ps1 index 14bd07d..f61fa00 100644 --- a/Src/Private/Get-AbrVbrRepljobHyperV.ps1 +++ b/Src/Private/Get-AbrVbrRepljobHyperV.ps1 @@ -6,7 +6,7 @@ function Get-AbrVbrRepljobHyperV { .DESCRIPTION Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. .NOTES - Version: 0.5.3 + Version: 0.5.4 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -607,7 +607,7 @@ function Get-AbrVbrRepljobHyperV { Write-PscriboMessage "Discovered $($Bkjob.Name) guest processing." $inObj = [ordered] @{ 'Name' = $VSSObj.Name - 'Enabled' = ConvertTo-TextYN $Bkjob.VssOptions.Enabled + 'Enabled' = ConvertTo-TextYN $VSSObj.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 diff --git a/Src/Private/Get-AbrVbrRepljobVMware.ps1 b/Src/Private/Get-AbrVbrRepljobVMware.ps1 index 232b171..3c3e007 100644 --- a/Src/Private/Get-AbrVbrRepljobVMware.ps1 +++ b/Src/Private/Get-AbrVbrRepljobVMware.ps1 @@ -6,7 +6,7 @@ function Get-AbrVbrRepljobVMware { .DESCRIPTION Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. .NOTES - Version: 0.5.3 + Version: 0.5.4 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -611,7 +611,7 @@ function Get-AbrVbrRepljobVMware { Write-PscriboMessage "Discovered $($Bkjob.Name) guest processing." $inObj = [ordered] @{ 'Name' = $VSSObj.Name - 'Enabled' = ConvertTo-TextYN $Bkjob.VssOptions.Enabled + 'Enabled' = ConvertTo-TextYN $VSSObj.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 diff --git a/Src/Private/Get-AbrVbrStorageInfraSummary.ps1 b/Src/Private/Get-AbrVbrStorageInfraSummary.ps1 index bd948c1..72feab7 100644 --- a/Src/Private/Get-AbrVbrStorageInfraSummary.ps1 +++ b/Src/Private/Get-AbrVbrStorageInfraSummary.ps1 @@ -6,7 +6,7 @@ function Get-AbrVbrStorageInfraSummary { .DESCRIPTION Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. .NOTES - Version: 0.5.3 + Version: 0.5.4 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -26,34 +26,82 @@ function Get-AbrVbrStorageInfraSummary { process { try { - Section -Style NOTOCHeading3 -ExcludeFromTOC 'Storage Infrastructure' { - $OutObj = @() - try { - $OntapHosts = Get-NetAppHost - $OntapVols = Get-NetAppVolume - $IsilonHosts = Get-VBRIsilonHost - $IsilonVols = Get-VBRIsilonVolume - $inObj = [ordered] @{ - 'Number of NetApp Ontap Storage' = $OntapHosts.Count - 'Number of NetApp Ontap Volumes' = $OntapHosts.Count - 'Number of Dell Isilon Storage' = $IsilonHosts.Count - 'Number of Dell Isilon Volumes' = $IsilonVols.Count - } - $OutObj += [pscustomobject]$inobj + $OutObj = @() + try { + $OntapHosts = Get-NetAppHost + $OntapVols = Get-NetAppVolume + $IsilonHosts = Get-VBRIsilonHost + $IsilonVols = Get-VBRIsilonVolume + $inObj = [ordered] @{ + 'NetApp Ontap Storage' = $OntapHosts.Count + 'NetApp Ontap Volumes' = $OntapHosts.Count + 'Dell Isilon Storage' = $IsilonHosts.Count + 'Dell Isilon Volumes' = $IsilonVols.Count + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + + $TableParams = @{ + Name = "Storage Infrastructure Inventory - $VeeamBackupServer" + List = $true + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + try { + $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Category'; Expression = {$_.key}},@{ Name = 'Value'; Expression = {$_.value}} | Sort-Object -Property 'Category' + + $exampleChart = New-Chart -Name StorageInfrastructure -Width 600 -Height 400 + + $addChartAreaParams = @{ + Chart = $exampleChart + Name = 'exampleChartArea' + } + $exampleChartArea = Add-ChartArea @addChartAreaParams -PassThru + + $addChartSeriesParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = 'exampleChartSeries' + XField = 'Category' + YField = 'Value' + Palette = 'Green' + ColorPerDataPoint = $true } - catch { - Write-PscriboMessage -IsWarning $_.Exception.Message + $exampleChartSeries = $sampleData | Add-PieChartSeries @addChartSeriesParams -PassThru + + $addChartLegendParams = @{ + Chart = $exampleChart + Name = 'Infrastructure' + TitleAlignment = 'Center' } + Add-ChartLegend @addChartLegendParams - $TableParams = @{ - Name = "Storage Infrastructure Summary - $VeeamBackupServer" - List = $true - ColumnWidths = 50, 50 + $addChartTitleParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = ' ' + Text = ' ' + Font = New-Object -TypeName 'System.Drawing.Font' -ArgumentList @('Arial', '12', [System.Drawing.FontStyle]::Bold) } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" + Add-ChartTitle @addChartTitleParams + + $chartFileItem = Export-Chart -Chart $exampleChart -Path (Get-Location).Path -Format "PNG" -PassThru + } + catch { + Write-PscriboMessage -IsWarning $($_.Exception.Message) + } + if ($OutObj) { + Section -Style NOTOCHeading3 -ExcludeFromTOC 'Storage Infrastructure Inventory' { + if ($chartFileItem -and ($inObj.Values | Measure-Object -Sum).Sum -ne 0) { + Image -Text 'Storage Infrastructure Inventory - Diagram' -Align 'Center' -Percent 100 -Path $chartFileItem + } + $OutObj | Table @TableParams } - $OutObj | Table @TableParams } } catch { diff --git a/Src/Private/Get-AbrVbrStorageIsilon.ps1 b/Src/Private/Get-AbrVbrStorageIsilon.ps1 index 76ad59d..88a57bc 100644 --- a/Src/Private/Get-AbrVbrStorageIsilon.ps1 +++ b/Src/Private/Get-AbrVbrStorageIsilon.ps1 @@ -49,8 +49,8 @@ function Get-AbrVbrStorageIsilon { 0 {"-"} default {"$($UsedCred.Name) - ($($UsedCred.Description))"} } - 'Connnection Address' = $IsilonOptions.IsilonHostOptions.AdditionalAddresses.IP -join ", " - 'Connnection Port' = "$($IsilonOptions.IsilonHostOptions.Port)\TCP" + 'Connection Address' = $IsilonOptions.IsilonHostOptions.AdditionalAddresses.IP -join ", " + 'Connection Port' = "$($IsilonOptions.IsilonHostOptions.Port)\TCP" } $OutObj = [pscustomobject]$inobj diff --git a/Src/Private/Get-AbrVbrStorageOntap.ps1 b/Src/Private/Get-AbrVbrStorageOntap.ps1 index 7285fda..9153344 100644 --- a/Src/Private/Get-AbrVbrStorageOntap.ps1 +++ b/Src/Private/Get-AbrVbrStorageOntap.ps1 @@ -28,7 +28,7 @@ function Get-AbrVbrStorageOntap { try { if ((Get-NetAppHost).count -gt 0) { Section -Style Heading3 'NetApp Ontap Storage' { - Paragraph "TThe following section details information about NetApp storage infrastructure." + Paragraph "The following section details information about NetApp storage infrastructure." BlankLine $OutObj = @() try { @@ -50,8 +50,8 @@ function Get-AbrVbrStorageOntap { 0 {"-"} default {"$($UsedCred.Name) - ($($UsedCred.Description))"} } - 'Connnection Address' = $OntapHost.ConnPoints -join ", " - 'Connnection Port' = "$($OntapOptions.NaHostOptions.NaHostOptions.NaHostConnectionOptions.Port)\TCP" + 'Connection Address' = $OntapHost.ConnPoints -join ", " + 'Connection Port' = "$($OntapOptions.NaHostOptions.NaHostOptions.NaHostConnectionOptions.Port)\TCP" 'Installed Licenses' = $OntapHost.NaOptions.License } diff --git a/Src/Private/Get-AbrVbrTapeInfraSummary.ps1 b/Src/Private/Get-AbrVbrTapeInfraSummary.ps1 index c1553c5..c007213 100644 --- a/Src/Private/Get-AbrVbrTapeInfraSummary.ps1 +++ b/Src/Private/Get-AbrVbrTapeInfraSummary.ps1 @@ -6,7 +6,7 @@ function Get-AbrVbrTapeInfraSummary { .DESCRIPTION Documents the configuration of Veeam VBR in Word/HTML/Text formats using PScribo. .NOTES - Version: 0.5.3 + Version: 0.5.4 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -26,38 +26,86 @@ function Get-AbrVbrTapeInfraSummary { process { try { - Section -Style NOTOCHeading3 -ExcludeFromTOC 'Tape Infrastructure' { - $OutObj = @() - try { - $TapeServer = Get-VBRTapeServer - $TapeLibrary = Get-VBRTapeLibrary - $TapeMediaPool = Get-VBRTapeMediaPool - $TapeVault = Get-VBRTapeVault - $TapeDrive = Get-VBRTapeDrive - $TapeMedium = Get-VBRTapeMedium - $inObj = [ordered] @{ - 'Number of Tape Servers' = $TapeServer.Count - 'Number of Tape Library' = $TapeLibrary.Count - 'Number of Tape MediaPool' = $TapeMediaPool.Count - 'Number of Tape Vault' = $TapeVault.Count - 'Number of Tape Drives' = $TapeDrive.Count - 'Number of Tape Medium' = $TapeMedium.Count - } - $OutObj += [pscustomobject]$inobj + $OutObj = @() + try { + $TapeServer = Get-VBRTapeServer + $TapeLibrary = Get-VBRTapeLibrary + $TapeMediaPool = Get-VBRTapeMediaPool + $TapeVault = Get-VBRTapeVault + $TapeDrive = Get-VBRTapeDrive + $TapeMedium = Get-VBRTapeMedium + $inObj = [ordered] @{ + 'Tape Servers' = $TapeServer.Count + 'Tape Library' = $TapeLibrary.Count + 'Tape MediaPool' = $TapeMediaPool.Count + 'Tape Vault' = $TapeVault.Count + 'Tape Drives' = $TapeDrive.Count + 'Tape Medium' = $TapeMedium.Count + } + $OutObj += [pscustomobject]$inobj + } + catch { + Write-PscriboMessage -IsWarning $_.Exception.Message + } + + $TableParams = @{ + Name = "Tape Infrastructure Inventory - $VeeamBackupServer" + List = $true + ColumnWidths = 50, 50 + } + if ($Report.ShowTableCaptions) { + $TableParams['Caption'] = "- $($TableParams.Name)" + } + try { + $sampleData = $inObj.GetEnumerator() | Select-Object @{ Name = 'Category'; Expression = {$_.key}},@{ Name = 'Value'; Expression = {$_.value}} | Sort-Object -Property 'Category' + + $exampleChart = New-Chart -Name TapeInfrastructure -Width 600 -Height 400 + + $addChartAreaParams = @{ + Chart = $exampleChart + Name = 'exampleChartArea' + } + $exampleChartArea = Add-ChartArea @addChartAreaParams -PassThru + + $addChartSeriesParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = 'exampleChartSeries' + XField = 'Category' + YField = 'Value' + Palette = 'Green' + ColorPerDataPoint = $true } - catch { - Write-PscriboMessage -IsWarning $_.Exception.Message + $exampleChartSeries = $sampleData | Add-PieChartSeries @addChartSeriesParams -PassThru + + $addChartLegendParams = @{ + Chart = $exampleChart + Name = 'Infrastructure' + TitleAlignment = 'Center' } + Add-ChartLegend @addChartLegendParams - $TableParams = @{ - Name = "Tape Infrastructure Summary - $VeeamBackupServer" - List = $true - ColumnWidths = 50, 50 + $addChartTitleParams = @{ + Chart = $exampleChart + ChartArea = $exampleChartArea + Name = ' ' + Text = ' ' + Font = New-Object -TypeName 'System.Drawing.Font' -ArgumentList @('Arial', '12', [System.Drawing.FontStyle]::Bold) } - if ($Report.ShowTableCaptions) { - $TableParams['Caption'] = "- $($TableParams.Name)" + Add-ChartTitle @addChartTitleParams + + $chartFileItem = Export-Chart -Chart $exampleChart -Path (Get-Location).Path -Format "PNG" -PassThru + } + catch { + Write-PscriboMessage -IsWarning $($_.Exception.Message) + } + if ($OutObj) { + Section -Style NOTOCHeading3 -ExcludeFromTOC 'Tape Infrastructure' { + if ($chartFileItem -and ($inObj.Values | Measure-Object -Sum).Sum -ne 0) { + Image -Text 'Tape Infrastructure - Diagram' -Align 'Center' -Percent 100 -Path $chartFileItem + } + $OutObj | Table @TableParams } - $OutObj | Table @TableParams } } catch { diff --git a/Src/Public/Invoke-AsBuiltReport.Veeam.VBR.ps1 b/Src/Public/Invoke-AsBuiltReport.Veeam.VBR.ps1 index 2cdf674..a990fb7 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.5.3 + Version: 0.5.4 Author: Jonathan Colon Twitter: @jcolonfzenpr Github: rebelinux @@ -26,6 +26,17 @@ function Invoke-AsBuiltReport.Veeam.VBR { Write-PScriboMessage -IsWarning "Documentation: https://github.com/AsBuiltReport/AsBuiltReport.Veeam.VBR" Write-PScriboMessage -IsWarning "Issues or bug reporting: https://github.com/AsBuiltReport/AsBuiltReport.Veeam.VBR/issues" + $InstalledVersion = Get-Module -ListAvailable -Name AsBuiltReport.Veeam.VBR -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Version + + if ($InstalledVersion) { + Write-PScriboMessage -IsWarning "Installed AsBuiltReport.Veeam.VBR Version: $($InstalledVersion.ToString())" + $MostCurrentVersion = Find-Module -Name AsBuiltReport.Veeam.VBR -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Version + if ($MostCurrentVersion -and ($MostCurrentVersion -gt $InstalledVersion)) { + Write-PScriboMessage -IsWarning "New Update: AsBuiltReport.Veeam.VBR Version: $($MostCurrentVersion.ToString())" + Write-PScriboMessage -IsWarning "To Update run: Update-Module -Name AsBuiltReport.Veeam.VBR -Force" + } + } + # Import Report Configuration $Report = $ReportConfig.Report $InfoLevel = $ReportConfig.InfoLevel @@ -235,6 +246,11 @@ function Invoke-AsBuiltReport.Veeam.VBR { Get-AbrVbrAgentBackupjob Get-AbrVbrAgentBackupjobConf } + Write-PScriboMessage "File Share Jobs InfoLevel set at $($InfoLevel.Jobs.FileShare)." + if ($InfoLevel.Jobs.FileShare -ge 1) { + Get-AbrVbrFileShareBackupjob + Get-AbrVbrFileShareBackupjobConf + } } } }