├── AdditionalResources.md ├── FullResVideos.md ├── LICENSE ├── README.md ├── SampleOutput ├── Session1 │ ├── ConfigReports │ │ ├── ausveeambr_Jobs.csv │ │ ├── ausveeambr_Proxies.csv │ │ ├── ausveeambr_Repositories.csv │ │ ├── ausveeambr_SOBRExtents.csv │ │ ├── ausveeambr_SOBRs.csv │ │ └── ausveeambr_Servers.csv │ ├── JobStatusMethods.csv │ ├── JobStatusProperties.csv │ ├── VM_DiskFilterDetails.csv │ ├── VeeamBackupSizeReport1.csv │ ├── VeeamBackupSizeReport2.csv │ ├── VeeamRestorePointReport1.csv │ ├── VeeamRestorePointReport2.csv │ ├── VeeamSessionReport1.csv │ └── VeeamSessionReport2.csv └── Session2 │ ├── SQLRestorePointReport.csv │ ├── VeeamJobComparisonDetails.csv │ └── VeeamJobDetails.csv ├── Session1 ├── 10_VeeamGeneralOptions.ps1 ├── 11_Get-VBRConfig.ps1 ├── 12_Get-VeeamSessionReport_Quick.ps1 ├── 12_Get-VeeamSessionReport_Slow.ps1 ├── 13_Get-VMandDiskFilterDetails.ps1 ├── 14_VMsNotInBackups.ps1 ├── 1_NewBackupShellJob.ps1 ├── 2_QuickJobStatus.ps1 ├── 3_RestorePointReport_Quick.ps1 ├── 3_RestorePointReport_Slow.ps1 ├── 4_VeeamBackupSize_Quick.ps1 ├── 4_VeeamBackupSize_Slow.ps1 ├── 5_ProtectionScopeGroupJob.ps1 ├── 6_API_Backup_Session_Report.ps1 ├── 7_FindCmdletsByParameterType.ps1 ├── 8_ExportVeeamTypes&Methods.ps1 ├── 9_Dump-VBRObject.ps1 └── Session1Scripts&Demos.md └── Session2 ├── 10_1_DeployAgentsbyIPRange-QueryVMs.ps1 ├── 10_2_DeployAgentsbyIPRange-CreateProtectionGroup.ps1 ├── 11_Send-VeeamError.ps1 ├── 12_NewBackupShellJob.ps1 ├── 13_1_AddVMsFromTextFile.ps1 ├── 13_2_MaintenanceForVMsFromTextFile.ps1 ├── 13_3_RemoveForVMsFromTextFile.ps1 ├── 15_API_Quick_Backup.ps1 ├── 16_AWS_EC2_Restore.ps1 ├── 17_AzureRestore.ps1 ├── 19_1_Run-SQLRestorePointReport.ps1 ├── 19_2_Run-OracleRestorePointReport.ps1 ├── 1_AgentToVMInstantRecovery.ps1 ├── 2_NASCmdlets.ps1 ├── 3_DataIntegrationAPI.ps1 ├── 4_VirtualLabAutomation.ps1 ├── 5_LicenseCmdlets.ps1 ├── 6_Get-VeeamJobConfiguration.ps1 ├── 7_Run-VeeamJobComparison.ps1 ├── 8_SetJobOptions&SQLVSS.ps1 ├── 9_CloneJob&Options.ps1 ├── AutomaticVMBackup ├── Find-UnprotectedVMs.ps1 └── Protect-MissingVMs.ps1 ├── Session2Scripts&Demos.md ├── VMsFromTextFile ├── AddVMs.txt ├── MaintenanceVMs.txt └── RemoveVMs.txt └── VeeamJobConfigs ├── Binaries └── Veeam.JobQuickConfig.format.ps1xml ├── LICENSE ├── Public ├── Compare-VeeamJobConfiguration.ps1 └── Get-VeeamJobConfiguration.ps1 ├── VeeamJobConfigs.psd1 └── VeeamJobConfigs.psm1 /AdditionalResources.md: -------------------------------------------------------------------------------- 1 | # Additional Resources 2 | 3 | __From Session 1:__ 4 | [Veeam PowerShell types](https://helpcenter.veeam.com/docs/backup/powershell/veeam_powershell_types.html) 5 | [Veeam PowerShell enumerations](https://helpcenter.veeam.com/docs/backup/powershell/enums.html) 6 | [VeeamHub](https://github.com/VeeamHub) 7 | [Handy PowerShell scripts](https://www.powershellgallery.com/packages/PowerShellCookbook/) 8 | 9 | __From Session 2:__ 10 | From the [PowerShell.org YouTube channel](https://www.youtube.com/channel/UCqIw7UUwC5fUBFXYX68aMrQ): 11 | - Functions/Toolmaking — Don Jones Toolmaking 12 | [Part1](https://youtu.be/KprrLkjPq_c) 13 | [Part2](https://youtu.be/U849a17G7Ro) 14 | [Part3](https://youtu.be/GXdmjCPYYNM) 15 | - Proxy functions — Jeff Hicks — [Accelerated Toolmaking](https://youtu.be/zWh4Y_7lNBg) 16 | - Optimizing performance — Joshua King — [Whip Your Scripts into Shape](https://youtu.be/Yp_m5T_kyJU) 17 | 18 | The PowerShell Scripting & Toolmaking Book — Don Jones/Jeff Hicks on [Leanpub](https://leanpub.com/powershell-scripting-toolmaking) 19 | 20 | From the ATXPowerShell YT channel [link](https://www.youtube.com/channel/UChN0jsc6e02jAh9p9rmR_Iw): 21 | - Debugging PowerShell in VSCode w/Josh Duffney [Video](https://youtu.be/Kg5eKslokao) 22 | - From Scripting to Toolmaking 23 | [Spiceworld2019](https://youtu.be/tMDZt7bC6XE) 24 | [ATXPowerShell](https://youtu.be/fex4xq4chys) 25 | 26 | __Modules:__ 27 | [PSKoans](https://github.com/vexx32/PSKoans) — Learn PowerShell through Pester 28 | [Plaster](https://github.com/PowerShellOrg/Plaster) — “Scaffolding” of modules, Pester tests, DSC configs, etc. 29 | [PlatyPS](https://github.com/PowerShell/platyPS) — Write PowerShell External Help in Markdown 30 | -------------------------------------------------------------------------------- /FullResVideos.md: -------------------------------------------------------------------------------- 1 | # Full Resolution Videos 2 | 3 | _My apologies to everyone who attended live and got a live video with no demos, or watched the on-demand content and couldn't make out the video._ 4 | 5 | _Links to the full resolution videos are below for those wanting to view the full video with included demos._ 6 | 7 | [VeeamON 2020 - Veeam Automation with PowerShell Deep Dive (Part 1)](https://youtu.be/RzZApNPEw0w) 8 | 9 | [VeeamON 2020 - Veeam Automation with PowerShell Deep Dive (Part 2)](https://youtu.be/MnpA8ruJuaM) 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Joe Houghes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VeeamOn2020PowerShell 2 | Presentation, Code & Resource Listings from VeeamON 2020 sessions titled: 3 | 4 | Veeam Automation with PowerShell Deep-Dive: 5 | Configuration, Reporting, & Testing… Oh My! 6 | 7 | (Full resolution video links are now available) 8 | 9 | Updated 6/30/2020 10 | -------------------------------------------------------------------------------- /SampleOutput/Session1/ConfigReports/ausveeambr_Jobs.csv: -------------------------------------------------------------------------------- 1 | "Name","JobType","SheduleEnabledTime","ScheduleOptions","RestorePoints","RepoName","Algorithm","FullBackupScheduleKind","FullBackupDays","TransformFullToSyntethic","TransformIncrementsToSyntethic","TransformToSyntethicDays" 2 | "zPowerShellDemoJob","Backup",,"Start time: [6/2/2020 15:00:00], Latest run time: [6/2/2020 14:55:00], Timeout for backup completion: [180min], Next run time: [], Retry times on failure: [3], Retry timeout: [10 min], Daily options: [Enabled: True, DayNumberInMonth: Everyday, Days: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday]","7","ReFS-PerVM","Increment","Daily","Saturday","True","False","Saturday" 3 | "DomainControllers","Backup","5/11/2020 21:06:30","Start time: [5/12/2020 12:25:00], Latest run time: [5/12/2020 09:12:31], Timeout for backup completion: [180min], Next run time: [], Retry times on failure: [3], Retry timeout: [10 min], Periodically options: [Enabled: True, Period: 4 hour(s), ScheduleString: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, HourlyOffset: 25]","7","ReFS-PerVM","Increment","Monthly","Saturday","True","False","Saturday" 4 | "SQLLogTest","Backup",,"Start time: [5/28/2020 22:00:00], Latest run time: [5/28/2020 18:50:43], Timeout for backup completion: [180min], Next run time: [], Retry times on failure: [3], Retry timeout: [10 min], Daily options: [Enabled: True, DayNumberInMonth: Everyday, Days: Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]","42","ReFS-PerVM","Increment","Daily","Saturday","True","False","Saturday" 5 | "Backup Copy Job 1","BackupSync","12/13/2019 11:03:43","Start time: [6/24/2019 11:28:39], Latest run time: [12/16/2019 00:00:05], Timeout for backup completion: [180min], Next run time: [12/16/2019 00:00:06], Retry times on failure: [3], Retry timeout: [10 min], Continuous options: [Enabled: True, ScheduleString: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]","7","NTFS-Bulk","Increment","Daily","Saturday","True","False","Saturday" 6 | "AUSVCENTER-TagTest","Backup","5/11/2020 21:06:27","Start time: [5/12/2020 13:05:00], Latest run time: [5/12/2020 09:52:55], Timeout for backup completion: [180min], Next run time: [], Retry times on failure: [3], Retry timeout: [10 min], Periodically options: [Enabled: True, Period: 4 hour(s), ScheduleString: 1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,01,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,01,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,01,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,01,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,01,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,01,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0, HourlyOffset: 5]","4","ReFS-PerVM","Increment","Daily","Saturday","True","False","Monday Tuesday Wednesday Thursday Friday Saturday Sunday" 7 | "AUSVCENTER-NoTag","Backup","5/11/2020 21:06:24","Start time: [5/31/2020 16:05:00], Latest run time: [5/31/2020 14:25:51], Timeout for backup completion: [180min], Next run time: [], Retry times on failure: [3], Retry timeout: [10 min], Periodically options: [Enabled: True, Period: 4 hour(s), ScheduleString: 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,10,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,10,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,10,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,10,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,10,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,10,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1, HourlyOffset: 5]","4","ReFS-PerVM","Increment","Daily","Saturday","True","False","Monday Tuesday Wednesday Thursday Friday Saturday Sunday" 8 | "vCenterServers","Backup","5/11/2020 21:06:35","Start time: [5/12/2020 19:00:00], Latest run time: [5/12/2020 08:14:55], Timeout for backup completion: [180min], Next run time: [], Retry times on failure: [3], Retry timeout: [10 min], Daily options: [Enabled: True, DayNumberInMonth: Everyday, Days: Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]","5","ReFS-PerVM","Increment","Daily","Saturday","True","False","Saturday" 9 | "HyperV","Backup",,"Start time: [9/19/2019 22:00:00], Latest run time: [9/19/2019 13:09:19], Timeout for backup completion: [180min], Next run time: [], Retry times on failure: [3], Retry timeout: [10 min], Daily options: [Enabled: True, DayNumberInMonth: Everyday, Days: Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]","14","NTFS-Bulk","Increment","Daily","Saturday","True","False","Saturday" 10 | "SOBRBackupTest","Backup",,"Start time: [5/31/2020 22:00:00], Latest run time: [5/31/2020 19:20:55], Timeout for backup completion: [180min], Next run time: [], Retry times on failure: [3], Retry timeout: [10 min], Daily options: [Enabled: True, DayNumberInMonth: Everyday, Days: Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]","7","SOBR_Test","Increment","Daily","Saturday","False","False","Saturday" 11 | -------------------------------------------------------------------------------- /SampleOutput/Session1/ConfigReports/ausveeambr_Proxies.csv: -------------------------------------------------------------------------------- 1 | "Id","Name","Description","Info","HostId","Host","Type","IsDisabled","Options","MaxTasksCount","ChosenVm","ChassisType" 2 | "a5253b98-eac0-4b76-a3cc-4d0780c5c631","ausveeampxy01.lab.fullstackgeek.net","Austin Virtual Proxy #1","Veeam.Backup.Model.CBackupProxyInfo","c251e39e-3b10-4a71-94de-ddfdfc7e6e9c","Veeam.Backup.Core.Common.CHost","Vi","False","Veeam.Backup.Model.CDomViProxyOptions","4",,"ViVirtual" 3 | "18b661c1-d9dc-4233-90a0-7e7b10dc2d09","VMware Backup Proxy","Created by Veeam Backup & Replication","Veeam.Backup.Model.CBackupProxyInfo","6745a759-2205-4cd2-b172-8ec8f7e60ef8","Veeam.Backup.Core.Common.CHost","Vi","True","Veeam.Backup.Model.CDomViProxyOptions","2",,"ViVirtual" 4 | "38060fcc-91db-4e8e-9c1f-91684f420679","ausveeampxy02.lab.fullstackgeek.net","Austin Virtual Proxy #2","Veeam.Backup.Model.CBackupProxyInfo","90e93595-590b-4651-8081-d3588cee8b85","Veeam.Backup.Core.Common.CHost","Vi","False","Veeam.Backup.Model.CDomViProxyOptions","4",,"ViVirtual" 5 | -------------------------------------------------------------------------------- /SampleOutput/Session1/ConfigReports/ausveeambr_Repositories.csv: -------------------------------------------------------------------------------- 1 | "Info","Host","Id","Name","HostId","MountHostId","Description","CreationTime","Path","FullPath","FriendlyPath","ShareCredsId","Type","Status","IsUnavailable","Group","UseNfsOnMountHost","VersionOfCreation","Tag","IsTemporary","TypeDisplay","IsRotatedDriveRepository","EndPointCryptoKeyId","Options","HasBackupChainLengthLimitation","IsSanSnapshotOnly","IsDedupStorage","SplitStoragesPerVm" 2 | "Veeam.Backup.Model.CBackupRepositoryInfo","Veeam.Backup.Core.Common.CHost","88788f9e-d8f5-4eb4-bc4f-9b3f5403bcec","Default Backup Repository","6745a759-2205-4cd2-b172-8ec8f7e60ef8","6745a759-2205-4cd2-b172-8ec8f7e60ef8","Created by Veeam Backup",,"C:\Backup","C:|Backup","C:\Backup","00000000-0000-0000-0000-000000000000","WinLocal","Ordinal","False","BackupRepository","True","9.0.0.0","88788F9ED8F54EB4BC4F9B3F5403BCEC","False","Windows","False","00000000-0000-0000-0000-000000000000","Veeam.Backup.Model.CDomBackupRepositoryOptions","False","False","False","False" 3 | "Veeam.Backup.Model.CBackupRepositoryInfo","Veeam.Backup.Core.Common.CHost","9f5a1e48-d95d-4654-98d8-9719e23334d3","NTFS-Bulk","90e93595-590b-4651-8081-d3588cee8b85","90e93595-590b-4651-8081-d3588cee8b85","NTFS on ausveeampxy02 - D:\Backups\",,"D:\Backups","D:|Backups","D:\Backups","00000000-0000-0000-0000-000000000000","WinLocal","Ordinal","False","BackupRepository","True","9.5.0.1536","9F5A1E48D95D465498D89719E23334D3","False","Windows","False","00000000-0000-0000-0000-000000000000","Veeam.Backup.Model.CDomBackupRepositoryOptions","False","False","False","False" 4 | "Veeam.Backup.Model.CBackupRepositoryInfo","Veeam.Backup.Core.Common.CHost","3829e566-800c-49f6-931b-3d038040c8d4","ReFS-PerVM","c251e39e-3b10-4a71-94de-ddfdfc7e6e9c","c251e39e-3b10-4a71-94de-ddfdfc7e6e9c","ReFS on ausveeampxy01 - D:\Backups\",,"D:\Backups","D:|Backups","D:\Backups","00000000-0000-0000-0000-000000000000","WinLocal","Ordinal","False","BackupRepository","True","9.5.0.1922","3829E566800C49F6931B3D038040C8D4","False","Windows","False","00000000-0000-0000-0000-000000000000","Veeam.Backup.Model.CDomBackupRepositoryOptions","False","False","False","True" 5 | "Veeam.Backup.Model.CBackupRepositoryInfo","Veeam.Backup.Core.Common.CHost","0656972f-230d-4c1a-be88-70b4aa6e7271","DataDomain","00000000-0000-0000-0000-000000000000","90e93595-590b-4651-8081-d3588cee8b85","Virtual DataDomain",,"ddboost://192.168.20.47:StorageUnit1@/","ddboost://192.168.20.47:StorageUnit1@/","ddboost://192.168.20.47:StorageUnit1@/","00000000-0000-0000-0000-000000000000","DDBoost","Ordinal","False","BackupRepository","True","9.5.4.2866","0656972F230D4C1ABE8870B4AA6E7271","False","Dell EMC Data Domain","False","00000000-0000-0000-0000-000000000000","Veeam.Backup.Model.CDomBackupRepositoryOptions","True","False","True","True" 6 | "Veeam.Backup.Model.CBackupRepositoryInfo","Veeam.Backup.Core.Common.CHost","22d66f3d-a671-4992-9284-1b400d0c98b7","BCJ-PerVM","90e93595-590b-4651-8081-d3588cee8b85","90e93595-590b-4651-8081-d3588cee8b85","NTFS on ausveeampxy02 - D:\BCJ",,"D:\BCJ","D:|BCJ","D:\BCJ","00000000-0000-0000-0000-000000000000","WinLocal","Ordinal","False","BackupRepository","True","9.5.4.2866","22D66F3DA671499292841B400D0C98B7","False","Windows","False","00000000-0000-0000-0000-000000000000","Veeam.Backup.Model.CDomBackupRepositoryOptions","False","False","False","True" 7 | "Veeam.Backup.Model.CBackupRepositoryInfo","Veeam.Backup.Core.Common.CHost","de79845e-bc51-4de9-90e0-fa6fd05fa5c9","iSCSI","c251e39e-3b10-4a71-94de-ddfdfc7e6e9c","c251e39e-3b10-4a71-94de-ddfdfc7e6e9c","iSCSI Volume on PNTLSLAB-BACKUP",,"I:\Backups","I:|Backups","I:\Backups","00000000-0000-0000-0000-000000000000","WinLocal","Ordinal","False","BackupRepository","True","9.5.4.2866","DE79845EBC514DE990E0FA6FD05FA5C9","False","Windows","False","00000000-0000-0000-0000-000000000000","Veeam.Backup.Model.CDomBackupRepositoryOptions","False","False","False","True" 8 | -------------------------------------------------------------------------------- /SampleOutput/Session1/ConfigReports/ausveeambr_SOBRExtents.csv: -------------------------------------------------------------------------------- 1 | "Info","Host","Id","Name","HostId","MountHostId","Description","CreationTime","Path","FullPath","FriendlyPath","ShareCredsId","Type","Status","IsUnavailable","Group","UseNfsOnMountHost","VersionOfCreation","Tag","IsTemporary","TypeDisplay","IsRotatedDriveRepository","EndPointCryptoKeyId","Options","HasBackupChainLengthLimitation","IsSanSnapshotOnly","IsDedupStorage","SplitStoragesPerVm","SOBR_Name" 2 | "Veeam.Backup.Model.CBackupRepositoryInfo","Veeam.Backup.Core.Common.CHost","6e154dcb-348b-45f3-a8b9-3d6dd513de13","SOBR1","c251e39e-3b10-4a71-94de-ddfdfc7e6e9c","c251e39e-3b10-4a71-94de-ddfdfc7e6e9c","Created by FSGLAB\svc_veeam_br at 4/24/2020 12:45 PM.",,"D:\Backups1","D:|Backups1","D:\Backups1","00000000-0000-0000-0000-000000000000","WinLocal","Ordinal","False","BackupRepository","True","10.0.0.4442","6E154DCB348B45F3A8B93D6DD513DE13","False","Windows","False","00000000-0000-0000-0000-000000000000","Veeam.Backup.Model.CDomBackupRepositoryOptions","False","False","False","False","SOBR_Test" 3 | "Veeam.Backup.Model.CBackupRepositoryInfo","Veeam.Backup.Core.Common.CHost","9f284e55-2024-4fb9-a62e-2845972e2d2c","SOBR2","90e93595-590b-4651-8081-d3588cee8b85","90e93595-590b-4651-8081-d3588cee8b85","Created by FSGLAB\svc_veeam_br at 4/24/2020 12:46 PM.",,"D:\Backups1","D:|Backups1","D:\Backups1","00000000-0000-0000-0000-000000000000","WinLocal","Ordinal","False","BackupRepository","True","10.0.0.4442","9F284E5520244FB9A62E2845972E2D2C","False","Windows","False","00000000-0000-0000-0000-000000000000","Veeam.Backup.Model.CDomBackupRepositoryOptions","False","False","False","False","SOBR_Test" 4 | -------------------------------------------------------------------------------- /SampleOutput/Session1/ConfigReports/ausveeambr_SOBRs.csv: -------------------------------------------------------------------------------- 1 | "PolicyType","Extent","UsePerVMBackupFiles","PerformFullWhenExtentOffline","EnableCapacityTier","OperationalRestorePeriod","OverridePolicyEnabled","OverrideSpaceThreshold","OffloadWindowOptions","CapacityExtent","EncryptionEnabled","EncryptionKey","CapacityTierCopyPolicyEnabled","CapacityTierMovePolicyEnabled","Id","Name","Description" 2 | "DataLocality","Veeam.Backup.PowerShell.Infos.VBRRepositoryExtent[]","True","False","False","14","False","90","1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",,"False",,"False","True","6f9733bf-a4cc-4338-93cc-eb5461dea344","SOBR_Test","Created by FSGLAB\svc_veeam_br at 4/24/2020 1:01 PM." 3 | -------------------------------------------------------------------------------- /SampleOutput/Session1/ConfigReports/ausveeambr_Servers.csv: -------------------------------------------------------------------------------- 1 | "Info","ParentId","Id","Name","Reference","Description","IsUnavailable","Type","ApiVersion","PhysHostId","ProxyServicesCreds" 2 | "ausvcenter.lab.fullstackgeek.net (VMware vCenter Server)","00000000-0000-0000-0000-000000000000","fdd958d1-0a04-410a-964f-0f8f9c13a5fe","ausvcenter.lab.fullstackgeek.net","","Austin vCenter Server","False","VC","V672","ec1ad47d-e38a-4390-95df-7b555a9a77f7", 3 | "nest-esxi2.lab.fullstackgeek.net (VMware ESXi Server)","fdd958d1-0a04-410a-964f-0f8f9c13a5fe","8d5d5b3b-7aa1-423e-b2d2-133e1da9d0ca","nest-esxi2.lab.fullstackgeek.net","host-22655","","False","ESXi","V67","060d6daf-ac7c-4e26-9878-e0c425099307", 4 | "\\192.168.50.9\LabMedia (SMB file share)","00000000-0000-0000-0000-000000000000","055d56fb-2b37-4032-b3b4-364140ea4578","\\192.168.50.9\LabMedia","","","False","CifsServer","Unknown","00000000-0000-0000-0000-000000000000","Veeam.Backup.Common.CCredentials" 5 | "esxi2.lab.fullstackgeek.net (VMware ESXi Server)","fdd958d1-0a04-410a-964f-0f8f9c13a5fe","3fcdad8a-5bb8-4e4b-abd2-3d484ca98714","esxi2.lab.fullstackgeek.net","host-34","","False","ESXi","V672","70cf28dc-855d-4bbd-a5f1-61ed767d01e5", 6 | "ausjump01.lab.fullstackgeek.net (Microsoft Windows Server)","00000000-0000-0000-0000-000000000000","cca8cb04-2bea-4a82-bc8a-5caa71094b99","ausjump01.lab.fullstackgeek.net","","File to Tape Test VM","False","Windows","Unknown","6cf90933-57a5-4f9e-a807-55216d1b6c48","Veeam.Backup.Common.CCredentials" 7 | "esxi2.fsglab.local (VMware ESXi Server)","5000abb5-f13d-4434-a48d-bec0763f68f3","51434bbf-3389-42ec-b0e4-675d852f305c","esxi2.fsglab.local","host-154","","False","ESXi","V672","70cf28dc-855d-4bbd-a5f1-61ed767d01e5", 8 | "esxi3.lab.fullstackgeek.net (VMware ESXi Server)","fdd958d1-0a04-410a-964f-0f8f9c13a5fe","796c8a1b-893e-4613-b332-7a4d93bcd700","esxi3.lab.fullstackgeek.net","host-22554","","False","ESXi","V672","8736fdd7-1a5d-4504-a047-9f5e54fd7f46", 9 | "This server (Microsoft Windows Server)","00000000-0000-0000-0000-000000000000","6745a759-2205-4cd2-b172-8ec8f7e60ef8","ausveeambr.lab.fullstackgeek.net","","Backup server","False","Local","Unknown","d7c4ff97-b99b-4d1f-884d-283b7b6b9ee3", 10 | "esxi3.fsglab.local (VMware ESXi Server)","5000abb5-f13d-4434-a48d-bec0763f68f3","2725ab9f-777b-4490-977c-a8dfc8d7537e","esxi3.fsglab.local","host-86","","False","ESXi","V672","8736fdd7-1a5d-4504-a047-9f5e54fd7f46", 11 | "esxi1.fsglab.local (VMware ESXi Server)","5000abb5-f13d-4434-a48d-bec0763f68f3","f38ab6c2-1fa7-44f7-bbf2-b6c8f7cf5d57","esxi1.fsglab.local","host-32","","False","ESXi","V672","959f14c3-b237-42d4-81f3-12c736786dc1", 12 | "ausvcenter.fsglab.local (VMware vCenter Server)","00000000-0000-0000-0000-000000000000","5000abb5-f13d-4434-a48d-bec0763f68f3","ausvcenter.fsglab.local","","Austin vCenter","False","VC","V672","22edcd4f-ff8b-47b2-b1af-93dcaac69898", 13 | "ausveeampxy02.lab.fullstackgeek.net (Microsoft Windows Server)","00000000-0000-0000-0000-000000000000","90e93595-590b-4651-8081-d3588cee8b85","ausveeampxy02.lab.fullstackgeek.net","","Austin Proxy #2","False","Windows","Unknown","bfc7b0b9-358e-42b3-bf6c-8d693df86465","Veeam.Backup.Common.CCredentials" 14 | "ausveeampxy01.lab.fullstackgeek.net (Microsoft Windows Server)","00000000-0000-0000-0000-000000000000","c251e39e-3b10-4a71-94de-ddfdfc7e6e9c","ausveeampxy01.lab.fullstackgeek.net","","Austin Proxy #1","False","Windows","Unknown","df9e4963-1d19-44fb-973a-73cd51fcf318","Veeam.Backup.Common.CCredentials" 15 | "hyperv.lab.fullstackgeek.net (Microsoft Hyper-V Server)","00000000-0000-0000-0000-000000000000","ce4c7031-12d7-41c8-8ccd-de43c29dc6cf","hyperv.lab.fullstackgeek.net",,"Standalong Hyper-V nested host","True","HvServer","Unknown","2e7068cb-145f-4d3a-8b85-8fbf99e72e9b","Veeam.Backup.Common.CCredentials" 16 | "ausubuntufile.lab.fullstackgeek.net (Linux Host)","00000000-0000-0000-0000-000000000000","49406aa2-a443-4db2-aefe-f40c108492fd","ausubuntufile.lab.fullstackgeek.net","","ausubuntufile.lab.fullstackgeek.net","True","Linux","Unknown","a756f27f-0ce3-4fea-959c-f8b618487e50", 17 | -------------------------------------------------------------------------------- /SampleOutput/Session1/JobStatusMethods.csv: -------------------------------------------------------------------------------- 1 | "Name","JobType","LastResult","LastState","ObjectsCount","Repository","InWindow","WANAcc" 2 | "zPowerShellDemoJob","VMware Backup","None","Stopped","0","ReFS-PerVM","True","False" 3 | "HomePCs Policy","Windows Agent Policy","Failed","Stopped","1","NTFS-Bulk","True","False" 4 | "vcenter_repl","VMware Replication","Success","Stopped","1","ReFS-PerVM","True","False" 5 | "Replication Test_clone1","VMware Replication","Failed","Stopped","6","ReFS-PerVM","True","False" 6 | "DomainControllers","VMware Backup","Success","Stopped","2","ReFS-PerVM","True","False" 7 | "SQLLogTest","VMware Backup","Failed","Stopped","1","ReFS-PerVM","True","False" 8 | "Backup Copy Job 1","VMware Backup Copy","Success","Stopped","0","NTFS-Bulk","True","False" 9 | "AUSVCENTER-TagTest","VMware Backup","Success","Stopped","1","ReFS-PerVM","True","False" 10 | "AUSVCENTER-NoTag","VMware Backup","Success","Stopped","5","ReFS-PerVM","True","False" 11 | "vCenterServers","VMware Backup","Success","Stopped","1","ReFS-PerVM","True","False" 12 | "HyperV","Hyper-V Backup","Success","Stopped","1","NTFS-Bulk","True","False" 13 | "AgentExclude","Windows Agent Backup","None","Stopped","1","ReFS-PerVM","True","False" 14 | "Workstation Agent Backup Policy","Windows Agent Policy","Failed","Stopped","1","NTFS-Bulk","True","False" 15 | "SOBRBackupTest","VMware Backup","Success","Stopped","3","SOBR_Test","True","False" 16 | -------------------------------------------------------------------------------- /SampleOutput/Session1/JobStatusProperties.csv: -------------------------------------------------------------------------------- 1 | "Name","JobType","Running","RequiresRetry","Scheduled","LatestRunLocal" 2 | "zPowerShellDemoJob","VMware Backup","False","False","True","1/1/0001 00:00:00" 3 | "HomePCs Policy","Windows Agent Policy","False","False","False","1/1/0001 00:00:00" 4 | "vcenter_repl","VMware Replication","False","False","True","10/3/2019 21:36:50" 5 | "Replication Test_clone1","VMware Replication","False","False","False","12/16/2019 05:00:09" 6 | "DomainControllers","VMware Backup","False","False","True","6/2/2020 12:25:16" 7 | "SQLLogTest","VMware Backup","False","False","True","2/7/2020 17:16:27" 8 | "Backup Copy Job 1","VMware Backup Copy","False","False","False","12/16/2019 06:00:05" 9 | "AUSVCENTER-TagTest","VMware Backup","False","False","True","6/2/2020 13:05:01" 10 | "AUSVCENTER-NoTag","VMware Backup","False","False","True","6/2/2020 12:05:02" 11 | "vCenterServers","VMware Backup","False","False","True","6/1/2020 19:00:13" 12 | "HyperV","Hyper-V Backup","False","False","True","9/19/2019 18:09:19" 13 | "AgentExclude","Windows Agent Backup","False","False","False","1/1/0001 00:00:00" 14 | "Workstation Agent Backup Policy","Windows Agent Policy","False","False","False","1/1/0001 00:00:00" 15 | "SOBRBackupTest","VMware Backup","False","False","True","6/1/2020 22:00:16" 16 | -------------------------------------------------------------------------------- /SampleOutput/Session1/VM_DiskFilterDetails.csv: -------------------------------------------------------------------------------- 1 | "BackupJob","VMName","Location","DiskMode","SpecificDisks" 2 | "DomainControllers","ausdc01","ReFS-PerVM","AllDisks","All" 3 | "DomainControllers","ausdc02","ReFS-PerVM","AllDisks","All" 4 | "SQLLogTest","aussql2k14","ReFS-PerVM","AllDisks","All" 5 | "AUSVCENTER-TagTest","VeeamTagTest","ReFS-PerVM","AllDisks","All" 6 | "AUSVCENTER-NoTag","ausveeambem","ReFS-PerVM","SystemDisks","SCSI (0:0);SATA (0:0);IDE (0:0);NVMe (0:0)" 7 | "AUSVCENTER-NoTag","ausveeambr","ReFS-PerVM","AllDisks","All" 8 | "AUSVCENTER-NoTag","ausveeamone","ReFS-PerVM","SelectedDisks","SCSI (0:0);SCSI (0:2);SCSI (0:4)" 9 | "AUSVCENTER-NoTag","ausdev01","ReFS-PerVM","AllDisks","All" 10 | "AUSVCENTER-NoTag","ausjump01","ReFS-PerVM","AllDisks","All" 11 | "vCenterServers","ausvcenter","ReFS-PerVM","AllDisks","All" 12 | "SOBRBackupTest","client",,"SystemDisks","SCSI (0:0);SATA (0:0);IDE (0:0);NVMe (0:0)" 13 | "SOBRBackupTest","DC",,"AllDisks","All" 14 | "SOBRBackupTest","member",,"SelectedDisks","SCSI (0:0);SCSI (0:1);SCSI (0:2)" 15 | -------------------------------------------------------------------------------- /SampleOutput/Session1/VeeamBackupSizeReport1.csv: -------------------------------------------------------------------------------- 1 | "BackupJob","VMName","Timestamp","BackupSize(GB)","BackupCost($)" 2 | "DomainControllers","ausdc02","6/1/2020 00:25:14","0.08","0.01" 3 | "DomainControllers","ausdc02","5/31/2020 16:25:19","0.09","0.01" 4 | "DomainControllers","ausdc02","5/31/2020 12:25:28","0.09","0.01" 5 | "DomainControllers","ausdc02","5/31/2020 20:25:16","0.08","0.01" 6 | "DomainControllers","ausdc02","6/2/2020 08:25:16","0.28","0.04" 7 | "DomainControllers","ausdc02","6/2/2020 00:25:19","0.08","0.01" 8 | "DomainControllers","ausdc02","5/31/2020 04:25:15","0.08","0.01" 9 | "DomainControllers","ausdc02","5/31/2020 00:25:13","0.08","0.01" 10 | "DomainControllers","ausdc02","5/30/2020 04:25:22","0.11","0.02" 11 | "DomainControllers","ausdc02","5/30/2020 16:25:31","0.08","0.01" 12 | "DomainControllers","ausdc02","6/1/2020 08:25:29","0.11","0.02" 13 | "DomainControllers","ausdc02","6/1/2020 12:25:17","0.08","0.01" 14 | "DomainControllers","ausdc02","5/30/2020 08:25:10","0.09","0.01" 15 | "DomainControllers","ausdc02","6/1/2020 04:25:31","0.09","0.01" 16 | "DomainControllers","ausdc02","5/30/2020 00:25:24","5.31","0.8" 17 | "DomainControllers","ausdc02","6/1/2020 20:25:27","0.07","0.01" 18 | "DomainControllers","ausdc02","5/30/2020 12:25:10","0.1","0.02" 19 | "DomainControllers","ausdc02","6/2/2020 04:25:15","0.07","0.01" 20 | "DomainControllers","ausdc02","5/31/2020 08:25:13","0.3","0.04" 21 | "DomainControllers","ausdc02","5/30/2020 20:25:32","0.08","0.01" 22 | "DomainControllers","ausdc02","6/2/2020 12:25:26","0.11","0.02" 23 | "DomainControllers","ausdc02","6/1/2020 16:25:23","0.08","0.01" 24 | "DomainControllers","ausdc01","5/31/2020 08:25:13","0.28","0.04" 25 | "DomainControllers","ausdc01","5/31/2020 16:25:19","0.08","0.01" 26 | "DomainControllers","ausdc01","5/30/2020 08:25:10","0.09","0.01" 27 | "DomainControllers","ausdc01","5/30/2020 04:25:22","0.1","0.02" 28 | "DomainControllers","ausdc01","6/2/2020 00:25:19","0.08","0.01" 29 | "DomainControllers","ausdc01","5/31/2020 00:25:13","0.07","0.01" 30 | "DomainControllers","ausdc01","6/1/2020 08:25:29","0.09","0.01" 31 | "DomainControllers","ausdc01","6/2/2020 08:25:16","0.28","0.04" 32 | "DomainControllers","ausdc01","5/30/2020 00:25:24","7.55","1.13" 33 | "DomainControllers","ausdc01","5/31/2020 04:25:15","0.1","0.02" 34 | "DomainControllers","ausdc01","6/2/2020 12:25:26","0.08","0.01" 35 | "DomainControllers","ausdc01","5/30/2020 20:25:32","0.07","0.01" 36 | "DomainControllers","ausdc01","5/30/2020 16:25:31","0.08","0.01" 37 | "DomainControllers","ausdc01","5/30/2020 12:25:10","0.08","0.01" 38 | "DomainControllers","ausdc01","6/1/2020 20:25:27","0.07","0.01" 39 | "DomainControllers","ausdc01","6/1/2020 04:25:31","0.1","0.02" 40 | "DomainControllers","ausdc01","6/2/2020 04:25:15","0.1","0.02" 41 | "DomainControllers","ausdc01","5/31/2020 20:25:16","0.07","0.01" 42 | "DomainControllers","ausdc01","6/1/2020 16:25:23","0.07","0.01" 43 | "DomainControllers","ausdc01","5/31/2020 12:25:28","0.09","0.01" 44 | "DomainControllers","ausdc01","6/1/2020 12:25:17","0.08","0.01" 45 | "DomainControllers","ausdc01","6/1/2020 00:25:14","0.07","0.01" 46 | "SQLLogTest","aussql2k14","3/27/2020 18:48:40","1.66","0.25" 47 | "SQLLogTest","aussql2k14","2/7/2020 17:18:26","0.21","0.03" 48 | "SQLLogTest","aussql2k14","3/27/2020 19:24:12","0.09","0.01" 49 | "SQLLogTest","aussql2k14","2/7/2020 15:43:10","0.18","0.03" 50 | "SQLLogTest","aussql2k14","2/7/2020 18:05:36","0.1","0.02" 51 | "SQLLogTest","aussql2k14","3/27/2020 19:02:09","0.71","0.11" 52 | "SQLLogTest","aussql2k14","2/7/2020 13:21:05","12.27","1.84" 53 | "SQLLogTest","aussql2k14","2/7/2020 18:13:44","0.1","0.02" 54 | "SQLLogTest","aussql2k14","2/7/2020 13:54:10","0.2","0.03" 55 | "SQLLogTest","aussql2k14","2/7/2020 18:18:40","0.09","0.01" 56 | "SQLLogTest","aussql2k14","4/6/2020 15:38:03","2.3","0.34" 57 | "SQLLogTest","aussql2k14","2/7/2020 17:54:14","0.13","0.02" 58 | "SQLLogTest","aussql2k14","2/28/2020 09:09:35","7.78","1.17" 59 | "SQLLogTest","aussql2k14","3/23/2020 15:35:20","4.6","0.69" 60 | "Backup Copy Job 1","0 VM(s)","12/13/2019 00:00:00","79.26","11.89" 61 | "Backup Copy Job 1","0 VM(s)","8/13/2019 00:00:00","151.86","22.78" 62 | "Backup Copy Job 1","0 VM(s)","12/14/2019 00:00:00","4.21","0.63" 63 | "Backup Copy Job 1","0 VM(s)","12/15/2019 00:00:00","7.67","1.15" 64 | "Backup Copy Job 1","0 VM(s)","12/16/2019 00:00:00","7.75","1.16" 65 | "AUSVCENTER-TagTest","ausveeambr","6/2/2020 05:05:16","0.59","0.09" 66 | "AUSVCENTER-TagTest","ausveeambr","6/2/2020 09:05:21","1.01","0.15" 67 | "AUSVCENTER-TagTest","ausveeambr","6/2/2020 01:05:24","29.84","4.48" 68 | "AUSVCENTER-TagTest","ausveeambr","6/2/2020 13:05:12","11.92","1.79" 69 | "AUSVCENTER-TagTest","ausdc01","6/2/2020 13:05:12","0.06","0.01" 70 | "AUSVCENTER-TagTest","ausdc01","6/2/2020 05:05:16","0.08","0.01" 71 | "AUSVCENTER-TagTest","ausdc01","6/2/2020 01:05:24","5.05","0.76" 72 | "AUSVCENTER-TagTest","ausdc01","6/2/2020 09:05:21","0.23","0.03" 73 | "AUSVCENTER-NoTag","ausdev01","6/2/2020 08:05:31","0.41","0.06" 74 | "AUSVCENTER-NoTag","ausdev01","6/2/2020 12:05:13","2.01","0.3" 75 | "AUSVCENTER-NoTag","ausdev01","6/1/2020 12:05:21","0.7","0.1" 76 | "AUSVCENTER-NoTag","ausdev01","6/2/2020 00:05:10","105.13","15.77" 77 | "AUSVCENTER-NoTag","ausdev01","6/2/2020 04:05:30","2.19","0.33" 78 | "AUSVCENTER-NoTag","ausdev01","6/1/2020 04:05:30","0.72","0.11" 79 | "AUSVCENTER-NoTag","ausdev01","6/1/2020 08:05:19","0.54","0.08" 80 | "AUSVCENTER-NoTag","ausdev01","6/1/2020 16:05:10","0.71","0.11" 81 | "AUSVCENTER-NoTag","ausdev01","6/1/2020 00:05:10","104.97","15.75" 82 | "AUSVCENTER-NoTag","ausdev01","6/1/2020 20:05:31","0.68","0.1" 83 | "AUSVCENTER-NoTag","ausveeamone","6/2/2020 04:05:30","0.02","0" 84 | "AUSVCENTER-NoTag","ausveeamone","6/1/2020 08:05:19","0.35","0.05" 85 | "AUSVCENTER-NoTag","ausveeamone","6/2/2020 00:05:10","15.16","2.27" 86 | "AUSVCENTER-NoTag","ausveeamone","6/1/2020 12:05:21","0.13","0.02" 87 | "AUSVCENTER-NoTag","ausveeamone","6/1/2020 16:05:10","0.17","0.03" 88 | "AUSVCENTER-NoTag","ausveeamone","6/2/2020 12:05:13","0.02","0" 89 | "AUSVCENTER-NoTag","ausveeamone","6/1/2020 20:05:31","0.16","0.02" 90 | "AUSVCENTER-NoTag","ausveeamone","6/1/2020 00:05:10","15.23","2.28" 91 | "AUSVCENTER-NoTag","ausveeamone","6/1/2020 04:05:30","0.18","0.03" 92 | "AUSVCENTER-NoTag","ausveeamone","6/2/2020 08:05:31","0.02","0" 93 | "AUSVCENTER-NoTag","ausveeambem","6/2/2020 04:05:30","0.23","0.03" 94 | "AUSVCENTER-NoTag","ausveeambem","6/2/2020 00:05:10","18.16","2.72" 95 | "AUSVCENTER-NoTag","ausveeambem","6/1/2020 16:05:10","0.33","0.05" 96 | "AUSVCENTER-NoTag","ausveeambem","6/1/2020 20:05:31","0.2","0.03" 97 | "AUSVCENTER-NoTag","ausveeambem","6/1/2020 08:05:19","0.34","0.05" 98 | "AUSVCENTER-NoTag","ausveeambem","6/1/2020 00:05:10","18.16","2.72" 99 | "AUSVCENTER-NoTag","ausveeambem","6/1/2020 04:05:30","0.2","0.03" 100 | "AUSVCENTER-NoTag","ausveeambem","6/2/2020 12:05:13","0.45","0.07" 101 | "AUSVCENTER-NoTag","ausveeambem","6/2/2020 08:05:31","0.29","0.04" 102 | "AUSVCENTER-NoTag","ausveeambem","6/1/2020 12:05:21","0.22","0.03" 103 | "AUSVCENTER-NoTag","ausveeambr","6/2/2020 04:05:30","0.63","0.09" 104 | "AUSVCENTER-NoTag","ausveeambr","6/1/2020 12:05:21","0.71","0.11" 105 | "AUSVCENTER-NoTag","ausveeambr","6/1/2020 20:05:31","0.61","0.09" 106 | "AUSVCENTER-NoTag","ausveeambr","6/1/2020 16:05:10","0.67","0.1" 107 | "AUSVCENTER-NoTag","ausveeambr","6/2/2020 08:05:31","1.03","0.15" 108 | "AUSVCENTER-NoTag","ausveeambr","6/1/2020 08:05:19","0.85","0.13" 109 | "AUSVCENTER-NoTag","ausveeambr","6/1/2020 04:05:30","0.72","0.11" 110 | "AUSVCENTER-NoTag","ausveeambr","6/2/2020 12:05:13","11.93","1.79" 111 | "AUSVCENTER-NoTag","ausveeambr","6/2/2020 00:05:10","31.19","4.68" 112 | "AUSVCENTER-NoTag","ausveeambr","6/1/2020 00:05:10","31.18","4.68" 113 | "AUSVCENTER-NoTag","ausjump01","6/1/2020 04:05:30","0.02","0" 114 | "AUSVCENTER-NoTag","ausjump01","6/1/2020 23:21:35","3.68","0.55" 115 | "AUSVCENTER-NoTag","ausjump01","6/2/2020 12:05:13","0.24","0.04" 116 | "AUSVCENTER-NoTag","ausjump01","6/2/2020 00:05:10","20.65","3.1" 117 | "AUSVCENTER-NoTag","ausjump01","6/1/2020 23:38:32","0.35","0.05" 118 | "AUSVCENTER-NoTag","ausjump01","6/1/2020 00:05:10","19.26","2.89" 119 | "AUSVCENTER-NoTag","ausjump01","6/1/2020 12:05:21","0.02","0" 120 | "AUSVCENTER-NoTag","ausjump01","6/2/2020 08:05:31","0.22","0.03" 121 | "AUSVCENTER-NoTag","ausjump01","6/1/2020 16:05:10","0.02","0" 122 | "AUSVCENTER-NoTag","ausjump01","6/1/2020 20:05:31","0.02","0" 123 | "AUSVCENTER-NoTag","ausjump01","6/2/2020 04:05:30","0.49","0.07" 124 | "AUSVCENTER-NoTag","ausjump01","6/1/2020 08:05:19","0.02","0" 125 | "vCenterServers","ausvcenter","5/27/2020 19:00:11","1.04","0.16" 126 | "vCenterServers","ausvcenter","5/24/2020 19:00:29","0.49","0.07" 127 | "vCenterServers","ausvcenter","5/29/2020 19:00:22","0.49","0.07" 128 | "vCenterServers","ausvcenter","5/30/2020 19:00:11","12.59","1.89" 129 | "vCenterServers","ausvcenter","5/23/2020 19:00:30","11.84","1.78" 130 | "vCenterServers","ausvcenter","5/28/2020 19:00:31","0.88","0.13" 131 | "vCenterServers","ausvcenter","6/1/2020 19:00:23","0.54","0.08" 132 | "vCenterServers","ausvcenter","5/31/2020 19:00:23","0.45","0.07" 133 | "vCenterServers","ausvcenter","5/25/2020 19:00:32","0.53","0.08" 134 | "SOBRBackupTest","DC","5/23/2020 22:00:18","6.21","0.93" 135 | "SOBRBackupTest","DC","5/31/2020 22:00:34","0.02","0" 136 | "SOBRBackupTest","DC","5/29/2020 22:00:19","0.02","0" 137 | "SOBRBackupTest","DC","5/25/2020 22:00:20","0.02","0" 138 | "SOBRBackupTest","DC","5/28/2020 22:00:12","0.02","0" 139 | "SOBRBackupTest","DC","6/1/2020 22:00:27","0.02","0" 140 | "SOBRBackupTest","DC","5/27/2020 22:00:26","0.02","0" 141 | "SOBRBackupTest","DC","5/30/2020 22:00:25","6.21","0.93" 142 | "SOBRBackupTest","DC","5/24/2020 22:00:16","0.02","0" 143 | "SOBRBackupTest","client","5/25/2020 22:00:20","0.02","0" 144 | "SOBRBackupTest","client","5/27/2020 22:00:26","0.02","0" 145 | "SOBRBackupTest","client","6/1/2020 22:00:27","0.02","0" 146 | "SOBRBackupTest","client","5/28/2020 22:00:12","0.02","0" 147 | "SOBRBackupTest","client","5/24/2020 22:00:16","0.02","0" 148 | "SOBRBackupTest","client","5/29/2020 22:00:19","0.02","0" 149 | "SOBRBackupTest","client","5/23/2020 22:00:18","7.44","1.12" 150 | "SOBRBackupTest","client","5/30/2020 22:00:25","7.44","1.12" 151 | "SOBRBackupTest","client","5/31/2020 22:00:34","0.02","0" 152 | "SOBRBackupTest","member","5/24/2020 22:00:16","0.02","0" 153 | "SOBRBackupTest","member","5/23/2020 22:00:18","6.8","1.02" 154 | "SOBRBackupTest","member","6/1/2020 22:00:27","0.02","0" 155 | "SOBRBackupTest","member","5/31/2020 22:00:34","0.02","0" 156 | "SOBRBackupTest","member","5/25/2020 22:00:20","0.02","0" 157 | "SOBRBackupTest","member","5/28/2020 22:00:12","0.02","0" 158 | "SOBRBackupTest","member","5/29/2020 22:00:19","0.02","0" 159 | "SOBRBackupTest","member","5/30/2020 22:00:25","6.8","1.02" 160 | "SOBRBackupTest","member","5/27/2020 22:00:26","0.02","0" 161 | -------------------------------------------------------------------------------- /SampleOutput/Session1/VeeamBackupSizeReport2.csv: -------------------------------------------------------------------------------- 1 | "BackupJob","VMName","Timestamp","BackupSize(GB)","BackupCost($)" 2 | "DomainControllers","ausdc02","6/1/2020 00:25:14","0.08","0.01" 3 | "DomainControllers","ausdc02","5/31/2020 16:25:19","0.09","0.01" 4 | "DomainControllers","ausdc02","5/31/2020 12:25:28","0.09","0.01" 5 | "DomainControllers","ausdc02","5/31/2020 20:25:16","0.08","0.01" 6 | "DomainControllers","ausdc02","6/2/2020 08:25:16","0.28","0.04" 7 | "DomainControllers","ausdc02","6/2/2020 00:25:19","0.08","0.01" 8 | "DomainControllers","ausdc02","5/31/2020 04:25:15","0.08","0.01" 9 | "DomainControllers","ausdc02","5/31/2020 00:25:13","0.08","0.01" 10 | "DomainControllers","ausdc02","5/30/2020 04:25:22","0.11","0.02" 11 | "DomainControllers","ausdc02","5/30/2020 16:25:31","0.08","0.01" 12 | "DomainControllers","ausdc02","6/1/2020 08:25:29","0.11","0.02" 13 | "DomainControllers","ausdc02","6/1/2020 12:25:17","0.08","0.01" 14 | "DomainControllers","ausdc02","5/30/2020 08:25:10","0.09","0.01" 15 | "DomainControllers","ausdc02","6/1/2020 04:25:31","0.09","0.01" 16 | "DomainControllers","ausdc02","5/30/2020 00:25:24","5.31","0.8" 17 | "DomainControllers","ausdc02","6/1/2020 20:25:27","0.07","0.01" 18 | "DomainControllers","ausdc02","5/30/2020 12:25:10","0.1","0.02" 19 | "DomainControllers","ausdc02","6/2/2020 04:25:15","0.07","0.01" 20 | "DomainControllers","ausdc02","5/31/2020 08:25:13","0.3","0.04" 21 | "DomainControllers","ausdc02","5/30/2020 20:25:32","0.08","0.01" 22 | "DomainControllers","ausdc02","6/2/2020 12:25:26","0.11","0.02" 23 | "DomainControllers","ausdc02","6/1/2020 16:25:23","0.08","0.01" 24 | "DomainControllers","ausdc01","5/31/2020 08:25:13","0.28","0.04" 25 | "DomainControllers","ausdc01","5/31/2020 16:25:19","0.08","0.01" 26 | "DomainControllers","ausdc01","5/30/2020 08:25:10","0.09","0.01" 27 | "DomainControllers","ausdc01","5/30/2020 04:25:22","0.1","0.02" 28 | "DomainControllers","ausdc01","6/2/2020 00:25:19","0.08","0.01" 29 | "DomainControllers","ausdc01","5/31/2020 00:25:13","0.07","0.01" 30 | "DomainControllers","ausdc01","6/1/2020 08:25:29","0.09","0.01" 31 | "DomainControllers","ausdc01","6/2/2020 08:25:16","0.28","0.04" 32 | "DomainControllers","ausdc01","5/30/2020 00:25:24","7.55","1.13" 33 | "DomainControllers","ausdc01","5/31/2020 04:25:15","0.1","0.02" 34 | "DomainControllers","ausdc01","6/2/2020 12:25:26","0.08","0.01" 35 | "DomainControllers","ausdc01","5/30/2020 20:25:32","0.07","0.01" 36 | "DomainControllers","ausdc01","5/30/2020 16:25:31","0.08","0.01" 37 | "DomainControllers","ausdc01","5/30/2020 12:25:10","0.08","0.01" 38 | "DomainControllers","ausdc01","6/1/2020 20:25:27","0.07","0.01" 39 | "DomainControllers","ausdc01","6/1/2020 04:25:31","0.1","0.02" 40 | "DomainControllers","ausdc01","6/2/2020 04:25:15","0.1","0.02" 41 | "DomainControllers","ausdc01","5/31/2020 20:25:16","0.07","0.01" 42 | "DomainControllers","ausdc01","6/1/2020 16:25:23","0.07","0.01" 43 | "DomainControllers","ausdc01","5/31/2020 12:25:28","0.09","0.01" 44 | "DomainControllers","ausdc01","6/1/2020 12:25:17","0.08","0.01" 45 | "DomainControllers","ausdc01","6/1/2020 00:25:14","0.07","0.01" 46 | "SQLLogTest","aussql2k14","3/27/2020 18:48:40","1.66","0.25" 47 | "SQLLogTest","aussql2k14","2/7/2020 17:18:26","0.21","0.03" 48 | "SQLLogTest","aussql2k14","3/27/2020 19:24:12","0.09","0.01" 49 | "SQLLogTest","aussql2k14","2/7/2020 15:43:10","0.18","0.03" 50 | "SQLLogTest","aussql2k14","2/7/2020 18:05:36","0.1","0.02" 51 | "SQLLogTest","aussql2k14","3/27/2020 19:02:09","0.71","0.11" 52 | "SQLLogTest","aussql2k14","2/7/2020 13:21:05","12.27","1.84" 53 | "SQLLogTest","aussql2k14","2/7/2020 18:13:44","0.1","0.02" 54 | "SQLLogTest","aussql2k14","2/7/2020 13:54:10","0.2","0.03" 55 | "SQLLogTest","aussql2k14","2/7/2020 18:18:40","0.09","0.01" 56 | "SQLLogTest","aussql2k14","4/6/2020 15:38:03","2.3","0.34" 57 | "SQLLogTest","aussql2k14","2/7/2020 17:54:14","0.13","0.02" 58 | "SQLLogTest","aussql2k14","2/28/2020 09:09:35","7.78","1.17" 59 | "SQLLogTest","aussql2k14","3/23/2020 15:35:20","4.6","0.69" 60 | "Backup Copy Job 1","0 VM(s)","12/13/2019 00:00:00","79.26","11.89" 61 | "Backup Copy Job 1","0 VM(s)","8/13/2019 00:00:00","151.86","22.78" 62 | "Backup Copy Job 1","0 VM(s)","12/14/2019 00:00:00","4.21","0.63" 63 | "Backup Copy Job 1","0 VM(s)","12/15/2019 00:00:00","7.67","1.15" 64 | "Backup Copy Job 1","0 VM(s)","12/16/2019 00:00:00","7.75","1.16" 65 | "AUSVCENTER-TagTest","ausveeambr","6/2/2020 05:05:16","0.59","0.09" 66 | "AUSVCENTER-TagTest","ausveeambr","6/2/2020 09:05:21","1.01","0.15" 67 | "AUSVCENTER-TagTest","ausveeambr","6/2/2020 01:05:24","29.84","4.48" 68 | "AUSVCENTER-TagTest","ausveeambr","6/2/2020 13:05:12","11.92","1.79" 69 | "AUSVCENTER-TagTest","ausdc01","6/2/2020 13:05:12","0.06","0.01" 70 | "AUSVCENTER-TagTest","ausdc01","6/2/2020 05:05:16","0.08","0.01" 71 | "AUSVCENTER-TagTest","ausdc01","6/2/2020 01:05:24","5.05","0.76" 72 | "AUSVCENTER-TagTest","ausdc01","6/2/2020 09:05:21","0.23","0.03" 73 | "AUSVCENTER-NoTag","ausdev01","6/2/2020 08:05:31","0.41","0.06" 74 | "AUSVCENTER-NoTag","ausdev01","6/2/2020 12:05:13","2.01","0.3" 75 | "AUSVCENTER-NoTag","ausdev01","6/1/2020 12:05:21","0.7","0.1" 76 | "AUSVCENTER-NoTag","ausdev01","6/2/2020 00:05:10","105.13","15.77" 77 | "AUSVCENTER-NoTag","ausdev01","6/2/2020 04:05:30","2.19","0.33" 78 | "AUSVCENTER-NoTag","ausdev01","6/1/2020 04:05:30","0.72","0.11" 79 | "AUSVCENTER-NoTag","ausdev01","6/1/2020 08:05:19","0.54","0.08" 80 | "AUSVCENTER-NoTag","ausdev01","6/1/2020 16:05:10","0.71","0.11" 81 | "AUSVCENTER-NoTag","ausdev01","6/1/2020 00:05:10","104.97","15.75" 82 | "AUSVCENTER-NoTag","ausdev01","6/1/2020 20:05:31","0.68","0.1" 83 | "AUSVCENTER-NoTag","ausveeamone","6/2/2020 04:05:30","0.02","0" 84 | "AUSVCENTER-NoTag","ausveeamone","6/1/2020 08:05:19","0.35","0.05" 85 | "AUSVCENTER-NoTag","ausveeamone","6/2/2020 00:05:10","15.16","2.27" 86 | "AUSVCENTER-NoTag","ausveeamone","6/1/2020 12:05:21","0.13","0.02" 87 | "AUSVCENTER-NoTag","ausveeamone","6/1/2020 16:05:10","0.17","0.03" 88 | "AUSVCENTER-NoTag","ausveeamone","6/2/2020 12:05:13","0.02","0" 89 | "AUSVCENTER-NoTag","ausveeamone","6/1/2020 20:05:31","0.16","0.02" 90 | "AUSVCENTER-NoTag","ausveeamone","6/1/2020 00:05:10","15.23","2.28" 91 | "AUSVCENTER-NoTag","ausveeamone","6/1/2020 04:05:30","0.18","0.03" 92 | "AUSVCENTER-NoTag","ausveeamone","6/2/2020 08:05:31","0.02","0" 93 | "AUSVCENTER-NoTag","ausveeambem","6/2/2020 04:05:30","0.23","0.03" 94 | "AUSVCENTER-NoTag","ausveeambem","6/2/2020 00:05:10","18.16","2.72" 95 | "AUSVCENTER-NoTag","ausveeambem","6/1/2020 16:05:10","0.33","0.05" 96 | "AUSVCENTER-NoTag","ausveeambem","6/1/2020 20:05:31","0.2","0.03" 97 | "AUSVCENTER-NoTag","ausveeambem","6/1/2020 08:05:19","0.34","0.05" 98 | "AUSVCENTER-NoTag","ausveeambem","6/1/2020 00:05:10","18.16","2.72" 99 | "AUSVCENTER-NoTag","ausveeambem","6/1/2020 04:05:30","0.2","0.03" 100 | "AUSVCENTER-NoTag","ausveeambem","6/2/2020 12:05:13","0.45","0.07" 101 | "AUSVCENTER-NoTag","ausveeambem","6/2/2020 08:05:31","0.29","0.04" 102 | "AUSVCENTER-NoTag","ausveeambem","6/1/2020 12:05:21","0.22","0.03" 103 | "AUSVCENTER-NoTag","ausveeambr","6/2/2020 04:05:30","0.63","0.09" 104 | "AUSVCENTER-NoTag","ausveeambr","6/1/2020 12:05:21","0.71","0.11" 105 | "AUSVCENTER-NoTag","ausveeambr","6/1/2020 20:05:31","0.61","0.09" 106 | "AUSVCENTER-NoTag","ausveeambr","6/1/2020 16:05:10","0.67","0.1" 107 | "AUSVCENTER-NoTag","ausveeambr","6/2/2020 08:05:31","1.03","0.15" 108 | "AUSVCENTER-NoTag","ausveeambr","6/1/2020 08:05:19","0.85","0.13" 109 | "AUSVCENTER-NoTag","ausveeambr","6/1/2020 04:05:30","0.72","0.11" 110 | "AUSVCENTER-NoTag","ausveeambr","6/2/2020 12:05:13","11.93","1.79" 111 | "AUSVCENTER-NoTag","ausveeambr","6/2/2020 00:05:10","31.19","4.68" 112 | "AUSVCENTER-NoTag","ausveeambr","6/1/2020 00:05:10","31.18","4.68" 113 | "AUSVCENTER-NoTag","ausjump01","6/1/2020 04:05:30","0.02","0" 114 | "AUSVCENTER-NoTag","ausjump01","6/1/2020 23:21:35","3.68","0.55" 115 | "AUSVCENTER-NoTag","ausjump01","6/2/2020 12:05:13","0.24","0.04" 116 | "AUSVCENTER-NoTag","ausjump01","6/2/2020 00:05:10","20.65","3.1" 117 | "AUSVCENTER-NoTag","ausjump01","6/1/2020 23:38:32","0.35","0.05" 118 | "AUSVCENTER-NoTag","ausjump01","6/1/2020 00:05:10","19.26","2.89" 119 | "AUSVCENTER-NoTag","ausjump01","6/1/2020 12:05:21","0.02","0" 120 | "AUSVCENTER-NoTag","ausjump01","6/2/2020 08:05:31","0.22","0.03" 121 | "AUSVCENTER-NoTag","ausjump01","6/1/2020 16:05:10","0.02","0" 122 | "AUSVCENTER-NoTag","ausjump01","6/1/2020 20:05:31","0.02","0" 123 | "AUSVCENTER-NoTag","ausjump01","6/2/2020 04:05:30","0.49","0.07" 124 | "AUSVCENTER-NoTag","ausjump01","6/1/2020 08:05:19","0.02","0" 125 | "vCenterServers","ausvcenter","5/27/2020 19:00:11","1.04","0.16" 126 | "vCenterServers","ausvcenter","5/24/2020 19:00:29","0.49","0.07" 127 | "vCenterServers","ausvcenter","5/29/2020 19:00:22","0.49","0.07" 128 | "vCenterServers","ausvcenter","5/30/2020 19:00:11","12.59","1.89" 129 | "vCenterServers","ausvcenter","5/23/2020 19:00:30","11.84","1.78" 130 | "vCenterServers","ausvcenter","5/28/2020 19:00:31","0.88","0.13" 131 | "vCenterServers","ausvcenter","6/1/2020 19:00:23","0.54","0.08" 132 | "vCenterServers","ausvcenter","5/31/2020 19:00:23","0.45","0.07" 133 | "vCenterServers","ausvcenter","5/25/2020 19:00:32","0.53","0.08" 134 | "SOBRBackupTest","DC","5/23/2020 22:00:18","6.21","0.93" 135 | "SOBRBackupTest","DC","5/31/2020 22:00:34","0.02","0" 136 | "SOBRBackupTest","DC","5/29/2020 22:00:19","0.02","0" 137 | "SOBRBackupTest","DC","5/25/2020 22:00:20","0.02","0" 138 | "SOBRBackupTest","DC","5/28/2020 22:00:12","0.02","0" 139 | "SOBRBackupTest","DC","6/1/2020 22:00:27","0.02","0" 140 | "SOBRBackupTest","DC","5/27/2020 22:00:26","0.02","0" 141 | "SOBRBackupTest","DC","5/30/2020 22:00:25","6.21","0.93" 142 | "SOBRBackupTest","DC","5/24/2020 22:00:16","0.02","0" 143 | "SOBRBackupTest","client","5/25/2020 22:00:20","0.02","0" 144 | "SOBRBackupTest","client","5/27/2020 22:00:26","0.02","0" 145 | "SOBRBackupTest","client","6/1/2020 22:00:27","0.02","0" 146 | "SOBRBackupTest","client","5/28/2020 22:00:12","0.02","0" 147 | "SOBRBackupTest","client","5/24/2020 22:00:16","0.02","0" 148 | "SOBRBackupTest","client","5/29/2020 22:00:19","0.02","0" 149 | "SOBRBackupTest","client","5/23/2020 22:00:18","7.44","1.12" 150 | "SOBRBackupTest","client","5/30/2020 22:00:25","7.44","1.12" 151 | "SOBRBackupTest","client","5/31/2020 22:00:34","0.02","0" 152 | "SOBRBackupTest","member","5/24/2020 22:00:16","0.02","0" 153 | "SOBRBackupTest","member","5/23/2020 22:00:18","6.8","1.02" 154 | "SOBRBackupTest","member","6/1/2020 22:00:27","0.02","0" 155 | "SOBRBackupTest","member","5/31/2020 22:00:34","0.02","0" 156 | "SOBRBackupTest","member","5/25/2020 22:00:20","0.02","0" 157 | "SOBRBackupTest","member","5/28/2020 22:00:12","0.02","0" 158 | "SOBRBackupTest","member","5/29/2020 22:00:19","0.02","0" 159 | "SOBRBackupTest","member","5/30/2020 22:00:25","6.8","1.02" 160 | "SOBRBackupTest","member","5/27/2020 22:00:26","0.02","0" 161 | -------------------------------------------------------------------------------- /SampleOutput/Session2/VeeamJobComparisonDetails.csv: -------------------------------------------------------------------------------- 1 | #TYPE Selected.System.Management.Automation.PSCustomObject 2 | "Name","ScheduledMatch","BackupModeMatch","FullEnabledMatch","AutoProxyMatch","ProxiesMatch","RepositoryMatch","RestorePointsMatch","DeduplicationMatch","CompressionMatch","StorageOptimizationMatch","RemoveDeletedVMsMatch","DeletedVMRetentionMatch","CBTEnabledMatch","QuiesceVMToolsMatch","IntegrityChecksMatch","SetVMNotesMatch","VMAttributeMatch","VSSEnabledMatch","IndexGuestFSMatch" 3 | "AUSVCENTER-NoTag","REFJOB","REFJOB","REFJOB","REFJOB","REFJOB","REFJOB","REFJOB","REFJOB","REFJOB","REFJOB","REFJOB","REFJOB","REFJOB","REFJOB","REFJOB","REFJOB","REFJOB","REFJOB","REFJOB" 4 | "zPowerShellDemoJob-2","True","True","True","False","False","True","False","True","True","True","False","True","True","False","True","False","False","False","False" 5 | "zPowerShellDemoJob-6","True","True","True","False","False","True","False","True","True","True","False","True","True","False","True","False","False","False","False" 6 | "zPowerShellDemoJob-7","True","True","True","False","False","True","False","True","True","True","False","True","True","False","True","False","False","False","False" 7 | "zPowerShellDemoJob","True","True","True","False","False","True","False","True","True","True","False","True","True","False","True","False","False","False","False" 8 | "zPowerShellDemoJob-4","True","True","True","False","False","True","False","True","True","True","False","True","True","False","True","False","False","False","False" 9 | "zPowerShellDemoJob-1","True","True","True","False","False","True","False","True","True","True","False","True","True","False","True","False","False","False","False" 10 | "DomainControllers","True","True","True","False","False","True","False","True","True","True","True","True","True","True","True","True","True","True","False" 11 | "SQLLogTest","True","True","True","True","False","True","False","True","True","True","True","True","True","True","True","True","True","True","True" 12 | "AUSVCENTER-TagTest","True","True","True","True","False","True","True","True","True","True","True","True","True","True","True","True","True","False","False" 13 | "zPowerShellDemoJob-3","True","True","True","False","False","True","False","True","True","True","False","True","True","False","True","False","False","False","False" 14 | "vCenterServers","True","True","True","False","False","True","False","True","True","True","True","True","True","True","True","True","True","False","False" 15 | "HyperV","True","True","True","False","False","False","False","True","True","True","False","True","True","False","True","False","False","True","False" 16 | "SOBRBackupTest","True","True","False","False","False","False","False","True","True","True","True","True","True","True","True","True","True","False","False" 17 | "zPowerShellDemoJob-5","True","True","True","False","False","True","False","True","True","True","False","True","True","False","True","False","False","False","False" 18 | -------------------------------------------------------------------------------- /SampleOutput/Session2/VeeamJobDetails.csv: -------------------------------------------------------------------------------- 1 | #TYPE Veeam.JobQuickConfig 2 | "Name","Scheduled","BackupMode","FullEnabled","AutoProxy","Proxies","Repository","RestorePoints","Deduplication","Compression","StorageOptimization","RemoveDeletedVMs","DeletedVMRetention","CBTEnabled","QuiesceVMTools","IntegrityChecks","SetVMNotes","VMAttribute","VSSEnabled","IndexGuestFS" 3 | "zPowerShellDemoJob-2","True","Increment","True","True","ausveeampxy01.lab.fullstackgeek.net;VMware Backup Proxy;ausveeampxy02.lab.fullstackgeek.net","ReFS-PerVM","7","True","Optimal","Local Target","False","14","True","False","True","False","Notes","False","Disabled" 4 | "zPowerShellDemoJob-6","True","Increment","True","True","ausveeampxy01.lab.fullstackgeek.net;VMware Backup Proxy;ausveeampxy02.lab.fullstackgeek.net","ReFS-PerVM","7","True","Optimal","Local Target","False","14","True","False","True","False","Notes","False","Disabled" 5 | "zPowerShellDemoJob-7","True","Increment","True","True","ausveeampxy01.lab.fullstackgeek.net;VMware Backup Proxy;ausveeampxy02.lab.fullstackgeek.net","ReFS-PerVM","7","True","Optimal","Local Target","False","14","True","False","True","False","Notes","False","Disabled" 6 | "zPowerShellDemoJob","True","Increment","True","True","ausveeampxy01.lab.fullstackgeek.net;VMware Backup Proxy;ausveeampxy02.lab.fullstackgeek.net","ReFS-PerVM","7","True","Optimal","Local Target","False","14","True","False","True","False","Notes","False","Disabled" 7 | "zPowerShellDemoJob-4","True","Increment","True","True","ausveeampxy01.lab.fullstackgeek.net;VMware Backup Proxy;ausveeampxy02.lab.fullstackgeek.net","ReFS-PerVM","7","True","Optimal","Local Target","False","14","True","False","True","False","Notes","False","Disabled" 8 | "zPowerShellDemoJob-1","True","Increment","True","True","ausveeampxy01.lab.fullstackgeek.net;VMware Backup Proxy;ausveeampxy02.lab.fullstackgeek.net","ReFS-PerVM","7","True","Optimal","Local Target","False","14","True","False","True","False","Notes","False","Disabled" 9 | "DomainControllers","True","Increment","True","True","ausveeampxy01.lab.fullstackgeek.net;VMware Backup Proxy;ausveeampxy02.lab.fullstackgeek.net","ReFS-PerVM","7","True","Optimal","Local Target","True","14","True","True","True","True","Veeam_Backup_Time","True","Disabled" 10 | "SQLLogTest","True","Increment","True","False","ausveeampxy01.lab.fullstackgeek.net","ReFS-PerVM","42","True","Optimal","Local Target","True","14","True","True","True","True","Veeam_Backup_Time","True","Enabled" 11 | "AUSVCENTER-TagTest","True","Increment","True","False","ausveeampxy01.lab.fullstackgeek.net","ReFS-PerVM","4","True","Optimal","Local Target","True","14","True","True","True","True","Veeam_Backup_Time","False","Disabled" 12 | "zPowerShellDemoJob-3","True","Increment","True","True","ausveeampxy01.lab.fullstackgeek.net;VMware Backup Proxy;ausveeampxy02.lab.fullstackgeek.net","ReFS-PerVM","7","True","Optimal","Local Target","False","14","True","False","True","False","Notes","False","Disabled" 13 | "AUSVCENTER-NoTag","True","Increment","True","False","ausveeampxy02.lab.fullstackgeek.net;ausveeampxy01.lab.fullstackgeek.net","ReFS-PerVM","4","True","Optimal","Local Target","True","14","True","True","True","True","Veeam_Backup_Time","True","Enabled" 14 | "vCenterServers","True","Increment","True","True","ausveeampxy01.lab.fullstackgeek.net;VMware Backup Proxy;ausveeampxy02.lab.fullstackgeek.net","ReFS-PerVM","5","True","Optimal","Local Target","True","14","True","True","True","True","Veeam_Backup_Time","False","Disabled" 15 | "HyperV","True","Increment","True","True","ausveeampxy01.lab.fullstackgeek.net;VMware Backup Proxy;ausveeampxy02.lab.fullstackgeek.net","NTFS-Bulk","14","True","Optimal","Local Target","False","14","True","False","True","False","Notes","True","Disabled" 16 | "SOBRBackupTest","True","Increment","False","True","ausveeampxy01.lab.fullstackgeek.net;VMware Backup Proxy;ausveeampxy02.lab.fullstackgeek.net","SOBR_Test","7","True","Optimal","Local Target","True","14","True","True","True","True","Veeam_Backup_Time","False","Disabled" 17 | "zPowerShellDemoJob-5","True","Increment","True","True","ausveeampxy01.lab.fullstackgeek.net;VMware Backup Proxy;ausveeampxy02.lab.fullstackgeek.net","ReFS-PerVM","7","True","Optimal","Local Target","False","14","True","False","True","False","Notes","False","Disabled" 18 | -------------------------------------------------------------------------------- /Session1/10_VeeamGeneralOptions.ps1: -------------------------------------------------------------------------------- 1 | #Check configuration of storage latency control 2 | $CIMDetails = Get-CimInstance -ClassName BackupServer -Namespace root/VeeamBS -Computername ausveeambr 3 | 4 | $StorageLatencyDetails = [PSCustomObject]@{ 5 | StorageLatencyEnabled = $CIMDetails.LimitParallelTasksByDatastoreLatency; 6 | StopAssigningTasksLatency = $CIMDetails.MaxDatastoreLatencyMs; 7 | ThrottleExistingTasksLatency = $CIMDetails.MinDatastoreLatency4ThrottleMs 8 | } 9 | 10 | Write-Output $StorageLatencyDetails 11 | 12 | $CIMDetails | Show-Object 13 | -------------------------------------------------------------------------------- /Session1/11_Get-VBRConfig.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 4 2 | #Requires -RunAsAdministrator 3 | <# 4 | .Synopsis 5 | Simple Veeam report to dump server & job configurations 6 | .Notes 7 | Version: 0.2 8 | Author: Joe Houghes 9 | Modified Date: 4-24-2020 10 | .EXAMPLE 11 | Get-VBRConfig -VBRServer ausveeambr -ReportPath C:\Temp\VBROutput 12 | #> 13 | 14 | function Get-VBRConfig { 15 | param( 16 | # VBRServer 17 | [Parameter(Mandatory)] 18 | [string]$VBRServer, 19 | [Parameter(Mandatory)] 20 | [string]$ReportPath 21 | ) 22 | 23 | begin { 24 | 25 | #Load the Veeam PSSnapin 26 | if (!(Get-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue)) { 27 | Add-PSSnapin -Name VeeamPSSnapIn 28 | Connect-VBRServer -Server $VBRServer 29 | } 30 | 31 | else { 32 | Disconnect-VBRServer 33 | Connect-VBRServer -Server $VBRServer 34 | } 35 | 36 | if (!(Test-Path $ReportPath)) { 37 | New-Item -Path $ReportPath -ItemType Directory | Out-Null 38 | } 39 | 40 | Push-Location -Path $ReportPath 41 | Write-Verbose ("Changing directory to '$ReportPath'") 42 | 43 | } 44 | 45 | process { 46 | 47 | $Servers = Get-VBRServer 48 | $Jobs = Get-VBRJob -WarningAction SilentlyContinue | Where-Object { $_.JobType -eq 'Backup' -OR $_.JobType -eq 'BackupSync' } 49 | $Proxies = Get-VBRViProxy 50 | $Repositories = Get-VBRBackupRepository 51 | $SOBRs = Get-VBRBackupRepository -ScaleOut 52 | 53 | [System.Collections.ArrayList]$RepositoryDetails = @() 54 | 55 | foreach ($Repo in $Repositories) { 56 | $RepoOutput = [pscustomobject] @{ 57 | 'ID' = $Repo.ID 58 | 'Name' = $Repo.Name 59 | } 60 | $null = $RepositoryDetails.Add($RepoOutput) 61 | Remove-Variable RepoOutput 62 | } 63 | 64 | foreach ($Repo in $SOBRs) { 65 | $RepoOutput = [pscustomobject] @{ 66 | 'ID' = $Repo.ID 67 | 'Name' = $Repo.Name 68 | } 69 | $null = $RepositoryDetails.Add($RepoOutput) 70 | Remove-Variable RepoOutput 71 | } 72 | 73 | [System.Collections.ArrayList]$AllJobs = @() 74 | 75 | foreach ($Job in $Jobs) { 76 | $JobDetails = $Job | Select-Object -Property 'Name', 'JobType', 'SheduleEnabledTime', 'ScheduleOptions', @{n = 'RestorePoints'; e = { $Job.Options.BackupStorageOptions.RetainCycles } }, @{n = 'RepoName'; e = { $RepositoryDetails | Where-Object { $_.Id -eq $job.Info.TargetRepositoryId.Guid } | Select-Object -ExpandProperty Name } }, @{n = 'Algorithm'; e = { $Job.Options.BackupTargetOptions.Algorithm } }, @{n = 'FullBackupScheduleKind'; e = { $Job.Options.BackupTargetOptions.FullBackupScheduleKind } }, @{n = 'FullBackupDays'; e = { $Job.Options.BackupTargetOptions.FullBackupDays } }, @{n = 'TransformFullToSyntethic'; e = { $Job.Options.BackupTargetOptions.TransformFullToSyntethic } }, @{n = 'TransformIncrementsToSyntethic'; e = { $Job.Options.BackupTargetOptions.TransformIncrementsToSyntethic } }, @{n = 'TransformToSyntethicDays'; e = { $Job.Options.BackupTargetOptions.TransformToSyntethicDays } } 77 | $AllJobs.Add($JobDetails) | Out-Null 78 | } 79 | 80 | [System.Collections.ArrayList]$AllSOBRExtents = @() 81 | 82 | foreach ($SOBR in $SOBRs) { 83 | $Extents = Get-VBRRepositoryExtent -Repository $SOBR 84 | 85 | foreach ($Extent in $Extents) { 86 | $ExtentDetails = $Extent.Repository | Select-Object *, @{n = 'SOBR_Name'; e = { $SOBR.Name } } 87 | $AllSOBRExtents.Add($ExtentDetails) | Out-Null 88 | } 89 | } 90 | 91 | } 92 | 93 | end { 94 | 95 | $Servers | Export-Csv -Path $("$ReportPath\$VBRServer" + '_Servers.csv') -NoTypeInformation 96 | $AllJobs | Export-Csv -Path $("$ReportPath\$VBRServer" + '_Jobs.csv') -NoTypeInformation 97 | $Proxies | Export-Csv -Path $("$ReportPath\$VBRServer" + '_Proxies.csv') -NoTypeInformation 98 | $Repositories | Export-Csv -Path $("$ReportPath\$VBRServer" + '_Repositories.csv') -NoTypeInformation 99 | $SOBRs | Export-Csv -Path $("$ReportPath\$VBRServer" + '_SOBRs.csv') -NoTypeInformation 100 | $AllSOBRExtents | Export-Csv -Path $("$ReportPath\$VBRServer" + '_SOBRExtents.csv') -NoTypeInformation 101 | 102 | Disconnect-VBRServer 103 | Pop-Location 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Session1/12_Get-VeeamSessionReport_Quick.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 4 2 | #Requires -RunAsAdministrator 3 | <# 4 | .Synopsis 5 | Simple Veeam report to give details of task sessions for VMware backup jobs 6 | .Notes 7 | Version: 1.0 8 | Author: Joe Houghes 9 | Modified Date: 4-21-20 10 | .EXAMPLE 11 | Get-VeeamSessionReport | Format-Table 12 | .EXAMPLE 13 | Get-VeeamSessionReport -VBRServer ausveeambr | Export-Csv D:\Temp\VeeamSessionReport.csv -NoTypeInformation 14 | .EXAMPLE 15 | Get-VeeamSessionReport -VBRServer ausveeambr -RemoveDuplicates | Export-Csv D:\Temp\VeeamSessionReport_NoDupes.csv -NoTypeInformation 16 | 17 | #> 18 | 19 | function Get-VeeamSessionReport { 20 | [CmdletBinding()] 21 | param ( 22 | [string]$VBRServer = 'localhost', 23 | [string[]]$JobName, 24 | [switch]$RemoveDuplicates 25 | ) 26 | begin { 27 | 28 | #Load the Veeam PSSnapin 29 | if (!(Get-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue)) { 30 | Add-PSSnapin -Name VeeamPSSnapIn 31 | Connect-VBRServer -Server $VBRServer 32 | } 33 | 34 | Disconnect-VBRServer 35 | Connect-VBRServer -Server $VBRServer 36 | 37 | } #end Begin block 38 | 39 | process { 40 | 41 | $AllJobs = Get-VBRJob -WarningAction SilentlyContinue 42 | 43 | $VMwareBackupJobIDs = $AllJobs | Where-Object { ($_.JobType -eq 'Backup') -AND ($_.BackupPlatform.Platform -eq 'EVmware') } | Select-Object -ExpandProperty ID 44 | 45 | $AllBackupSessions = [Veeam.Backup.Core.CBackupSession]::GetAll() 46 | $SelectBackupSessions = $AllBackupSessions | Where-Object { $_.JobId -in $VMwareBackupJobIDs } 47 | 48 | $SelectTaskSessions = $SelectBackupSessions.GetTaskSessions() 49 | 50 | [System.Collections.ArrayList]$AllTasksOutput = @() 51 | 52 | foreach ($TaskSession in $SelectTaskSessions) { 53 | 54 | $LogRegex = [regex]'\bUsing \b.+\s(\[[^\]]*\])' 55 | $BottleneckRegex = [regex]'^Busy: (\S+ \d+% > \S+ \d+% > \S+ \d+% > \S+ \d+%)' 56 | $PrimaryBottleneckRegex = [regex]'^Primary bottleneck: (\S+)' 57 | 58 | $ProcessingLogMatches = $TaskSession.Logger.GetLog().UpdatedRecords | Where-Object Title -match $LogRegex 59 | $ProcessingLogMatchTitles = $(($ProcessingLogMatches.Title -replace '\bUsing \b.+\s\[', '') -replace ']', '') 60 | $ProcessingMode = $($ProcessingLogMatchTitles | Select-Object -Unique) -join ';' 61 | 62 | $BottleneckLogMatch = $TaskSession.Logger.GetLog().UpdatedRecords | Where-Object Title -match $BottleneckRegex 63 | $BottleneckDetails = $BottleneckLogMatch.Title -replace 'Busy: ', '' 64 | 65 | $PrimaryBottleneckLogMatch = $TaskSession.Logger.GetLog().UpdatedRecords | Where-Object Title -match $PrimaryBottleneckRegex 66 | $PrimaryBottleneckDetails = $PrimaryBottleneckLogMatch.Title -replace 'Primary bottleneck: ' 67 | 68 | try { 69 | $JobSessionDuration = $TaskSession.JobSess.SessionInfo.Progress.Duration.ToString() 70 | } catch { 71 | $JobSessionDuration = '' 72 | } 73 | 74 | try { 75 | $TaskSessionDuration = $TaskSession.WorkDetails.WorkDuration.ToString() 76 | } catch { 77 | $TaskSessionDuration = '' 78 | } 79 | 80 | $TaskOutputResult = [pscustomobject][ordered] @{ 81 | 82 | 'JobName' = $TaskSession.JobName 83 | 'VMName' = $TaskSession.Name 84 | 'Status' = $TaskSession.Status 85 | 'IsRetry' = $TaskSession.JobSess.IsRetryMode 86 | 'ProcessingMode' = $ProcessingMode 87 | 'JobDuration' = $($JobSessionDuration) 88 | 'TaskDuration' = $($TaskSessionDuration) 89 | 'TaskAlgorithm' = $TaskSession.WorkDetails.TaskAlgorithm 90 | 'CreationTime' = $TaskSession.JobSess.CreationTime 91 | 'BackupSize(GB)' = [math]::Round(($TaskSession.JobSess.BackupStats.BackupSize / 1GB), 4) 92 | 'DataSize(GB)' = [math]::Round(($TaskSession.JobSess.BackupStats.DataSize / 1GB), 4) 93 | 'DedupRatio' = $TaskSession.JobSess.BackupStats.DedupRatio 94 | 'CompressRatio' = $TaskSession.JobSess.BackupStats.CompressRatio 95 | 'BottleneckDetails' = $BottleneckDetails 96 | 'PrimaryBottleneck' = $PrimaryBottleneckDetails 97 | 98 | } #end TaskOutputResult object 99 | 100 | if ($TaskOutputResult) { 101 | $null = $AllTasksOutput.Add($TaskOutputResult) 102 | Remove-Variable TaskOutputResult -ErrorAction SilentlyContinue 103 | }#end if 104 | 105 | } #end foreach TaskSession 106 | 107 | } #end Process block 108 | 109 | end { 110 | 111 | if ($RemoveDuplicates) { 112 | 113 | $UniqueTaskOutput = $AllTasksOutput | Select-Object JobName, VMName, Status, IsRetry, ProcessingMode, WorkDuration, TaskAlgorithm, CreationTime, BackupSize, DataSize, DedupRatio, CompressRatio -Unique 114 | Write-Output $UniqueTaskOutput 115 | 116 | } 117 | 118 | else { 119 | Write-Output $AllTasksOutput 120 | } 121 | 122 | } #end End block 123 | 124 | } #end function 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /Session1/12_Get-VeeamSessionReport_Slow.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 4 2 | #Requires -RunAsAdministrator 3 | <# 4 | .Synopsis 5 | Simple Veeam report to give details of task sessions for VMware backup jobs 6 | .Notes 7 | Version: 1.0 8 | Author: Joe Houghes 9 | Modified Date: 4-21-20 10 | .EXAMPLE 11 | Get-VeeamSessionReport | Format-Table 12 | .EXAMPLE 13 | Get-VeeamSessionReport -VBRServer ausveeambr | Export-Csv D:\Temp\VeeamSessionReport.csv -NoTypeInformation 14 | .EXAMPLE 15 | Get-VeeamSessionReport -VBRServer ausveeambr -RemoveDuplicates | Export-Csv D:\Temp\VeeamSessionReport_NoDupes.csv -NoTypeInformation 16 | 17 | #> 18 | 19 | function Get-VeeamSessionReport { 20 | [CmdletBinding()] 21 | param ( 22 | [string]$VBRServer = 'localhost', 23 | [switch]$RemoveDuplicates 24 | ) 25 | begin { 26 | 27 | #Load the Veeam PSSnapin 28 | if (!(Get-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue)) { 29 | Add-PSSnapin -Name VeeamPSSnapIn 30 | Connect-VBRServer -Server $VBRServer 31 | } 32 | 33 | Disconnect-VBRServer 34 | Connect-VBRServer -Server $VBRServer 35 | 36 | $AllJobs = Get-VBRJob -WarningAction SilentlyContinue | Where-Object { ($_.JobType -eq 'Backup') -AND ($_.BackupPlatform.Platform -eq 'EVmware') } 37 | 38 | [System.Collections.ArrayList]$AllTasksOutput = @() 39 | 40 | } 41 | 42 | process { 43 | 44 | foreach ($EachJob in $AllJobs) { 45 | 46 | $JobSessions = [Veeam.Backup.Core.CBackupSession]::GetByJob($EachJob.Id) 47 | 48 | if ([bool]$JobSessions) { 49 | 50 | foreach ($CurrentSession in $JobSessions) { 51 | 52 | $TaskSessions = Get-VBRTaskSession -Session $CurrentSession 53 | 54 | foreach ($TaskSession in $TaskSessions) { 55 | 56 | $LogMatch = [regex]'\bUsing \b.+\s(\[[^\]]*\])' 57 | $LogMatches = $TaskSession.Logger.GetLog().UpdatedRecords | Where-Object Title -match $LogMatch 58 | 59 | foreach ($LogMatch in $LogMatches) { 60 | $TitleMatch = $LogMatch.Title -match $LogMatch 61 | $ProcessingMode = ($Matches[1] -replace '\[', '') -replace ']', '' 62 | 63 | $TaskOutputResult = [pscustomobject] @{ 64 | 65 | 'JobName' = $TaskSession.JobName; 66 | 'VMName' = $TaskSession.Name; 67 | 'Status' = $TaskSession.Status; 68 | 'IsRetry' = $TaskSession.JobSess.IsRetryMode; 69 | 'ProcessingMode' = $ProcessingMode; 70 | 'WorkDuration' = $TaskSession.WorkDetails.WorkDuration.TotalSeconds; 71 | 'TaskAlgorithm' = $TaskSession.WorkDetails.TaskAlgorithm; 72 | 'CreationTime' = $TaskSession.JobSess.CreationTime; 73 | 'BackupSize' = $TaskSession.JobSess.BackupStats.BackupSize; 74 | 'DataSize' = $TaskSession.JobSess.BackupStats.DataSize; 75 | 'DedupRatio' = $TaskSession.JobSess.BackupStats.DedupRatio; 76 | 'CompressRatio' = $TaskSession.JobSess.BackupStats.CompressRatio; 77 | 78 | } #end TaskOutputResult object 79 | 80 | $null = $AllTasksOutput.Add($TaskOutputResult) 81 | 82 | } #end foreach LogMatch 83 | 84 | } #end foreach TaskSession 85 | 86 | } #end foreach JobSession 87 | 88 | } #end if JobSessions 89 | 90 | } #end foreach Job 91 | 92 | } 93 | 94 | end { 95 | 96 | if ($RemoveDuplicates) { 97 | $UniqueTaskOutput = $AllTasksOutput | Select-Object JobName, VMName, Status, IsRetry, ProcessingMode, WorkDuration, TaskAlgorithm, CreationTime, BackupSize, DataSize, DedupRatio, CompressRatio -Unique 98 | Write-Output $UniqueTaskOutput 99 | } 100 | 101 | else { 102 | Write-Output $AllTasksOutput 103 | } 104 | 105 | } 106 | 107 | } -------------------------------------------------------------------------------- /Session1/13_Get-VMandDiskFilterDetails.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 4 2 | #Requires -RunAsAdministrator 3 | <# 4 | .Synopsis 5 | Simple Veeam report to check for disk filters 6 | .Notes 7 | Version: 0.2 8 | Author: Joe Houghes 9 | Modified Date: 3-1-2019 10 | .EXAMPLE 11 | Get-VMandDiskFilterDetails | Format-Table 12 | .EXAMPLE 13 | Get-VMandDiskFilterDetails | Export-Csv VM_DiskFilterDetails.csv -NoTypeInformation 14 | #> 15 | 16 | function Get-VMandDiskFilterDetails { 17 | [CmdletBinding()] 18 | param ( 19 | [string]$VBRServer = 'localhost' 20 | ) 21 | 22 | begin { 23 | 24 | #Load the Veeam PSSnapin 25 | if (!(Get-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue)) { 26 | Add-PSSnapin -Name VeeamPSSnapIn 27 | Connect-VBRServer -Server $VBRServer 28 | } 29 | 30 | Disconnect-VBRServer 31 | Connect-VBRServer -Server $VBRServer 32 | 33 | [System.Collections.ArrayList]$reportJobOutput = @() 34 | 35 | } 36 | 37 | Process{ 38 | 39 | $reportJobs = Get-VBRJob -WarningAction SilentlyContinue | Where-Object {$PSItem.JobType -eq 'Backup' -OR $PSItem.JobType -eq 'BackupSync' -AND $PSItem.BackupPlatform.Platform -eq 'EVmware'} 40 | $repositories = Get-VBRBackupRepository | Select-Object Name,Id 41 | 42 | foreach ($reportJob in $reportJobs) { 43 | 44 | $currentBackup = Get-VBRBackup -Name $reportJob.Name 45 | $currentRepo = $repositories | Where-Object -Property Id -eq -Value $currentBackup.RepositoryId 46 | $currentJobVMs = $reportJob.GetViOijs() 47 | 48 | foreach ($currentVM in $currentJobVMs) { 49 | $Mode = $currentVM.DiskFilterInfo.Mode 50 | 51 | if (($Mode -ne 'AllDisks')){ 52 | $Disks = ($currentVM.DiskFilter.Disks | Select-Object -ExpandProperty DisplayName) -join ';' 53 | } 54 | else { 55 | $Disks = 'All' 56 | } 57 | 58 | $reportJobOutputObject = [PSCustomObject] @{ 59 | 'BackupJob' = $reportJob.Name 60 | 'VMName' = $currentVM.Name 61 | 'Location' = $currentRepo.Name 62 | 'DiskMode' = $Mode 63 | 'SpecificDisks' = $Disks 64 | } 65 | 66 | $null = $reportJobOutput.Add($reportJobOutputObject) 67 | } 68 | } 69 | } 70 | 71 | end{ 72 | 73 | Write-Output $reportJobOutput | Select-Object 'BackupJob','VMName','Location','DiskMode','SpecificDisks' 74 | 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /Session1/14_VMsNotInBackups.ps1: -------------------------------------------------------------------------------- 1 | [string]$VBRServer = 'ausveeambr' 2 | 3 | #Load the Veeam PSSnapin 4 | if (!(Get-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue)) { 5 | Add-PSSnapin -Name VeeamPSSnapIn 6 | Connect-VBRServer -Server $VBRServer 7 | } 8 | 9 | Disconnect-VBRServer 10 | Connect-VBRServer -Server $VBRServer 11 | 12 | $Jobs = Get-VBRJob -WarningAction SilentlyContinue | Where-Object { $PSItem.JobType -eq 'Backup' -AND $PSItem.BackupPlatform.Platform -eq 'EVmware' } 13 | $JobObjects = $Jobs | Get-VBRJobObject 14 | $JobVMObjects = $JobObjects | Where-Object { $PSItem.Object.ViType -eq 'VirtualMachine' -AND $PSItem.Object.Platform.Platform -eq 'EVmware' } 15 | $JobTagObjects = $JobObjects | Where-Object { $PSItem.Object.ViType -eq 'Tag' -AND $PSItem.Object.Platform.Platform -eq 'EVmware' } 16 | 17 | $JobVMs = $JobVMObjects | Select-Object Name, @{n = 'JobID'; e = { $PSItem.JobId.Guid } }, @{n = 'MoRefID'; e = { $PSItem.Object.ObjectID } }, @{n = 'Uuid'; e = { $PSItem.Object.Uuid } }, @{n = 'vCenter'; e = { $PSItem.Object.Host.Name } } 18 | $UniqueJobVMs = $JobVMs | Select-Object Name, JobID, MoRefID, Uuid, VC -Unique 19 | 20 | $JobTags = $JobTagObjects | Select-Object Name, @{n = 'JobID'; e = { $PSItem.JobId.Guid } }, @{n = 'Path'; e = { $PSItem.Location } }, @{n = 'vCenter'; e = { $PSItem.Object.Host.Name } } 21 | $UniqueJobTags = $JobTags | Select-Object Name, JobID, Path, VC -Unique 22 | 23 | $TagPaths = foreach ($EachTag in $UniqueJobTags) { 24 | $EachTag.Path + "\*" 25 | } 26 | 27 | $Backups = Get-VBRBackup -Name $Jobs.Name 28 | $BackupObjects = $Backups.GetObjects() | Select-Object Name, @{n = 'MoRefID'; e = { $PSItem.ObjectID } }, @{n = 'Uuid'; e = { $PSItem.Uuid } }, @{n = 'vCenterVC'; e = { $PSItem.Host.Name } } 29 | $UniqueBackupObjects = $BackupObjects | Select-Object Name, MoRefID, Uuid, VC -Unique 30 | 31 | $AllVMs = Find-VBRViEntity -VMsAndTemplates | Where-Object { $PSItem.Type -eq 'VM' } | Select-Object Name, Reference, Uuid, Path, @{n = 'vCenter'; e = { ($PSItem.Path -split '\\')[0] } } 32 | 33 | $VCTagVMs = Find-VBRViEntity -Tags | Where-Object { $PSItem.Type -eq 'VM' } | Select-Object Name, Reference, Uuid, Path, @{n = 'vCenter'; e = { ($PSItem.Path -split '\\')[0] } } 34 | 35 | $PathMatchVMs = foreach ($EachVM in $VCTagVMs) { 36 | foreach ($EachTag in $TagPaths) { 37 | if ($EachVM.Path -like $EachTag){ 38 | $EachVM 39 | } 40 | } 41 | } 42 | 43 | [System.Collections.ArrayList]$JobMissingVMs = @() 44 | [System.Collections.ArrayList]$JobCoveredVMs = @() 45 | 46 | [System.Collections.ArrayList]$BackupMissingVMs = @() 47 | [System.Collections.ArrayList]$BackupCoveredVMs = @() 48 | 49 | foreach ($EachVM in $AllVMs) { 50 | 51 | if ($EachVM.Uuid -In ($UniqueBackupObjects.Uuid) ) { 52 | 53 | $VMResult = [PSCustomObject] @{ 54 | Name = $EachVM.Name 55 | MoRefID = $EachVM.Reference 56 | Uuid = $EachVM.Uuid 57 | Path = $EachVM.Path 58 | vCenter = $EachVM.vCenter 59 | } #end PSCustomObject 60 | 61 | $null = $BackupCoveredVMs.Add($VMResult) 62 | Remove-Variable VMResult 63 | }#end if notin UniqueBackupObjects 64 | 65 | else { 66 | $VMResult = [PSCustomObject] @{ 67 | Name = $EachVM.Name 68 | MoRefID = $EachVM.Reference 69 | Uuid = $EachVM.Uuid 70 | Path = $EachVM.Path 71 | vCenter = $EachVM.vCenter 72 | } #end PSCustomObject 73 | 74 | $null = $BackupMissingVMs.Add($VMResult) 75 | Remove-Variable VMResult 76 | 77 | }#end else in UniqueBackupObjects 78 | 79 | if ($EachVM.Uuid -In ($UniqueJobVMs.Uuid) ) { 80 | 81 | if ($EachVM.Uuid -In ($PathMatchVMs.Uuid) ) { 82 | $AddedBy = 'VM;Tag' 83 | } 84 | 85 | else { 86 | $AddedBy = 'VM' 87 | } 88 | 89 | $VMResult = [PSCustomObject] @{ 90 | Name = $EachVM.Name 91 | MoRefID = $EachVM.Reference 92 | Uuid = $EachVM.Uuid 93 | Path = $EachVM.Path 94 | vCenter = $EachVM.vCenter 95 | Addedby = $AddedBy 96 | } #end PSCustomObject 97 | 98 | $null = $JobCoveredVMs.Add($VMResult) 99 | Remove-Variable VMResult 100 | }#end if notin UniqueJobVMObjects 101 | 102 | elseif ($EachVM.Uuid -In ($PathMatchVMs.Uuid) ) { 103 | 104 | if ($EachVM.Uuid -In ($UniqueJobVMs.Uuid) ) { 105 | $AddedBy = 'Tag;VM' 106 | } 107 | 108 | else { 109 | $AddedBy = 'Tag' 110 | } 111 | 112 | $VMResult = [PSCustomObject] @{ 113 | Name = $EachVM.Name 114 | MoRefID = $EachVM.Reference 115 | Uuid = $EachVM.Uuid 116 | Path = $EachVM.Path 117 | vCenter = $EachVM.vCenter 118 | Addedby = $AddedBy 119 | } #end PSCustomObject 120 | 121 | $null = $JobCoveredVMs.Add($VMResult) 122 | Remove-Variable VMResult 123 | }#end if notin UniqueJobVMObjects 124 | 125 | else { 126 | $VMResult = [PSCustomObject] @{ 127 | Name = $EachVM.Name 128 | MoRefID = $EachVM.Reference 129 | Uuid = $EachVM.Uuid 130 | Path = $EachVM.Path 131 | vCenter = $EachVM.vCenter 132 | } #end PSCustomObject 133 | 134 | $null = $JobMissingVMs.Add($VMResult) 135 | Remove-Variable VMResult 136 | 137 | }#end else in UniqueJobVMObjects 138 | 139 | } #end foreach 140 | 141 | Write-Output 'Script completed, writing output.' 142 | Write-Output $JobMissingVMs | Export-Csv 'JobMissingVMs.csv' -NoTypeInformation 143 | Write-Output $JobCoveredVMs | Export-Csv 'JobCoveredVMs.csv' -NoTypeInformation 144 | 145 | Write-Output $BackupMissingVMs | Export-Csv 'BackupMissingVMs.csv' -NoTypeInformation 146 | Write-Output $BackupCoveredVMs | Export-Csv 'BackupCoveredVMs.csv' -NoTypeInformation 147 | 148 | 149 | $DupeJobVMs = Compare-Object -ReferenceObject $JobVMs -DifferenceObject $UniqueJobVMs -Property Name 150 | if ($DupeJobVMs) { 151 | 152 | Write-Output '' 153 | Write-Output 'VMs duplicated in Jobs are:' 154 | 155 | foreach ($EachVM in $($DupeJobVMs.Name)) { 156 | Write-Output "$EachVM" 157 | } 158 | 159 | Write-Output $($DupeJobVMs.Name) | Out-File 'DupeJobVMs.txt' 160 | } 161 | 162 | $DupeJobTagVMs = $JobCoveredVMs | Where-Object { ($PSItem.AddedBy -eq 'Tag;VM') -OR ($PSItem.AddedBy -eq 'VM;Tag') } 163 | if ($DupeJobTagVMs) { 164 | 165 | Write-Output '' 166 | Write-Output 'VMs duplicated by VM & tag within Jobs are:' 167 | 168 | foreach ($EachVM in $($DupeJobTagVMs.Name)) { 169 | Write-Output "$EachVM" 170 | } 171 | 172 | Write-Output $DupeJobTagVMs.Name | Out-File 'DupeJobVMs-VM&Tag.txt' 173 | } 174 | 175 | $DupeBackupVMs = Compare-Object -ReferenceObject $BackupObjects -DifferenceObject $UniqueBackupObjects -Property Name 176 | 177 | if ($DupeBackupVMs) { 178 | 179 | Write-Output '' 180 | Write-Output 'VMs duplicated in Backups are:' 181 | 182 | foreach ($EachVM in $($DupeBackupVMs.Name)) { 183 | Write-Output "$EachVM" 184 | } 185 | 186 | Write-Output $DupeBackupVMs.Name | Out-File 'DupeBackupVMs.txt' 187 | } -------------------------------------------------------------------------------- /Session1/1_NewBackupShellJob.ps1: -------------------------------------------------------------------------------- 1 | Add-PSSnapin -Name VeeamPSSnapIn 2 | Connect-VBRServer -Server ausveeambr.lab.fullstackgeek.net 3 | 4 | Get-VBRJob -WarningAction SilentlyContinue | Select-Object Name, Description 5 | 6 | #NewBackupShellJob 7 | $VeeamRepositoryName = 'ReFS-PerVM' 8 | $VeeamBackupJobName = 'zPowerShellDemoJob' 9 | 10 | $vCenterServerName = 'ausvcenter.fsglab.local' 11 | $VMName = 'ausvcenter' 12 | 13 | $Repository = Get-VBRBackupRepository -Name $VeeamRepositoryName 14 | $vCenterServer = Get-VBRServer -Name $vCenterServerName 15 | $VMtoAdd = Find-VBRViEntity -Name $VMName -Server $vCenterServer -VM 16 | 17 | #Create new shell backup job 18 | $NewShellJob = Add-VBRViBackupJob -Name $VeeamBackupJobName -Description 'Demo backup job for VMware VM created via script' -BackupRepository $Repository -Entity $VMtoAdd 19 | 20 | #Show Job Objects 21 | $NewShellJob | Get-VBRJobObject | Select Name, TypeDisplayName, Type 22 | 23 | #Remove VM from job objects 24 | $JobObject = $NewShellJob | Get-VBRJobObject 25 | Remove-VBRJobObject -Objects $JobObject -Completely 26 | 27 | $NewShellJob.Info.CommonInfo 28 | $NewShellJob.Info.CommonInfo.ModifiedBy 29 | $NewShellJob.Info.ScheduleOptions.LatestRunLocal 30 | 31 | Get-VBRJob -WarningAction SilentlyContinue | Select-Object Name, Description 32 | -------------------------------------------------------------------------------- /Session1/2_QuickJobStatus.ps1: -------------------------------------------------------------------------------- 1 | $Jobs = Get-VBRJob -WarningAction SilentlyContinue 2 | 3 | #Properties: 4 | $Jobs | Select-Object -Property Name, TypeToString, IsRunning, IsRequireRetry, IsScheduleEnabled, LatestRunLocal | Format-Table -AutoSize 5 | 6 | #Properties (Custom Labels): 7 | $Properties = @( 8 | @{n='Name';e={$_.Name}}, 9 | @{n='JobType';e={$_.TypeToString}}, 10 | @{n='Running';e={$_.IsRunning}}, 11 | @{n='RequiresRetry';e={$_.IsRequireRetry}}, 12 | @{n='Scheduled';e={$_.IsScheduleEnabled}}, 13 | @{n='LatestRunLocal';e={$_.LatestRunLocal}} 14 | ) 15 | 16 | $Jobs | Select-Object -Property $Properties | Format-Table 17 | 18 | $Jobs | Select-Object -Property $Properties | Export-CSV D:\Demos\Session1\JobStatusProperties.csv -NoTypeInformation 19 | 20 | Invoke-Item D:\Demos\Session1\JobStatusProperties.csv 21 | 22 | #Methods: 23 | $Jobs | Select-Object -Property Name, TypeToString, @{n = 'LastResult'; e = { $_.GetLastResult() } }, @{n = 'LastState'; e = { $_.GetLastState() } }, @{n = 'Objects'; e = { $_.GetObjectsInJob().Count } }, @{n = 'Repo'; e = { $_.GetTargetRepository().Name } }, @{n = 'InWindow'; e = { $_.IsInBackupWindow($(Get-Date)) } }, @{n = 'WANAcc';e = { $_.IsWanAcceleratorEnabled()}} | Format-Table -AutoSize 24 | 25 | #Methods (Custom Labels): 26 | 27 | $Methods = @( 28 | @{n='Name';e={$_.Name}}, 29 | @{n='JobType';e={$_.TypeToString}}, 30 | @{n='LastResult';e={$_.GetLastResult()}}, 31 | @{n='LastState';e={$_.GetLastState()}}, 32 | @{n='ObjectsCount';e={$_.GetObjectsInJob().Count}}, 33 | @{n='Repository';e={$_.GetTargetRepository().Name}}, 34 | @{n='InWindow';e={$_.IsInBackupWindow($(Get-Date))}}, 35 | @{n='WANAcc';e={$_.IsWanAcceleratorEnabled()}} 36 | ) 37 | 38 | $Jobs | Select-Object -Property $Methods | Format-Table 39 | 40 | $Jobs | Select-Object -Property $Methods | Export-CSV D:\Demos\Session1\JobStatusMethods.csv -NoTypeInformation 41 | 42 | Invoke-Item D:\Demos\Session1\JobStatusMethods.csv 43 | -------------------------------------------------------------------------------- /Session1/3_RestorePointReport_Quick.ps1: -------------------------------------------------------------------------------- 1 | [string]$VBRServer = 'ausveeambr' 2 | 3 | #Load the Veeam PSSnapin 4 | if (!(Get-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue)) { 5 | Add-PSSnapin -Name VeeamPSSnapIn 6 | Connect-VBRServer -Server $VBRServer 7 | } else { 8 | Disconnect-VBRServer 9 | Connect-VBRServer -Server $VBRServer 10 | } 11 | 12 | $VMBackups = Get-VBRBackup | Where-Object { $_.TypeToString -eq 'VMware Backup' } 13 | 14 | [System.Collections.ArrayList]$AllRestorePointsObject = @() 15 | 16 | foreach ($CurrentBackup in $VMBackups) { 17 | 18 | $RestorePoints = $CurrentBackup | Get-VBRRestorePoint 19 | 20 | $Storages = $CurrentBackup.GetAllStorages() 21 | 22 | foreach ($CurrentRestorePoint in $RestorePoints) { 23 | 24 | if ($CurrentRestorePoint.Info.IsConsistent) { 25 | $Status = 'Successful' 26 | } 27 | if ($CurrentRestorePoint.Info.IsCorrupted) { 28 | $Status = 'Corrupted' 29 | } 30 | if ($CurrentRestorePoint.Info.IsRecheckCorrupted) { 31 | $Status = 'FailedHealthCheck' 32 | } 33 | 34 | 35 | $StorageFile = $Storages | Where-Object { $_.Id -eq $CurrentRestorePoint.StorageId } 36 | $FileName = ($StorageFile.PartialPath.Internal.Elements[0]) 37 | 38 | $CurrentBackupOutputObject = [pscustomobject] @{ 39 | 40 | 'Hostname' = $CurrentRestorePoint.Name 41 | 'CreationTime' = $CurrentRestorePoint.CreationTime 42 | 'Job Name' = $CurrentBackup.JobName 43 | 'BackupSize(GB)' = [math]::Round(($StorageFile.Stats.BackupSize / 1GB), 4) 44 | 'DataSize(GB)' = [math]::Round(($StorageFile.Stats.DataSize / 1GB), 4) 45 | 'Full/Inc' = $CurrentRestorePoint.Algorithm 46 | 'Status' = $Status 47 | 'Job Type' = $CurrentBackup.TypeToString 48 | 'FileName' = $FileName 49 | 'IsAvailable' = $StorageFile.IsAvailable 50 | 'FilePath' = $StorageFile.FilePath 51 | } 52 | 53 | $null = $AllRestorePointsObject.Add($CurrentBackupOutputObject) 54 | 55 | Remove-Variable -Name CurrentBackupOutputObject -ErrorAction SilentlyContinue 56 | 57 | } #end foreach CurrentRestorePoint 58 | 59 | } #end foreach CurrentBackup 60 | 61 | Disconnect-VBRServer 62 | 63 | Write-Output $AllRestorePointsObject 64 | 65 | -------------------------------------------------------------------------------- /Session1/3_RestorePointReport_Slow.ps1: -------------------------------------------------------------------------------- 1 | [string]$VBRServer = 'ausveeambr' 2 | 3 | #Load the Veeam PSSnapin 4 | if (!(Get-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue)) { 5 | Add-PSSnapin -Name VeeamPSSnapIn 6 | Connect-VBRServer -Server $VBRServer 7 | } else { 8 | Disconnect-VBRServer 9 | Connect-VBRServer -Server $VBRServer 10 | } 11 | 12 | $VMBackups = Get-VBRBackup | Where-Object { $_.TypeToString -eq 'VMware Backup' } 13 | 14 | $AllRestorePointsObject = @() 15 | 16 | foreach ($CurrentBackup in $VMBackups) { 17 | 18 | $RestorePoints = $CurrentBackup | Get-VBRRestorePoint 19 | 20 | $Storages = $CurrentBackup.GetAllStorages() 21 | 22 | foreach ($CurrentRestorePoint in $RestorePoints) { 23 | 24 | if ($CurrentRestorePoint.Info.IsConsistent) { 25 | $Status = 'Successful' 26 | } 27 | if ($CurrentRestorePoint.Info.IsCorrupted) { 28 | $Status = 'Corrupted' 29 | } 30 | if ($CurrentRestorePoint.Info.IsRecheckCorrupted) { 31 | $Status = 'FailedHealthCheck' 32 | } 33 | 34 | 35 | $StorageFile = $Storages | Where-Object { $_.Id -eq $CurrentRestorePoint.StorageId } 36 | $FileName = ($StorageFile.PartialPath.Internal.Elements[0]) 37 | 38 | $CurrentBackupOutputObject = New-Object PSObject -Property @{ 39 | 40 | 'Hostname' = $CurrentRestorePoint.Name 41 | 'CreationTime' = $CurrentRestorePoint.CreationTime 42 | 'Job Name' = $CurrentBackup.JobName 43 | 'BackupSize(GB)' = [math]::Round(($StorageFile.Stats.BackupSize / 1GB), 4) 44 | 'DataSize(GB)' = [math]::Round(($StorageFile.Stats.DataSize / 1GB), 4) 45 | 'Full/Inc' = $CurrentRestorePoint.Algorithm 46 | 'Status' = $Status 47 | 'Job Type' = $CurrentBackup.TypeToString 48 | 'FileName' = $FileName 49 | 'IsAvailable' = $StorageFile.IsAvailable 50 | 'FilePath' = $StorageFile.FilePath 51 | } 52 | 53 | $AllRestorePointsObject += $CurrentBackupOutputObject 54 | 55 | Remove-Variable -Name CurrentBackupOutputObject -ErrorAction SilentlyContinue 56 | 57 | } #end foreach CurrentRestorePoint 58 | 59 | } #end foreach CurrentBackup 60 | 61 | Disconnect-VBRServer 62 | Remove-PSSnapin -Name VeeamPSSnapIn 63 | 64 | Write-Output $AllRestorePointsObject 65 | 66 | -------------------------------------------------------------------------------- /Session1/4_VeeamBackupSize_Quick.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 4 2 | #Requires -RunAsAdministrator 3 | <# 4 | .Synopsis 5 | Simple Veeam report to expand on information from 'Veeam Backup Billing' report in VeeamOne 6 | .Notes 7 | Version: 0.2 8 | Author: Joe Houghes 9 | Modified Date: 5-19-2020 10 | .EXAMPLE 11 | Get-VeeamBackupSize | Format-Table 12 | .EXAMPLE 13 | Get-VeeamBackupSize | Export-Csv VeeamBackupSize.csv -NoTypeInformation 14 | #> 15 | 16 | function Get-VeeamBackupSize { 17 | [CmdletBinding()] 18 | param ( 19 | [string]$VBRServer = 'localhost', 20 | [double]$PriceGB = 0.15 21 | ) 22 | 23 | begin { 24 | 25 | #Load the Veeam PSSnapin 26 | if (!(Get-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue)) { 27 | Add-PSSnapin -Name VeeamPSSnapIn 28 | Connect-VBRServer -Server $VBRServer 29 | } 30 | 31 | else { 32 | Disconnect-VBRServer 33 | Connect-VBRServer -Server $VBRServer 34 | } 35 | 36 | } #end begin block 37 | 38 | process { 39 | 40 | $Repositories = Get-VBRBackupRepository 41 | $SOBRs = Get-VBRBackupRepository -ScaleOut 42 | 43 | [System.Collections.ArrayList]$RepositoryDetails = @() 44 | 45 | foreach ($Repo in $Repositories) { 46 | $RepoOutput = [PSCustomObject] @{ 47 | 'Name' = $Repo.Name 48 | 'ID' = $Repo.ID 49 | 'PerVM' = [bool]($Repo.Options.OneBackupFilePerVm) 50 | } 51 | $null = $RepositoryDetails.Add($RepoOutput) 52 | Remove-Variable RepoOutput 53 | } #end foreach Repositories 54 | 55 | foreach ($Repo in $SOBRs) { 56 | $RepoOutput = [PSCustomObject] @{ 57 | 'Name' = $Repo.Name 58 | 'ID' = $Repo.ID 59 | 'PerVM' = [bool]($Repo | Get-VBRRepositoryExtent | Select-Object -ExpandProperty $_.Repository.Options.OneBackupFilePerVm -Unique) 60 | } 61 | $null = $RepositoryDetails.Add($RepoOutput) 62 | Remove-Variable RepoOutput 63 | } #end foreach SOBRs 64 | 65 | [System.Collections.ArrayList]$ReportJobOutput = @() 66 | 67 | $ReportJobs = Get-VBRJob -WarningAction SilentlyContinue | Where-Object { $PSItem.JobType -eq 'Backup' -OR $PSItem.JobType -eq 'BackupSync' -AND $PSItem.BackupPlatform.Platform -eq 'EVmware' } 68 | 69 | foreach ($ReportJob in $ReportJobs) { 70 | 71 | #Get Backups & VMs in Job 72 | $CurrentBackup = Get-VBRBackup -Name $ReportJob.Name 73 | $CurrentJobVMs = $ReportJob.GetViOijs() | Select-Object Name, ObjectId 74 | 75 | #Get all backup files associated with backup job 76 | $CurrentJobStorage = $CurrentBackup.GetAllStorages() | Select-Object Id, CreationTime, @{n = 'BackupSize'; e = { $PSItem.Stats.BackupSize } } 77 | 78 | #Check if backup is on a per-VM repository, if so calculate files as per VM backup sizes 79 | if ([bool]($RepositoryDetails | Where-Object -Property Id -eq -Value $CurrentBackup.RepositoryId | Select-Object -ExpandProperty PerVM)) { 80 | 81 | $CurrentRestorePoints = $CurrentBackup | Get-VBRRestorePoint | Select-Object VMName, StorageId 82 | 83 | foreach ($CurrentJobStorageFile in $CurrentJobStorage) { 84 | $BackupSizeGB = [math]::round(($CurrentJobStorageFile.BackupSize / 1GB), 2) 85 | 86 | $ReportJobOutputObject = [PSCustomObject] @{ 87 | 'BackupJob' = $ReportJob.Name 88 | 'VMName' = $($CurrentRestorePoints | Where-Object Storageid -EQ $CurrentJobStorageFile.id | Select-Object -ExpandProperty VMName) 89 | 'Timestamp' = $CurrentJobStorageFile.CreationTime 90 | 'BackupSize(GB)' = $BackupSizeGB 91 | 'BackupCost($)' = [math]::round(($BackupSizeGB * $PriceGB), 2) 92 | } #end ReportJobOutputObject 93 | 94 | $null = $ReportJobOutput.Add($ReportJobOutputObject) 95 | 96 | } # end foreach StorageFile 97 | 98 | } #end if 99 | 100 | else { 101 | foreach ($CurrentJobStorageFile in $CurrentJobStorage) { 102 | $BackupSizeGB = [math]::round(($CurrentJobStorageFile.BackupSize / 1GB), 2) 103 | $numVMs = @($CurrentJobVMs).count 104 | 105 | if ($numVMs -eq '1') { 106 | $VMName = $CurrentJobVMs | Select-Object -ExpandProperty Name 107 | } 108 | 109 | else { $VMName = "$numVMs VM(s)" } 110 | 111 | $ReportJobOutputObject = [PSCustomObject] @{ 112 | 'BackupJob' = $ReportJob.Name 113 | 'VMName' = $VMName 114 | 'Timestamp' = $CurrentJobStorageFile.CreationTime 115 | 'BackupSize(GB)' = $BackupSizeGB 116 | 'BackupCost($)' = [math]::round(($BackupSizeGB * $PriceGB), 2) 117 | } #end ReportJobOutputObject 118 | 119 | $null = $ReportJobOutput.Add($ReportJobOutputObject) 120 | 121 | } # end foreach StorageFile 122 | 123 | } #end else 124 | 125 | } #endforeach Job 126 | 127 | } #end process block 128 | 129 | end { 130 | 131 | Write-Output $ReportJobOutput 132 | 133 | } #end end block 134 | 135 | } #end function 136 | -------------------------------------------------------------------------------- /Session1/4_VeeamBackupSize_Slow.ps1: -------------------------------------------------------------------------------- 1 | [string]$VBRServer = 'ausveeambr' 2 | [double]$PriceGB = 0.15 3 | 4 | #Load the Veeam PSSnapin 5 | if (!(Get-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue)) { 6 | Add-PSSnapin -Name VeeamPSSnapIn 7 | Connect-VBRServer -Server $VBRServer 8 | } 9 | 10 | else { 11 | Disconnect-VBRServer 12 | Connect-VBRServer -Server $VBRServer 13 | } 14 | 15 | $Repositories = Get-VBRBackupRepository 16 | $SOBRs = Get-VBRBackupRepository -ScaleOut 17 | 18 | $RepositoryDetails = @() 19 | 20 | foreach ($Repo in $Repositories) { 21 | $RepoOutput = New-Object -TypeName PSCustomObject -Property @{ 22 | 'Name' = $Repo.Name 23 | 'ID' = $Repo.ID 24 | 'PerVM' = [bool]($Repo.Options.OneBackupFilePerVm) 25 | } 26 | $RepositoryDetails += $RepoOutput 27 | Remove-Variable RepoOutput 28 | } #end foreach Repositories 29 | 30 | foreach ($Repo in $SOBRs) { 31 | $RepoOutput = New-Object -TypeName PSCustomObject -Property @{ 32 | 'Name' = $Repo.Name 33 | 'ID' = $Repo.ID 34 | 'PerVM' = [bool]($Repo | Get-VBRRepositoryExtent | Select-Object -ExpandProperty $_.Repository.Options.OneBackupFilePerVm -Unique) 35 | } 36 | $RepositoryDetails += $RepoOutput 37 | Remove-Variable RepoOutput 38 | } #end foreach SOBRs 39 | 40 | $ReportJobOutput = @() 41 | 42 | $ReportJobs = Get-VBRJob -WarningAction SilentlyContinue | Where-Object { $PSItem.JobType -eq 'Backup' -OR $PSItem.JobType -eq 'BackupSync' -AND $PSItem.BackupPlatform.Platform -eq 'EVmware' } 43 | 44 | foreach ($ReportJob in $ReportJobs) { 45 | 46 | #Get Backups & VMs in Job 47 | $CurrentBackup = Get-VBRBackup -Name $ReportJob.Name 48 | $CurrentJobVMs = $ReportJob | Get-VBRJobObject | Where-Object { $_.Object.Type -eq 'VM' -AND $_.Object.Platform.Platform -eq 'EVmware' } | Select-Object Name, ObjectId 49 | 50 | #Get all backup files associated with backup job 51 | $CurrentJobStorage = $CurrentBackup.GetAllStorages() | Select-Object Id, CreationTime, @{n = 'BackupSize'; e = { $PSItem.Stats.BackupSize } } 52 | 53 | #Check if backup is on a per-VM repository, if so calculate files as per VM backup sizes 54 | if ([bool]($RepositoryDetails | Where-Object -Property Id -eq -Value $CurrentBackup.RepositoryId | Select-Object -ExpandProperty PerVM)) { 55 | 56 | $CurrentRestorePoints = $CurrentBackup | Get-VBRRestorePoint | Select-Object VMName, StorageId 57 | 58 | foreach ($CurrentJobStorageFile in $CurrentJobStorage) { 59 | $BackupSizeGB = [math]::round(($CurrentJobStorageFile.BackupSize / 1GB), 2) 60 | 61 | $ReportJobOutputObject = New-Object -TypeName PSCustomObject -Property @{ 62 | 'BackupJob' = $ReportJob.Name 63 | 'VMName' = $($CurrentRestorePoints | Where-Object Storageid -EQ $CurrentJobStorageFile.id | Select-Object -ExpandProperty VMName) 64 | 'Timestamp' = $CurrentJobStorageFile.CreationTime 65 | 'BackupSize(GB)' = $BackupSizeGB 66 | 'BackupCost($)' = [math]::round(($BackupSizeGB * $PriceGB), 2) 67 | } #end ReportJobOutputObject 68 | 69 | $ReportJobOutput += $ReportJobOutputObject 70 | 71 | } # end foreach StorageFile 72 | 73 | } #end if 74 | 75 | else { 76 | foreach ($CurrentJobStorageFile in $CurrentJobStorage) { 77 | $BackupSizeGB = [math]::round(($CurrentJobStorageFile.BackupSize / 1GB), 2) 78 | $numVMs = @($CurrentJobVMs).count 79 | 80 | if ($numVMs -eq '1') { 81 | $VMName = $CurrentJobVMs | Select-Object -ExpandProperty Name 82 | } 83 | 84 | else { $VMName = "$numVMs VM(s)" } 85 | 86 | $ReportJobOutputObject = New-Object -TypeName PSCustomObject -Property @{ 87 | 'BackupJob' = $ReportJob.Name 88 | 'VMName' = $VMName 89 | 'Timestamp' = $CurrentJobStorageFile.CreationTime 90 | 'BackupSize(GB)' = $BackupSizeGB 91 | 'BackupCost($)' = [math]::round(($BackupSizeGB * $PriceGB), 2) 92 | } #end ReportJobOutputObject 93 | 94 | $ReportJobOutput += $ReportJobOutputObject 95 | 96 | } # end foreach StorageFile 97 | 98 | } #end else 99 | 100 | } #endforeach Job 101 | 102 | 103 | Write-Output $ReportJobOutput | Select-Object 'BackupJob', 'VMName', 'Timestamp', 'BackupSize(GB)', 'BackupCost($)' 104 | 105 | -------------------------------------------------------------------------------- /Session1/5_ProtectionScopeGroupJob.ps1: -------------------------------------------------------------------------------- 1 | #Options & credentials to be modified per scope/backup job 2 | $FilePath = '\\fileserver\share\file.csv' 3 | $Repository = Get-VBRBackupRepository -Name 'RepositoryName' #-Scaleout #uncomment this parameter if scale-out repository 4 | $DailyBackup = New-VBRDailyOptions -DayOfWeek Friday -Period 21:00 5 | $BackupSchedule = New-VBRServerScheduleOptions -Type 'Daily' -DailyOptions $DailyBackup 6 | 7 | #Get existing Master Windows credential 8 | $MasterWindowsCredentialUsername = 'FSGLAB\svc_veeam_bkup' 9 | $MasterWindowsCredentialDescription = 'Veeam Backup Access to member servers' 10 | $VeeamMasterWindowsCredential = Get-VBRCredentials -Name $MasterWindowsCredentialUsername | Where-Object Description -eq $MasterWindowsCredentialDescription 11 | 12 | #Get existing credential for fileshare access 13 | $FileshareCredentialUsername = 'FSGLAB\svc_veeam_bkup' 14 | $FileshareCredentialDescription = 'Veeam Backup Access to member servers' 15 | $VeeamFileshareCredential = Get-VBRCredentials -Name $FileshareCredentialUsername | Where-Object Description -eq $FileshareCredentialDescription 16 | 17 | #Create schedule for 1-hour discovery cycle 18 | $Periodically = New-VBRPeriodicallyOptions -FullPeriod 1 -PeriodicallyKind Hours 19 | $Schedule = New-VBRProtectionGroupScheduleOptions -PolicyType Periodically -PeriodicallyOptions $Periodically 20 | 21 | #Create CSV container when all hosts using master credential 22 | $CSVScope = New-VBRCSVContainer -Path $FilePath -MasterCredentials $VeeamMasterWindowsCredential -NetworkCredentials $VeeamFileshareCredential 23 | 24 | #Create protection group from CSV container, set discovery cycle: 25 | $ProtGroup = Add-VBRProtectionGroup -Name 'CSV' -Container $CSVScope -ScheduleOptions $Schedule 26 | 27 | #Create agent backup job for scope targeting CSV file, enable scheduling, 14 restore points, and set target backup repository 28 | #Assuming no options selected for indexing, deleted computer retention, notification, compact of full backup, 29 | #health check, active/synthetic full, storage (compression & dedupe), custom scripts during job 30 | Add-VBRComputerBackupJob -OSPlatform 'Windows' -Type 'Server' -Mode 'ManagedByBackupServer' -BackupObject $ProtGroup -BackupType 'EntireComputer' -EnableSchedule 31 | -------------------------------------------------------------------------------- /Session1/6_API_Backup_Session_Report.ps1: -------------------------------------------------------------------------------- 1 | #API_Backup_Session_Report 2 | Add-Type @" 3 | using System.Net; 4 | using System.Security.Cryptography.X509Certificates; 5 | public class TrustAllCertsPolicy : ICertificatePolicy { 6 | public bool CheckValidationResult( 7 | ServicePoint srvPoint, X509Certificate certificate, 8 | WebRequest request, int certificateProblem) { 9 | return true; 10 | } 11 | } 12 | "@ 13 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy 14 | 15 | $server = 'ausveeambem' 16 | $username = 'svc_veeam_api' 17 | $password = 'S3cr3tsquirr3!' 18 | $JobName = 'AUSVCENTER-NoTag' 19 | $report_filepath = 'D:\Demos\Session1\api_backup_session_report_05262020_Name.csv' 20 | 21 | #get the api 22 | $r_api = Invoke-WebRequest -Method Get -Uri "https://$($server):9398/api/" 23 | $r_api_xml = [xml]$r_api.Content 24 | $r_api_links = @($r_api_xml.EnterpriseManager.SupportedVersions.SupportedVersion | Where-Object { $_.Name -eq "v1_5" })[0].Links 25 | 26 | #login 27 | $securepassword = ConvertTo-SecureString -String $password -AsPlainText -Force 28 | $api_credential = [pscredential]::new($username, $securepassword) 29 | $r_login = Invoke-WebRequest -method Post -Uri $r_api_links.Link.Href -Credential $api_credential 30 | 31 | $sessionheadername = "X-RestSvcSessionId" 32 | $sessionid = $r_login.Headers[$sessionheadername] 33 | 34 | #content 35 | $r_login_xml = [xml]$r_login.Content 36 | $r_login_links = $r_login_xml.LogonSession.Links.Link 37 | $r_login_links_base = $r_login_links | Where-Object { $_.Type -eq 'EnterpriseManager' } 38 | 39 | #get list of all backup jobs 40 | $r_jobs_query = $r_login_links_base.Href + 'query?type=Job&filter=JobType==Backup' 41 | 42 | $r_jobs_query_name = $r_login_links_base.Href + 'query?type=Job&filter=JobType==Backup;Name=="' + $JobName + '"' 43 | $r_jobs_name = Invoke-WebRequest -Method Get -Headers @{$sessionheadername = $sessionid } -Uri $r_jobs_query_name 44 | $r_jobs_name_xml = [xml]$r_jobs_name.Content 45 | $r_jobs_name_list = $r_jobs_name_xml.QueryResult.Refs.Ref.Href 46 | 47 | #gather backup session entities 48 | $r_backup_session_entity_list = @() 49 | $r_backup_session_link = Invoke-WebRequest -Method Get -Headers @{$sessionheadername = $sessionid } -Uri $(($r_jobs_name_list) + "/backupSessions") 50 | $r_backup_session_link_xml = [xml]$r_backup_session_link.Content 51 | $r_backup_session_entity_list = $r_backup_session_link_xml.EntityReferences.Ref.Links.Link | Where-Object Type -eq 'BackupJobSession' | Select-Object -ExpandProperty Href 52 | 53 | #gather task sessions 54 | foreach ($r_backup_session_entity in $r_backup_session_entity_list) { 55 | $r_backup_session_entity_link = Invoke-WebRequest -Method Get -Headers @{$sessionheadername = $sessionid } -Uri $r_backup_session_entity 56 | $r_backup_session_entity_link_xml = [xml]$r_backup_session_entity_link 57 | $r_task_session_ref = $r_backup_session_entity_link_xml.BackupJobSession.Links.Link | Where-Object Type -eq BackupTaskSessionReferenceList | Select-Object -ExpandProperty Href 58 | $r_task_session_link = Invoke-WebRequest -Method Get -Headers @{$sessionheadername = $sessionid } -Uri $r_task_session_ref 59 | $r_task_session_link_xml = [xml]$r_task_session_link 60 | $r_task_session_list = $r_task_session_link_xml.EntityReferences.Ref.Href 61 | 62 | #gather task session details 63 | foreach ($r_task_session in $r_task_session_list) { 64 | $r_task_session_entity = $($r_task_session + "?format=Entity") 65 | $r_task_session_entity_link = Invoke-WebRequest -Method Get -Headers @{$sessionheadername = $sessionid } -Uri $r_task_session_entity 66 | $r_task_session_entity_link_xml = [xml]$r_task_session_entity_link 67 | $r_task_session_detail = $r_task_session_entity_link_xml.BackupTaskSession 68 | 69 | #gather VM restore points 70 | $r_vm_restore_point_link = ($r_task_session_entity_link_xml.BackupTaskSession.Links.Link | Where-Object Type -eq VmRestorePoint) 71 | 72 | #gather VM restore point entities & details 73 | if ([bool]$r_vm_restore_point_link) { 74 | $r_vm_restore_point_entity_link = $r_vm_restore_point_link | Select-Object -ExpandProperty Href 75 | $r_vm_restore_point_entity = Invoke-WebRequest -Method Get -Headers @{$sessionheadername = $sessionid } -Uri $r_vm_restore_point_entity_link 76 | $r_vm_restore_point_entity_xml = [xml]$r_vm_restore_point_entity 77 | $r_vm_restore_point_entity_detail = $r_vm_restore_point_entity_xml.VmRestorePoint 78 | 79 | #VM name & task session details 80 | $backup_session_detail = [PSCustomObject] @{ 81 | 'VMName' = $r_vm_restore_point_entity_detail.VMName 82 | 'BackupCreationTime(UTC)' = $r_task_session_detail.CreationTimeUTC 83 | 'BackupEndTime(UTC)' = $r_task_session_detail.EndTimeUTC 84 | 'State' = $r_task_session_detail.State 85 | 'Result' = $r_task_session_detail.Result 86 | 'Reason' = $r_task_session_detail.Reason 87 | } 88 | 89 | Write-Output $backup_session_detail | Export-Csv -Path $report_filepath -NoTypeInformation -Append 90 | 91 | } 92 | 93 | } 94 | 95 | } 96 | 97 | #logout 98 | $logofflink = $r_login_xml.LogonSession.Links.Link | Where-Object { $_.type -match "LogonSession" } 99 | Invoke-WebRequest -Method Delete -Headers @{$sessionheadername = $sessionid } -Uri $logofflink.Href 100 | -------------------------------------------------------------------------------- /Session1/7_FindCmdletsByParameterType.ps1: -------------------------------------------------------------------------------- 1 | Get-VBRJob -WarningAction SilentlyContinue | Get-Member 2 | 3 | (Get-VBRJob -WarningAction SilentlyContinue)[0].GetType() 4 | 5 | Get-Command -ParameterType CBackupJob 6 | 7 | Get-Command -ParameterType CBackupJob -Verb Add 8 | 9 | Get-Command -ParameterType CBackupJob -Verb Set 10 | -------------------------------------------------------------------------------- /Session1/8_ExportVeeamTypes&Methods.ps1: -------------------------------------------------------------------------------- 1 | [appdomain]::CurrentDomain.GetAssemblies() 2 | 3 | Add-PSSnapin -Name VeeamPSSnapIn 4 | 5 | [appdomain]::CurrentDomain.GetAssemblies() 6 | 7 | $Assemblies = [appdomain]::CurrentDomain.GetAssemblies() 8 | 9 | $Assemblies 10 | 11 | $Assemblies | Where-Object { $_.Location -Match 'Veeam' } 12 | 13 | $VeeamAssemblies = $Assemblies | Where-Object { $_.Location -Match 'Veeam' } 14 | 15 | $VeeamAssemblies 16 | 17 | $VeeamAssemblies.GetType() 18 | 19 | $VeeamTypes = ($VeeamAssemblies).GetTypes() 20 | 21 | $VeeamTypes 22 | 23 | foreach ($CurrentAssembly in $VeeamAssemblies) { 24 | 25 | try { 26 | $Types = $CurrentAssembly.GetTypes() 27 | $Types | Export-Csv 'D:\Demos\Session1\Veeam_v10_Types.csv' -NoTypeInformation -Append 28 | 29 | $Methods = $Types.GetMethods() 30 | $Methods | Export-Csv 'D:\Demos\Session1\Veeam_v10_TypeMethods.csv' -NoTypeInformation -Append 31 | 32 | } 33 | 34 | catch { 35 | Write-Output "$($CurrentAssembly.Location) failed" 36 | } 37 | 38 | } 39 | 40 | Invoke-Item 'D:\Demos\Session1\Veeam_v10_Types.csv' 41 | Invoke-Item 'D:\Demos\Session1\Veeam_v10_TypeMethods.csv' 42 | -------------------------------------------------------------------------------- /Session1/9_Dump-VBRObject.ps1: -------------------------------------------------------------------------------- 1 | Add-PSSnapin -Name VeeamPSSnapIn 2 | 3 | #alter function if you want different location 4 | function mdfile { 5 | param($name) 6 | return ("{0}\{1}.md" -f [Environment]::GetFolderPath("Desktop"),$name) 7 | } 8 | $dumpfile = (mdfile -name "README") 9 | 10 | function Dump-VBRObject { 11 | param($object,[int]$level=0,[string]$header="",[String[]]$objectcode=@(),$prefix="$opt.",[System.Text.StringBuilder]$sb,[System.Text.StringBuilder]$issue,[String[]]$blacklist,[String[]]$blacklisttype,$func=$false,$emitval=$false) 12 | if ($level -eq 0) { 13 | 14 | [void]$sb.AppendLine(("# {0}" -f $header)) 15 | if ($objectcode.Length -gt 0) { 16 | [void]$sb.AppendLine(('``` powershell')) 17 | foreach($c in $objectcode) { 18 | [void]$sb.AppendLine(("{0}" -f $c)) 19 | } 20 | [void]$sb.AppendLine(('```')) 21 | } 22 | } 23 | if ($level -gt 6) { 24 | [void]$issue.AppendLine("Detected to deep level with $prefix") 25 | return 26 | 27 | #don't hang forever 28 | } 29 | 30 | if ($object -ne $null) { 31 | $ident = "" 32 | for ($i=0;$i -lt $level;$i++) { $ident = $ident + " " } 33 | 34 | if ($func) { 35 | $funcs = $object | gm -MemberType Method 36 | foreach ($f in $funcs) { 37 | if ($f.Name -notin $blacklist -and -not ($f.Name -match "^To")) { 38 | [void]$sb.AppendLine(("* {1}.{2}() Def [{3}]" -f $ident,$prefix,$f.Name,$f.Definition )) 39 | } 40 | } 41 | } 42 | 43 | $members = $object | gm -MemberType Property | % { $_.Name } 44 | 45 | 46 | foreach ($member in $members) 47 | { 48 | 49 | $memreal = $null 50 | 51 | $t = "`$null" 52 | try { 53 | $t = ""+$object.$member.GetType().Fullname 54 | } catch {} 55 | 56 | $memreal = $($object."$member") 57 | if($memreal) { 58 | [void]$sb.AppendLine(("* {1}.{2} \[{3}\]" -f $ident,$prefix,$member,$t )) 59 | if($emitval) { [void]$sb.AppendLine((" * Live Value : {1}" -f $ident,$memreal)) } 60 | 61 | if ($member -notin $blacklist -and $t -notin $blacklisttype) { 62 | Dump-VBRObject -object $memreal -level $($level+1) -prefix ("{0}.{1}" -f $prefix,$member) -sb $sb -issue $issue -blacklist $blacklist -func $func -emitval $emitval -blacklisttype $blacklisttype 63 | } 64 | 65 | } else { 66 | 67 | [void]$sb.AppendLine(("* {1}.{2} \[{3}\] \(`$null\)" -f $ident,$prefix,$member,$t)) 68 | if($emitval) { [void]$sb.AppendLine((" * Live Value : `$null" -f $ident)) } 69 | } 70 | 71 | 72 | } 73 | } else { 74 | [void]$issue.AppendLine(("Error with $prefix at level $level ")) 75 | 76 | } 77 | if($level -eq 0) { [void]$sb.AppendLine("");[void]$sb.AppendLine("")} 78 | } 79 | 80 | $sb = New-Object -TypeName "System.Text.StringBuilder"; 81 | [void]$sb.AppendLine((@" 82 | # Dumper script as quick powershell reference 83 | ## VeeamHub 84 | Veeamhub projects are community driven projects, and are not created by Veeam R&D nor validated by Veeam Q&A. They are maintained by community members which might be or not be Veeam employees. 85 | ## Distributed under MIT license 86 | Copyright (c) 2016 VeeamHub 87 | 88 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 89 | 90 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 91 | 92 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 93 | 94 | ## Project Notes 95 | **Author:** Timothy Dewin @tdewin 96 | 97 | **Function:** Dumps all methods/properties for joboptions and backups 98 | 99 | **Requires:** VBR 9.x 100 | 101 | **Usage:** Dump-VBRObjects.ps1 102 | 103 | **Parameters:** Not Applicable 104 | 105 | **Result:** Is actually this file 106 | 107 | ## QA 108 | 109 | **What is this strange syntax @(..)[0]** 110 | 111 | The code inside is executed and expected to return an array. For analysis, we only need one object thus we force the return value to be an array and take the first object. 112 | 113 | This does mean that you need to have actually one Job defined and have one Backup etc.. 114 | 115 | # Actual Dump 116 | Using VeeamPSSnapIn {0} 117 | 118 | "@ -f ((Get-PSSnapin -Name VeeamPSSnapin).PSVersion.ToString()))) 119 | 120 | 121 | 122 | 123 | $issue = New-Object -TypeName "System.Text.StringBuilder"; 124 | $blacklist = @("Date","Length","Equals","GetHashCode","GetTypeCode","GetType","ToString","CompareTo","value__","HasFlag") 125 | $blacklisttype = @("System.String","System.String[]","System.TimeSpan","System.Date","System.DateTime","System.Xml.XmlElement") 126 | 127 | 128 | 129 | $dumps = @() 130 | $dumps += New-Object -TypeName psobject -Property @{ 131 | Prefix="VBRJob"; 132 | ObjectCode=@('$VBRJob = @(Get-VBRJob)[0]'); 133 | } 134 | $dumps += New-Object -TypeName psobject -Property @{ 135 | Prefix="VBRJobObject"; 136 | ObjectCode=@('$job = @(Get-VBRJob | where { $_.JobType -eq "Backup" })[0]','$VBRJobObject = Get-VBRJobObject -job $job'); 137 | } 138 | $dumps += New-Object -TypeName psobject -Property @{ 139 | Prefix="VBRJobOptions"; 140 | ObjectCode=@('$job = @(Get-VBRJob | where { $_.JobType -eq "Backup" })[0]','$VBRJobOptions = Get-VBRJobOptions -job $job'); 141 | } 142 | $dumps += New-Object -TypeName psobject -Property @{ 143 | Prefix="VBRJobScheduleOptions"; 144 | ObjectCode=@('$job = @(Get-VBRJob | where { $_.JobType -eq "Backup" })[0]','$VBRJobScheduleOptions = Get-VBRJobScheduleOptions -job $job'); 145 | } 146 | $dumps += New-Object -TypeName psobject -Property @{ 147 | Prefix="VBRJobVSSOptions"; 148 | ObjectCode=@('$job = @(Get-VBRJob | where { $_.JobType -eq "Backup" })[0]','$VBRJobVSSOptions = Get-VBRJobVSSOptions -job $job'); 149 | } 150 | $dumps += New-Object -TypeName psobject -Property @{ 151 | Prefix="VBRJobObjectVssOptions"; 152 | ObjectCode=@('$job = @(Get-VBRJob | where { $_.JobType -eq "Backup" })[0]','$JobObject = @(Get-VBRJobObject -job $Job)[0]','$VBRJobObjectVssOptions = Get-VBRJobObjectVssOptions -ObjectInJob $JobObject'); 153 | } 154 | $dumps += New-Object -TypeName psobject -Property @{ 155 | Prefix="VBRBackup"; 156 | ObjectCode=@('$VBRBackup = @(Get-VBRBackup)[0]'); 157 | } 158 | $dumps += New-Object -TypeName psobject -Property @{ 159 | Prefix="VBRBackupStorage"; 160 | ObjectCode=@('$VBRBackup = @(Get-VBRBackup)[0]','$VBRBackupStorage = @($VBRBackup.GetAllStorages())[0]'); 161 | } 162 | $dumps += New-Object -TypeName psobject -Property @{ 163 | Prefix="VBRBackupPoint"; 164 | ObjectCode=@('$VBRBackup = @(Get-VBRBackup)[0]','$VBRBackupPoint = @($VBRBackup.GetPoints())[0]'); 165 | } 166 | $dumps += New-Object -TypeName psobject -Property @{ 167 | Prefix="VBRRestorePoint"; 168 | ObjectCode=@('$VBRBackup = @(Get-VBRBackup)[0]','$VBRRestorePoint = @($VBRBackup | Get-VBRRestorePoint )[0]'); 169 | } 170 | $dumps += New-Object -TypeName psobject -Property @{ 171 | Prefix="VBRBackupSession"; 172 | ObjectCode=@('$VBRBackupSession = @(Get-VBRBackupSession | ? {$_.JobType -eq "Backup"})[0]'); 173 | } 174 | $dumps += New-Object -TypeName psobject -Property @{ 175 | Prefix="VBRBackupSessionTaskSession"; 176 | ObjectCode=@('$VBRBackupSession = @(Get-VBRBackupSession | ? {$_.JobType -eq "Backup"})[0]','$VBRBackupSessionTaskSession = @($VBRBackupSession.GetTaskSessions())[0]'); 177 | } 178 | 179 | 180 | 181 | foreach ($dump in $dumps | Sort Prefix) { 182 | $sbfile = New-Object -TypeName "System.Text.StringBuilder"; 183 | $dump.ObjectCode | % { 184 | invoke-expression $_ 185 | } 186 | Invoke-Expression ('$o = ${0}' -f $dump.Prefix) 187 | 188 | if ($o -ne $null) { 189 | Dump-VBRObject -object $o -header ("{0} [{1}]" -f $dump.Prefix,$o.GetType().Fullname) -objectcode $dump.ObjectCode -prefix ("`${0}" -f $dump.Prefix) -sb $sbfile -issue $issue -blacklist $blacklist -func $true -blacklisttype $blacklisttype 190 | 191 | $fname = (mdfile -name $dump.Prefix) 192 | $sbfile.ToString() | Out-File -FilePath $fname -Encoding utf8 193 | 194 | [void]$sb.AppendLine(("* [{0}](./{1}.md)" -f $dump.Prefix,$dump.Prefix)) 195 | } else { 196 | write-host "No object was really made for "$dump.Prefix 197 | } 198 | } 199 | 200 | 201 | $sb.ToString() | Out-File -FilePath $dumpfile -Encoding utf8 202 | -------------------------------------------------------------------------------- /Session1/Session1Scripts&Demos.md: -------------------------------------------------------------------------------- 1 | # Session 1 Scripts & Demos 2 | 3 | ## Demo 1 4 | 5 | This is a simple script to demonstrate creating a "shell" job within Veeam Backup & Replication. 6 | 7 | _NOTE:_ You must add a VM to a job at creation, then you can delete the job object afterwards. For this purpose, I typically target my VCSA (vCenter) VM, as I know that it will exist within the environment to add to the job. 8 | 9 | **__Additional Note:__** This method to create a "shell" job will still not get you around the requirement within the GUI for there to be a VM that exists within a job, similar to creating a job within PowerShell. You will need to avoid clicking the "Virtual Machines" tab on the job within the GUI, or else you will need to remove the job object again. 10 | 11 | ## Demo 2 12 | 13 | This is a simple script to gather some commonly requested details for your backups jobs, using both properties and methods of the Veeam jobs. 14 | 15 | It also leverages calculated properties to modify the named used to display toe objects' properties. 16 | 17 | ## Demo 3 18 | 19 | There are two nearly matching versions of this script, both with names ending in '_Quick' or '_Slow'. 20 | 21 | The slight difference in these scripts is to highlight the usage of these differing techniques within the script: 22 | 23 | _Slow_ - Uses a standard array (line 14) to hold our results, uses the "New-Object PSObject" method (line 38) of creating a custom object, and the "+=" logic (line 53) to add members to the array (each of our custom objects) 24 | 25 | _Quick_ - Uses a ArrayList (line 14) to hold our results, uses the "PSCustomObject" type accelerator (line 38) for creating a custom object, and the "Add" method of the ArrayList (line 53) to add members to the ArrayList (each of our custom objects) 26 | 27 | ## Demo 4 28 | 29 | There are two nearly matching versions of this script, both with names ending in '_Quick' or '_Slow'. 30 | 31 | The slight difference in these scripts is to highlight the usage of these differing techniques within the script: 32 | 33 | _Slow_ - Uses a standard array (lines 18,40) to hold our results, uses the "New-Object PSObject" method (lines 21, 31, 61) of creating a custom object, and the "+=" logic (lines 26, 36, 69, 94) to add members to the array (each of our custom objects) 34 | 35 | _Quick_ - Uses a ArrayList (line 43) to hold our results, uses the "PSCustomObject" type accelerator (lines, 46, 56, 86) for creating a custom object, and the "Add" method of the ArrayList (lines 51, 61, 94, 119) to add members to the ArrayList (each of our custom objects). The Quick script has also been formatted into a function, which can be loaded into memory by dot-sourcing the script or using the 'Import-Module' cmdlet. 36 | 37 | ## Script 5 38 | 39 | This script is a simple example of the workflow for creating a Veeam Computer backup job (new terminology for Agent job within PowerShell), which is built via a protection group managed via CSV file. 40 | 41 | The following required components are created in this walk-through: 42 | 43 | - Schedule options (lines 4 & 5) 44 | - Veeam Credentials (lines 8-10 for use on the hosts; lines 13-15 for the network share of the CSV file) 45 | - Protection Group Discovery Schedule (lines 18-19) 46 | - VBR CSV Container (line 22) 47 | - Protection Group (line 25) 48 | - Computer Backup Job (line 30) 49 | 50 | ## Script 6 51 | 52 | This script is a basic backup/task session report, which was created by simply walking through the Veeam Enterprise Manager API, in a similar method to performing the same process via PowerShell. 53 | 54 | _NOTE:_ This script is not intended to be an efficient method of querying the API, but rather an easy to follow walk-through to help give some correlation to our API for someone that understands the basics of Veeam PowerShell. 55 | 56 | ## Demo 7 57 | 58 | This is a simple example of showing how to determine the type of an object with PowerShell. 59 | 60 | With that information, we then leveraging the 'ParameterType' parameter of the "Get-Command" cmdlet. 61 | 62 | This will show what additional cmdlets will allow the source object as an input object on the PowerShell pipeline (pipeline binding by value) 63 | 64 | ## Demo 8 65 | 66 | This basic script shows you how to leverage some PowerShell code to get a CSV file export of both the Veeam objects types and available methods for those object types. 67 | 68 | _NOTE:_ You will need to change the file paths on lines 27 & 30 to an appropriate path for your system. 69 | 70 | ## Script 9 71 | 72 | The script shown on screen and references in the demo video can be found here: 73 | 74 | [BR-Dump-Object](https://github.com/VeeamHub/powershell/tree/master/BR-Dump-Object) 75 | 76 | ## Demo 10 77 | 78 | This simple script leverages the native "Get-CIMInstance" cmdlet (PowerShell v3+) to gather some of the Veeam general options from WMI on the Veeam Backup & Replication server. 79 | 80 | It also leverages the "Show-Object" cmdlet found in the [PowerShellCookbook](https://www.powershellgallery.com/packages/PowerShellCookbook/1.3.6) module on the PowerShell Gallery. 81 | 82 | ## Demo 11 83 | 84 | This script is a simple function which will connect to a Veeam Backup & Replication server and query for details of servers, proxies, repositories, scale-out repositories, scale-out extents, and jobs (limited details). 85 | 86 | It will then export each of these sets of details as a separate CSV file. 87 | 88 | ## Demo 12 89 | 90 | There are two versions of this script, both with names ending in '_Quick' or '_Slow'. However, in this instance, the scripts vary greatly. 91 | 92 | The primary difference in these scripts is to highlight the performance cost with using differing techniques within the script: 93 | 94 | _Slow_ - Gathers all Veeam backup jobs for VMware, then uses a foreach loop for each job, each backup session, then each task session to gather details about the task session. 95 | 96 | _Quick_ - Gathers all Veeam backup jobs for VMware, then gather all backup sessions, filters down to those matching our job IDs, and gather the task sessions for those filtered backup sessions. We then parse the details for each task session, but do not incur the cost of running queries at each level. 97 | 98 | ## Demo 13 99 | 100 | This script is a basic function to list out the disk filters for all VMware backup & backup copy jobs. 101 | 102 | It is meant to be a simple real-world example of demonstrating how some basic code can make it easier to confirm settings & ensure standardization against your environment, in a method that is quicker and easier than through the GUI. 103 | 104 | ## Demo 14 105 | 106 | This script came up as an example that was requested to find all VMs registered to a vCenter server which are not included within Veeam backups, with the caveat that both VM & tag objects are used within the Veeam jobs. 107 | 108 | This script leverages the "Get-VBRJobObject" and "Find-VBRViEntity" (along with some additional logic & filtering) to gather details of all VMs/tags within Veeam, then gathers the details of all VMs by name & by tag, to perform a comparison of all VMs & job objects. 109 | 110 | The results parsed by this script which are exported to CSV file include: 111 | 112 | - VMs not included within Veeam jobs 113 | - VMs included within Veeam jobs 114 | - VMs not included within Veeam backups 115 | - VMs included within Veeam backups 116 | 117 | These lists of VMs are also parsed to find the following details, exported to text file: 118 | 119 | - VMs duplicated within Veeam jobs 120 | - VMs duplicated within Veeam backups 121 | -------------------------------------------------------------------------------- /Session2/10_1_DeployAgentsbyIPRange-QueryVMs.ps1: -------------------------------------------------------------------------------- 1 | #User input for vCenter servername & credentials, along with IP network to match VMs against 2 | $vCenterHost = Read-Host -Prompt "Enter vCenter server name/IP" 3 | $vCenterCreds = Get-Credential -Message "Enter vCenter credentials" 4 | $IPNetwork = Read-Host -Prompt "Enter the network octets to match" 5 | 6 | #Filepath for CSV output 7 | $CSVoutputpath = '\\server\share\vmnames.csv' 8 | 9 | #Import the PowerCLI module & connect to vCenter 10 | Import-Module VMware.PowerCLI 11 | Connect-VIServer -Server $vCenterHost -Credential $vCenterCreds 12 | 13 | #Run Get-View for efficient query of VM objects 14 | $AllVMs = Get-View -ViewType VirtualMachine 15 | 16 | #Filter for VMs with non-Windows guest ID 17 | $LinuxVMs = $AllVMs | Where-Object {$_.Guest.GuestId -NotLike "*windows*"} 18 | 19 | #Query for VMs which match the IP network pattern and return their hostnames from guest OS 20 | $IPmatchVMs = $LinuxVMs | Where-Object {$_.Guest.Net.IPaddress -match $IPNetwork} 21 | $VMNames = $IPMatchVMs.Guest.Hostname 22 | 23 | #Output results to file 24 | $VMNames | Export-CSV -Path $CSVoutputpath -NoTypeInformation -------------------------------------------------------------------------------- /Session2/10_2_DeployAgentsbyIPRange-CreateProtectionGroup.ps1: -------------------------------------------------------------------------------- 1 | #Options & credentials to be modified per scope/backup job 2 | $FilePath = '\\server\share\vmnames.csv' 3 | $Repository = Get-VBRBackupRepository -Name 'RepositoryName' #-Scaleout #uncomment this parameter if scale-out repository 4 | $DailyBackup = New-VBRDailyOptions -DayOfWeek Friday -Period 21:00 5 | $BackupSchedule = New-VBRLinuxScheduleOptions -Type Daily -DailyOptions $DailyBackup 6 | 7 | #Get existing Master Windows credential 8 | $MasterLinuxCredentialUsername = 'svc_veeam_bk' 9 | $MasterLinuxCredentialDescription = 'Veeam Backup Access to Linux servers' 10 | $VeeamMasterLinuxCredential = Get-VBRCredentials -Name $MasterLinuxCredentialUsername | Where-Object Description -eq $MasterLinuxCredentialDescription 11 | 12 | #Get existing credential for fileshare access 13 | $FileshareCredentialUsername = 'FSGLAB\svc_veeam_bkup' 14 | $FileshareCredentialDescription = 'Veeam Backup Access to member servers' 15 | $VeeamFileshareCredential = Get-VBRCredentials -Name $FileshareCredentialUsername | Where-Object Description -eq $FileshareCredentialDescription 16 | 17 | #Create schedule for 1-hour discovery cycle 18 | $Periodically = New-VBRPeriodicallyOptions -FullPeriod 1 -PeriodicallyKind Hours 19 | $Schedule = New-VBRProtectionGroupScheduleOptions -PolicyType Periodically -PeriodicallyOptions $Periodically 20 | 21 | #Create CSV container when all hosts using master credential 22 | $CSVScope = New-VBRCSVContainer -Path $FilePath -MasterCredentials $VeeamMasterLinuxCredential -NetworkCredentials $VeeamFileshareCredential 23 | 24 | #Create protection group from CSV container, set discovery cycle: 25 | $ProtGroup = Add-VBRProtectionGroup -Name 'CSVbyIP' -Container $CSVScope -ScheduleOptions $Schedule 26 | 27 | #Create new computer destination options 28 | $Destination = New-VBRComputerDestinationOptions -OSPlatform Linux -BackupRepository $repository 29 | 30 | #Create agent backup job for scope targeting CSV file, enable scheduling, 14 restore points, and set target backup repository 31 | #Assuming no options selected for indexing, deleted computer retention, notification, compact of full backup, health check, active/synthetic full, storage (compression & dedupe), custom scripts during job 32 | Add-VBRComputerBackupJob -OSPlatform 'Linux' -Type 'Server' -Mode 'ManagedByAgent' -Name 'LinuxAgentBackup' -Description 'Agent Managed - Prot Group by IP'` 33 | -BackupObject $ProtGroup -BackupType 'EntireComputer' -DestinationOptions $Destination -ScheduleOptions $BackupSchedule -EnableSchedule` 34 | -RetentionPolicy '14' -BackupRepository $Repository 35 | 36 | -------------------------------------------------------------------------------- /Session2/11_Send-VeeamError.ps1: -------------------------------------------------------------------------------- 1 | function Send-VeeamError { 2 | [CmdletBinding()] 3 | param ( 4 | [Parameter(Mandatory = $true)] 5 | [ValidateNotNullOrEmpty()] 6 | [string]$FileToParse, 7 | 8 | [string]$Method = 'POST', 9 | 10 | $ContentType = "application/json", 11 | $APIKey = "%Insert API key here%", 12 | 13 | $headers = @{ 14 | 'content-type' = $ContentType; 15 | 'x-api-key' = $APIKey 16 | }, 17 | 18 | $CredentialKey = 'PSCredentialKey1', 19 | 20 | [System.Uri]$Uri = "%Insert API URI here%" 21 | ) 22 | 23 | begin { 24 | $ScriptPath = $PSScriptRoot 25 | Push-Location -Path $ScriptPath 26 | 27 | Import-Module .\PSJsonCredential\PSJsonCredential.psd1 28 | 29 | $parse = Get-Content $FileToParse 30 | 31 | $VBRServer = $parse[0].Replace('"', '') 32 | $VBRServer = $VBRServer -replace ' ' 33 | 34 | $CredentialFile = Get-ChildItem -Path .\Credentials\ -Filter "*$VBRServer*" 35 | $Credential = Import-PSCredentialFromJson -Path $CredentialFile.FullName -Key $CredentialKey 36 | 37 | $JobTypeCheck = $parse[3] 38 | 39 | $JobType = switch -Wildcard ($JobTypeCheck) { 40 | 'Fired by event: VeeamBpEpAgent*' { 'Agent' } 41 | 'Fired by event: VeeamBpBackup*' { 'Job' } 42 | } 43 | 44 | if ($JobType -eq 'Job') { 45 | $JobNameRegex = [regex]'\bEvent description. Job \b(.+)\b finished with error\. \b' 46 | $JobNameErrors = $parse[3] -match "$JobNameRegex" 47 | [string]$Summary = $Matches[0] 48 | 49 | if ($JobNameErrors) { 50 | [string]$JobName = $Matches[1] 51 | } 52 | 53 | } 54 | 55 | if ($JobType -eq 'Agent') { 56 | $JobNameRegex = [regex]'\bEvent description. Job \b(.+)\b finished with error\. \b' 57 | $JobNameErrors = $parse[3] -match "$JobNameRegex" 58 | 59 | if ($JobNameErrors) { 60 | [string]$JobName = ($Matches[1].split(' - '))[0] 61 | $stringreplace = $Matches[1].Replace("$JobName", '') 62 | [string]$Summary = $Matches[0].Replace($stringreplace, '') 63 | 64 | } 65 | 66 | } 67 | 68 | [string]$AlarmName = $($parse[1].Replace('"', '')) 69 | $TimeSplit = $parse[2].Split('_') 70 | $AlarmTime = ($TimeSplit[0].Replace('-', '/')) + ' ' + ($TimeSplit[1].Replace('-', ':')) 71 | 72 | $Session = New-PSSession -ComputerName $VBRServer -Credential $Credential -ConfigurationName microsoft.powershell #-UseSSL #(Uncomment for using SSL) 73 | 74 | } 75 | 76 | process { 77 | 78 | $ScriptBlock = { 79 | param($JobType, $JobName, $AlarmName, $AlarmTime, $Summary, $VBRServer) 80 | Add-PSSnapin -Name VeeamPSSnapin 81 | 82 | Connect-VBRServer 83 | $Job = Get-VBRJob -Name $JobName 84 | $BackupSession = $Job.FindLastSession() 85 | 86 | if ($JobType -eq 'Job') { 87 | $TaskSession = Get-VBRTaskSession -Session $BackupSession 88 | $FailedTasks = $TaskSession | Where-Object { $_.Status -eq 'Failed' } 89 | } 90 | 91 | if ($JobType -eq 'Agent') { 92 | $FailedTasks = $BackupSession.Logger.GetLog().UpdatedRecords | Where-Object { $_.Title -like '*Failed*' } | Select-Object Status, Title 93 | } 94 | 95 | [System.Collections.ArrayList]$AllTasksOutput = @() 96 | 97 | foreach ($Task in $FailedTasks) { 98 | 99 | if ($JobType -eq 'Job') { 100 | 101 | $TaskRegex = [regex]'\bCode: (\d+)' 102 | $TaskErrors = $Task.Info.Reason -match "$TaskRegex" 103 | if ($TaskErrors) { 104 | $ErrorCode = $Matches[1] 105 | } 106 | 107 | switch ($Task.Info.Status) { 108 | 'Warning' { $Status = 'Warning'; break } 109 | 'Failed' { $Status = 'Critical'; break } 110 | } 111 | 112 | $NodeName = $Task.Name 113 | } 114 | 115 | if ($JobType -eq 'Agent') { 116 | 117 | $ErrorCode = 'N/A-Agent' 118 | 119 | $TaskRegex = [regex]'\bProcessing \b(.+)\b Error: \b' 120 | $TaskErrors = $Task.Title -match "$TaskRegex" 121 | if ($TaskErrors) { 122 | $NodeName = $Matches[1] 123 | } 124 | 125 | switch ($Task.Status) { 126 | 'EWarning' { $Status = 'Warning'; break } 127 | 'EFailed' { $Status = 'Critical'; break } 128 | } 129 | 130 | } 131 | 132 | $TaskOutputResult = [pscustomobject] @{ 133 | 134 | 'job_name' = $Job.Name; 135 | 'backup_server' = $VBRServer; 136 | 'affected_node_name' = $NodeName; 137 | 'alarm_status' = $Job.GetLastResult(); 138 | 'host_status' = $Status; 139 | 'error_code' = $ErrorCode; 140 | 'alarm_name' = $AlarmName; 141 | 'alarm_time' = $AlarmTime; 142 | 'alarm_summary' = $Summary 143 | } 144 | 145 | $null = $AllTasksOutput.Add($TaskOutputResult) 146 | 147 | } 148 | 149 | Write-Output $AllTasksOutput 150 | 151 | } 152 | 153 | $AllTasksOutput = Invoke-Command -Session $Session -ScriptBlock $ScriptBlock -ArgumentList $JobType, $JobName, $AlarmName, $AlarmTime, $Summary, $VBRServer 154 | $SelectedOutput = $AllTasksOutput | Select-Object -Property 'affected_node_name', 'alarm_name', 'alarm_summary', 'alarm_status', 'job_name', 'host_status', 'error_code', 'alarm_time', 'backup_server' 155 | 156 | #$SelectedOutput | Export-Csv -Path .\Output.csv -NoTypeInformation 157 | 158 | } 159 | 160 | end { 161 | 162 | Remove-PSSession -Session $Session 163 | 164 | foreach ($TaskOutput in $SelectedOutput) { 165 | 166 | $TaskJson = $TaskOutput | ConvertTo-Json 167 | 168 | $props = @{ 169 | Uri = $Uri 170 | Headers = $Headers 171 | Method = $Method 172 | Body = $TaskJson 173 | } 174 | 175 | Invoke-RestMethod @props 176 | 177 | } 178 | 179 | } 180 | 181 | } 182 | -------------------------------------------------------------------------------- /Session2/12_NewBackupShellJob.ps1: -------------------------------------------------------------------------------- 1 | Add-PSSnapin -Name VeeamPSSnapIn 2 | Connect-VBRServer -Server ausveeambr.lab.fullstackgeek.net -User FSGLAB\VeeamPowerShell -Password 'S3cr3tsquirr3!' 3 | 4 | Get-VBRJob -WarningAction SilentlyContinue | Select-Object Name, Description 5 | 6 | #NewBackupShellJob 7 | $VeeamVBRServerName = 'ausveeambr.lab.fullstackgeek.net' 8 | $VeeamRepositoryName = 'ReFS-PerVM' 9 | $VeeamBackupJobName = 'VMs-Text-File' 10 | 11 | $vCenterServerName = 'ausvcenter.fsglab.local' 12 | $VMName = 'veeamv101' 13 | 14 | $Repository = Get-VBRBackupRepository -Name $VeeamRepositoryName 15 | $vCenterServer = Get-VBRServer -Name $vCenterServerName 16 | $VMtoAdd = Find-VBRViEntity -Name $VMName -Server $vCenterServer -VM 17 | 18 | #Create new shell backup job 19 | $VMText = Add-VBRViBackupJob -Name $VeeamBackupJobName -Description 'VMs via Text File' -BackupRepository $Repository -Entity $VMtoAdd 20 | $VMText | Get-VBRJobObject | Select-Object Name, TypeDisplayName, Type 21 | -------------------------------------------------------------------------------- /Session2/13_1_AddVMsFromTextFile.ps1: -------------------------------------------------------------------------------- 1 | #AddVMsFromTextFile 2 | $vCenterServerName = 'ausvcenter.fsglab.local' 3 | $VeeamBackupJobName = 'VMs-Text-File' 4 | $FileToParse = 'D:\Demos\veeamon2020\Session2\VMsFromTextFile\AddVMs.txt' 5 | 6 | #Read in text file 7 | $VMList = Get-Content -Path $FileToParse 8 | 9 | #Get Veeam job 10 | $BackupJob = Get-VBRJob -Name $VeeamBackupJobName 11 | 12 | #Show Job Objects 13 | $BackupJob | Get-VBRJobObject | Select-Object Name, TypeDisplayName, Type 14 | 15 | #Get vCenter connection object 16 | $vCenterServer = Get-VBRServer -Name $vCenterServerName 17 | 18 | #Loop through list of VM names and add each to backup job 19 | foreach ($VMtoAdd in $VMList){ 20 | $VMwareTarget = Find-VBRViEntity -Name $VMtoAdd -VM -Server $vCenterServer 21 | Add-VBRViJobObject -Job $BackupJob -Entities $VMwareTarget | Out-Null 22 | } 23 | 24 | #Show Job Objects 25 | $BackupJob | Get-VBRJobObject | Select-Object Name, TypeDisplayName, Type 26 | -------------------------------------------------------------------------------- /Session2/13_2_MaintenanceForVMsFromTextFile.ps1: -------------------------------------------------------------------------------- 1 | #MaintenanceForVMsFromTextFile 2 | $VeeamBackupJobName = 'VMs-Text-File' 3 | $FileToParse = 'D:\Demos\veeamon2020\Session2\VMsFromTextFile\MaintenanceVMs.txt' 4 | 5 | #Read in text file 6 | $VMList = Get-Content -Path $FileToParse 7 | 8 | #Get Veeam job 9 | $BackupJob = Get-VBRJob -Name $VeeamBackupJobName 10 | 11 | #Show Job Objects 12 | $BackupJob | Get-VBRJobObject | Select Name, TypeDisplayName, Type 13 | 14 | #Loop through list of VM names and set for maintenance in backup job 15 | foreach ($MaintenanceVM in $VMList){ 16 | $VMforMaintenance = Get-VBRJobObject -Job $BackupJob -Name $MaintenanceVM 17 | $VMforMaintenance | Remove-VBRJobObject | Out-Null 18 | } 19 | 20 | #Show Job Objects 21 | $BackupJob | Get-VBRJobObject | Select Name, TypeDisplayName, Type 22 | -------------------------------------------------------------------------------- /Session2/13_3_RemoveForVMsFromTextFile.ps1: -------------------------------------------------------------------------------- 1 | #RemoveForVMsFromTextFile 2 | $VeeamBackupJobName = 'VMs-Text-File' 3 | $FileToParse = 'D:\Demos\veeamon2020\Session2\VMsFromTextFile\RemoveVMs.txt' 4 | 5 | #Read in text file 6 | $VMList = Get-Content -Path $FileToParse 7 | 8 | #Get Veeam job & vCenter connection object 9 | $BackupJob = Get-VBRJob -Name $VeeamBackupJobName 10 | 11 | #Show Job Objects 12 | $BackupJob | Get-VBRJobObject | Select Name, TypeDisplayName, Type 13 | 14 | #Loop through list of VM names and add each to backup job 15 | foreach ($RemoveVM in $VMList){ 16 | $VMtoRemove = Get-VBRJobObject -Job $BackupJob -Name $RemoveVM 17 | $VMtoRemove | Remove-VBRJobObject -Completely | Out-Null 18 | } 19 | 20 | #Show Job Objects 21 | $BackupJob | Get-VBRJobObject | Select Name, TypeDisplayName, Type 22 | 23 | -------------------------------------------------------------------------------- /Session2/15_API_Quick_Backup.ps1: -------------------------------------------------------------------------------- 1 | #API_Start_Backup_Job 2 | Add-Type @" 3 | using System.Net; 4 | using System.Security.Cryptography.X509Certificates; 5 | public class TrustAllCertsPolicy : ICertificatePolicy { 6 | public bool CheckValidationResult( 7 | ServicePoint srvPoint, X509Certificate certificate, 8 | WebRequest request, int certificateProblem) { 9 | return true; 10 | } 11 | } 12 | "@ 13 | [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy 14 | 15 | $server = 'ausveeambem.lab.fullstackgeek.net' 16 | $username = 'svc_veeam_api' 17 | $password = 'S3cr3tsquirr3!' 18 | $vCenter_name = 'ausvcenter.fsglab.local' 19 | $VM_name = 'ausjump01' 20 | 21 | #get the api 22 | $r_api = Invoke-WebRequest -Method Get -Uri "https://$($server):9398/api/" 23 | $r_api_xml = [xml]$r_api.Content 24 | $r_api_links = @($r_api_xml.EnterpriseManager.SupportedVersions.SupportedVersion | Where-Object { $_.Name -eq "v1_5" })[0].Links 25 | 26 | #login 27 | $securepassword = ConvertTo-SecureString -String $password -AsPlainText -Force 28 | $api_credential = [pscredential]::new($username, $securepassword) 29 | $r_login = Invoke-WebRequest -method Post -Uri $r_api_links.Link.Href -Credential $api_credential 30 | 31 | $sessionheadername = "X-RestSvcSessionId" 32 | $sessionid = $r_login.Headers[$sessionheadername] 33 | 34 | #content 35 | $r_login_xml = [xml]$r_login.Content 36 | $r_login_links = $r_login_xml.LogonSession.Links.Link 37 | $r_login_links_base = $r_login_links | Where-Object { $_.Type -eq 'EnterpriseManager' } 38 | 39 | #get hierarchy root 40 | $r_hier_root_uri = $r_login_links_base.Href + 'hierarchyRoots' 41 | $r_hier_roots = Invoke-WebRequest -Method Get -Headers @{$sessionheadername = $sessionid } -Uri $r_hier_root_uri 42 | $r_hier_roots_xml = [xml]$r_hier_roots.Content 43 | $r_hier_root = $r_hier_roots_xml.EntityReferences.Ref | Where-Object { $_.Name -eq $vCenter_name } 44 | $r_hier_root_ID = $r_hier_root.Href -replace ($($r_hier_root_uri + '/')) 45 | 46 | #get vm object reference 47 | $vm_query = $("lookup?host=urn%3aveeam%3aHierarchyRoot%3a$r_hier_root_ID&name=*&type=Vm") 48 | $r_vm_query_uri = $r_login_links_base.Href + $vm_query 49 | $r_vm = Invoke-WebRequest -Method Get -Headers @{$sessionheadername = $sessionid } -Uri $r_vm_query_uri 50 | $r_vm_xml = [xml]$r_vm.Content 51 | $r_vm_obj_ref = $r_vm_xml.HierarchyItems.HierarchyItem | Where-Object { $_.ObjectName -eq $VM_name } | Select-Object -ExpandProperty ObjectRef 52 | 53 | #get vbr server entity 54 | $vcenter_query = 'managedServers?format=Entity' 55 | $r_vcenter_query_uri = $r_login_links_base.Href + $vcenter_query 56 | $r_vcenter = Invoke-WebRequest -Method Get -Headers @{$sessionheadername = $sessionid } -Uri $r_vcenter_query_uri 57 | $r_vcenter_xml = [xml]$r_vcenter 58 | $r_backup_server = ($r_vcenter_xml.ManagedServers.ManagedServer | Where-Object { $_.Name -eq $vCenter_name }).Links.Link | Where-Object { $_.Type -eq 'BackupServer' } 59 | $r_backup_server_id = ($r_backup_server.Href -replace $(($r_login_links_base.Href + 'backupServers/'))) -replace ('\?format=Entity') 60 | 61 | #initiate quick backup for vm 62 | $r_quick_backup_link = $('backupServers/' + $r_backup_server_id + '?action=quickbackup') 63 | $r_quick_backup_uri = $r_login_links_base.Href + $r_quick_backup_link 64 | 65 | $request_body = @" 66 | 67 | 68 | $r_vm_obj_ref 69 | 70 | "@ 71 | 72 | Invoke-WebRequest -Method Post -Headers @{$sessionheadername = $sessionid } -Uri $r_quick_backup_uri -Body $request_body 73 | -------------------------------------------------------------------------------- /Session2/16_AWS_EC2_Restore.ps1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jhoughes/VeeamON2020PowerShell/d613b1df4924eb5f3b24f8a548c6c2ea238f78d2/Session2/16_AWS_EC2_Restore.ps1 -------------------------------------------------------------------------------- /Session2/17_AzureRestore.ps1: -------------------------------------------------------------------------------- 1 | $restorepoint = Get-VBRBackup -Name 'AUSVCENTER-NoTag' | Get-VBRRestorePoint -Name 'ausmemberclt01' | Sort-Object $_.CreationTime -Descending | Select-Object -First 1 2 | $account = Get-VBRAzureAccount -Type ResourceManager -Name 'azure@fullstackgeek.net' 3 | $subscription = Get-VBRAzureSubscription -Account $account -name 'Pay-As-You-Go' 4 | $storageaccount = Get-VBRAzureStorageAccount -Subscription $subscription -Name 'veeamon' 5 | $location = Get-VBRAzureLocation -Subscription $subscription -Name 'southcentralus' 6 | $vmsize = Get-VBRAzureVMSize -Subscription $subscription -Location $location -Name 'Standard_A1' 7 | $network = Get-VBRAzureVirtualNetwork -Subscription $subscription -Name 'veeamon' 8 | $subnet = Get-VBRAzureVirtualNetworkSubnet -Network $network -Name 'veeamon' 9 | $resourcegroup = Get-VBRAzureResourceGroup -Subscription $subscription -Name 'veeamon' 10 | 11 | 12 | Start-VBRVMRestoreToAzure -RestorePoint $restorepoint -Subscription $subscription -StorageAccount $storageaccount ` 13 | -VmSize $vmsize -VirtualNetwork $network -VirtualSubnet $subnet -ResourceGroup $resourcegroup ` 14 | -VmName vmrestore2Az -Reason 'PowerShell Restore to Veeam' -------------------------------------------------------------------------------- /Session2/19_1_Run-SQLRestorePointReport.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | This cmdlet will return an object with details based on SQL restore points. It is suggested to export results to CSV file. 4 | .DESCRIPTION 5 | This cmdlet utilizes the Veeam Explorer for SQL to launch restore sessions and gather details of the restore points, databases, and database files which match the specified parameters. 6 | This cmdlet will require the Veeam PSSnapin and the Veeam Explorer for SQL module to exist on the system, and will require the appropriate access to Veeam B&R. 7 | .EXAMPLE 8 | Run-SQLRestorePointReport -VBRServer 'ausveeambr' -VMName 'aussql2k14' 9 | .EXAMPLE 10 | Run-SQLRestorePointReport -VBRServer 'ausveeambr' -VMName 'aussql2k14', 'ausveeamone', 'ausveeambr' | Export-Csv 'D:\Temp\SQLMultiJobNameReport.csv' -NoTypeInformation 11 | .EXAMPLE 12 | Run-SQLRestorePointReport -VBRServer 'ausveeambr' -VMName 'aussql2k14', 'ausveeamone', 'ausveeambr' -FilterHours 24 | Export-Csv 'D:\Temp\SQLMultiJobNameFilterHoursReport.csv' -NoTypeInformation 13 | .INPUTS 14 | None. You cannot pipe objects to Run-SQLRestorePointReport. 15 | .OUTPUTS 16 | PSCustomObject 17 | .FUNCTIONALITY 18 | This cmdlet utilizes the Veeam Explorer for SQL to find application restore points for SQL. 19 | For each restore point meeting the criteria for VM name(s) within the specified 'Filter Hours' period, it will launch a restore session for each restore point. 20 | Details of the restore points, databases, and database files will be gathered, and the arraylist of the results will be output. 21 | #> 22 | 23 | function Run-SQLRestorePointReport { 24 | [CmdletBinding()] 25 | param ( 26 | 27 | [string]$VBRServer = 'localhost', 28 | [string[]]$VMName, 29 | [int]$FilterHours 30 | 31 | ) 32 | 33 | begin { 34 | 35 | Add-PSSnapin -Name VeeamPSSnapIn 36 | Import-Module Veeam.SQL.PowerShell 37 | Disconnect-VBRServer 38 | Connect-VBRServer -Server $VBRServer 39 | 40 | } #end begin block 41 | 42 | process { 43 | 44 | if ($VMName -AND $FilterHours) { 45 | $SQLRPs = Get-VBRApplicationRestorePoint -Name $VMName -SQL | Where-Object { $_.CreationTime -ge ((Get-Date).AddHours(-$FilterHours)) } 46 | } 47 | elseif ($VMName) { 48 | $SQLRPs = Get-VBRApplicationRestorePoint -Name $VMName -SQL 49 | } 50 | elseif ($FilterHours) { 51 | $SQLRPs = Get-VBRApplicationRestorePoint -SQL | Where-Object { $_.CreationTime -ge ((Get-Date).AddHours(-$FilterHours)) } 52 | } 53 | else { 54 | $SQLRPs = Get-VBRApplicationRestorePoint -SQL 55 | } 56 | 57 | $SQLDetails = [System.Collections.ArrayList]@() 58 | 59 | foreach ($RestorePoint in $SQLRPs) { 60 | 61 | $SQLSession = Start-VESQLRestoreSession -RestorePoint $RestorePoint 62 | $SQLDBs = Get-VESQLDatabase -Session $SQLSession 63 | 64 | foreach ($Database in $SQLDBs) { 65 | 66 | try { 67 | $RestoreInterval = Get-VESQLDatabaseRestoreInterval -Database $Database 68 | } 69 | catch { 70 | 71 | $Properties = @{ 72 | FromUtc = 'No Restore Interval' 73 | ToUtc = 'No Restore Interval' 74 | } 75 | 76 | $RestoreInterval = New-Object psobject -Property $Properties 77 | 78 | } 79 | 80 | $DatabaseFiles = Get-VESQLDatabaseFile -Database $Database 81 | 82 | foreach ($File in $DatabaseFiles) { 83 | 84 | $RestorePointSQLDetail = [PSCustomObject]@{ 85 | 86 | 'VMName' = $RestorePoint.Name 87 | 'RestorePointCreationTime' = $RestorePoint.CreationTime 88 | 'BackupType' = $RestorePoint.Type 89 | 'BackupCorrupted' = $RestorePoint.IsCorrupted 90 | 'RestorePointId' = $RestorePoint.Id 91 | 'DatabaseName' = $Database.Name 92 | 'DatabaseServerName' = $Database.ServerName 93 | 'DatabaseInstanceName' = $Database.InstanceName 94 | 'SystemDB' = $Database.IsSystem 95 | 'ReadOnly' = $Database.IsReadonly 96 | 'BackedUp' = $Database.IsBackedUp 97 | 'Heuristic' = $Database.IsHeuristic 98 | 'AvailabilityGroupName' = $Database.AvailabilityGroupName 99 | 'RecoveryModel' = $Database.RecoveryModel 100 | 'DatabaseID' = $Database.Id 101 | 'RestoreIntervalStart' = $RestoreInterval.FromUtc 102 | 'RestoreIntervalEnd' = $RestoreInterval.ToUtc 103 | 'DatabaseFilePath' = $File.Path 104 | 'DatabaseFileType' = $File.Type 105 | 106 | } #endPSCustomObject 107 | 108 | $null = $SQLDetails.Add($RestorePointSQLDetail) 109 | 110 | Remove-Variable File -ErrorAction SilentlyContinue 111 | 112 | } #end foreach File 113 | 114 | Remove-Variable RestoreInterval -ErrorAction SilentlyContinue 115 | 116 | } #end foreach Database 117 | 118 | Stop-VESQLRestoreSession -Session $SQLSession 119 | 120 | } #end foreach RestorePoint 121 | 122 | } #end process block 123 | 124 | end { 125 | 126 | Write-Output $SQLDetails 127 | 128 | } #end end block 129 | 130 | } 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /Session2/19_2_Run-OracleRestorePointReport.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | This cmdlet will return an object with details based on Oracle restore points. It is suggested to export results to CSV file. 4 | .DESCRIPTION 5 | This cmdlet utilizes the Veeam Explorer for Oracle to launch restore sessions and gather details of the restore points, databases, and database files which match the specified parameters. 6 | This cmdlet will require the Veeam PSSnapin and the Veeam Explorer for Oracle module to exist on the system, and will require the appropriate access to Veeam B&R. 7 | .EXAMPLE 8 | Run-OracleRestorePointReport -VBRServer 'ausveeambr' -VMName 'atloraclelnxvm1' 9 | .EXAMPLE 10 | Run-OracleRestorePointReport -VBRServer 'ausveeambr' -VMName 'atloraclelnxvm1', 'atloraclelnxvm2', 'atloraclelnxvm3' | Export-Csv 'D:\Temp\OracleMultiJobNameReport.csv' -NoTypeInformation 11 | .EXAMPLE 12 | Run-OracleRestorePointReport -VBRServer 'ausveeambr' -VMName 'atloraclelnxvm1', 'atloraclelnxvm2', 'atloraclelnxvm3' -FilterHours 24 | Export-Csv 'D:\Temp\OracleMultiJobNameFilterHoursReport.csv' -NoTypeInformation 13 | .INPUTS 14 | None. You cannot pipe objects to Run-OracleRestorePointReport. 15 | .OUTPUTS 16 | PSCustomObject 17 | .FUNCTIONALITY 18 | This cmdlet utilizes the Veeam Explorer for Oracle to find application restore points for Oracle. 19 | For each restore point meeting the criteria for VM name(s) within the specified 'Filter Hours' period, it will launch a restore session for each restore point. 20 | Details of the restore points, databases, and database files will be gathered, and the arraylist of the results will be output. 21 | #> 22 | 23 | function Run-OracleRestorePointReport { 24 | [CmdletBinding()] 25 | param ( 26 | 27 | [string]$VBRServer = 'localhost', 28 | [string[]]$VMName, 29 | [int]$FilterHours 30 | 31 | ) 32 | 33 | begin { 34 | 35 | Add-PSSnapin -Name VeeamPSSnapIn 36 | Import-Module Veeam.Oracle.PowerShell 37 | Disconnect-VBRServer 38 | Connect-VBRServer -Server $VBRServer 39 | 40 | } #end begin block 41 | 42 | process { 43 | 44 | if ($VMName -AND $FilterHours) { 45 | $OracleRPs = Get-VBRApplicationRestorePoint -Name $VMName -Oracle | Where-Object { $_.CreationTime -ge ((Get-Date).AddHours(-$FilterHours)) } 46 | } elseif ($VMName) { 47 | $OracleRPs = Get-VBRApplicationRestorePoint -Name $VMName -Oracle 48 | } elseif ($FilterHours) { 49 | $OracleRPs = Get-VBRApplicationRestorePoint -Oracle | Where-Object { $_.CreationTime -ge ((Get-Date).AddHours(-$FilterHours)) } 50 | } else { 51 | $OracleRPs = Get-VBRApplicationRestorePoint -Oracle 52 | } 53 | 54 | $OracleDetails = [System.Collections.ArrayList]@() 55 | 56 | foreach ($RestorePoint in $OracleRPs) { 57 | 58 | $OracleSession = Start-VEORRestoreSession -RestorePoint $RestorePoint 59 | $OracleDBs = Get-VEORDatabase -Session $OracleSession 60 | 61 | foreach ($Database in $OracleDBs) { 62 | 63 | $RestoreInterval = Get-VEORDatabaseRestoreInterval -Database $Database 64 | $DatabaseFiles = Get-VEORDatabaseFile -Database $Database 65 | 66 | foreach ($File in $DatabaseFiles) { 67 | 68 | $RestorePointOracleDetail = [PSCustomObject]@{ 69 | 70 | 'VMName' = $RestorePoint.Name 71 | 'RestorePointCreationTime' = $RestorePoint.CreationTime 72 | 'BackupType' = $RestorePoint.Type 73 | 'BackupCorrupted' = $RestorePoint.IsCorrupted 74 | 'RestorePointId' = $RestorePoint.Id 75 | 'DatabaseGlobalName' = $Database.GlobalName 76 | 'DatabaseHome' = $Database.Home 77 | 'RestoreIntervalStart' = $RestoreInterval.From 78 | 'RestoreIntervalEnd' = $RestoreInterval.To 79 | 'DatabaseFilePath' = $File.Path 80 | 'DatabaseFileType' = $File.Type 81 | 82 | } #endPSCustomObject 83 | 84 | $null = $OracleDetails.Add($RestorePointOracleDetail) 85 | 86 | } #end foreach File 87 | 88 | } #end foreach Database 89 | 90 | Stop-VEORRestoreSession -Session $OracleSession 91 | 92 | } #end foreach RestorePoint 93 | 94 | } #end process block 95 | 96 | end { 97 | 98 | Write-Output $OracleDetails 99 | 100 | } #end end block 101 | 102 | } -------------------------------------------------------------------------------- /Session2/1_AgentToVMInstantRecovery.ps1: -------------------------------------------------------------------------------- 1 | #AgentToVMInstantRecovery 2 | $LaptopRestorePoint = Get-VBRRestorePoint -Name 'JOESURFACELAP3' 3 | $ESXiHost = Get-VBRServer -Name 'esxi1.fsglab.local' 4 | $VMFolder = Find-VBRViFolder -Name "VeeamON" -Server $ESXiHost 5 | $VMResourcePool = Find-VBRViResourcePool -Name "VeeamON" -Server $ESXiHost 6 | $VMDatastore = Find-VBRViDatastore -Name "ESXi_AllFlash" -Server $ESXiHost 7 | $Networks = Get-VBRComputerNetworkInfo -RestorePoint $LaptopRestorePoint 8 | $TargetNetwork = Get-VBRViServerNetworkInfo -Server $ESXiHost | Where-Object NetworkName -eq 'Austin-PROD' 9 | 10 | Start-VBRViComputerInstantRecovery -RestorePoint $LaptopRestorePoint -Server $ESXiHost -RestoredVMName 'Surface_Restore' 11 | -VMFolder $VMFolder -ResourcePool $VMResourcePool -CacheDatastore $VMDatastore -PowerOnAfterRestoring -Reason "VeeamON Demo" -RunAsync 12 | -------------------------------------------------------------------------------- /Session2/2_NASCmdlets.ps1: -------------------------------------------------------------------------------- 1 | Get-Command -Module Veeam* -Noun *NAS* | Measure-Object 2 | 3 | Get-Command -Module Veeam* -Noun *NAS* -Verb Add 4 | 5 | Get-Command -Module Veeam* -Noun *NAS* -Verb Start 6 | 7 | Get-Command -Module Veeam* -Noun *NAS* -Verb Restore 8 | 9 | #Create NAS Proxy, NAS Server, NAS Object & NAS job 10 | $RepositoryName = 'ReFS-PerVM' 11 | $Repository = Get-VBRBackupRepository -Name $RepositoryName 12 | 13 | $ProxyServer = Get-VBRServer -Name 'ausveeampxy02.lab.fullstackgeek.net' 14 | $VBRNASProxyServer = Add-VBRNASProxyServer -Server $ProxyServer -Description 'Demo File Proxy' 15 | 16 | $NASCredentials = Get-Credential -Username 'admin' -Message 'NAS Admin Credentials' 17 | $NASServer = Add-VBRNASSMBServer -Path '\\192.168.50.9\LabMedia' -AccessCredentials $NASCredentials -CacheRepository $Repository -ProcessingMode Direct -ProxyMode SelectedProxy -SelectedProxyServer $VBRNASProxyServer -BackupIOControlLevel Medium 18 | 19 | $NASObject = New-VBRNASBackupJobObject -Server $NASServer -Path "\\192.168.50.9\LabMedia\Veeam" 20 | 21 | $NASBackupJob = Add-VBRNASBackupJob -BackupObject $NASObject -ShortTermBackupRepository $Repository -Name 'Veeam_Lab_Media' -Description 'NAS Backup by PowerShell' -ShortTermRetentionPeriod 3 -ShortTermRetentionType Daily 22 | 23 | #Show Job & Object 24 | $NASBackupJob.BackupObject 25 | 26 | $NASBackupJob.BackupObject.Server 27 | 28 | $NASBackupJob.BackupObject.Server.CacheRepository 29 | 30 | $NASBackupJob.BackupObject.Server.CacheRepository.Name 31 | -------------------------------------------------------------------------------- /Session2/3_DataIntegrationAPI.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .NAME 3 | Veeam Backup & Replication Data Integration API example 4 | .SYNOPSIS 5 | Script to use for mounting backup data (VM disks) from a backup to an external server 6 | .DESCRIPTION 7 | This script will perform the following tasks: 8 | - check a specific backup file 9 | - select the last restore point for the defined virtual machine 10 | - present the disks within that backup to an external server 11 | 12 | Created for Veeam Backup & Replication v10 13 | Released under the MIT license. 14 | .LINK 15 | http://www.github.com/nielsengelen 16 | #> 17 | 18 | # Add the Veeam PowerShell snapin - if it already is loaded continue silently with no error 19 | Add-PSSnapin VeeamPSSnapin -ErrorAction SilentlyContinue 20 | 21 | # The vmname variable $vmname is where you define the Virtual Machine name 22 | $vmname = "MYVIRTUALMACHINENAME" 23 | 24 | # The backup variable $backup is populated by the cmdlet Get-VBRBackup which will return info regarding the backup data, this contains your backup job name 25 | $backup = Get-VBRBackup -Name "MYBACKUPJOBNAME" 26 | 27 | # Provide the host name of the target server 28 | $targetServerName = "TARGETSERVER" 29 | 30 | # Provide the credentials to access the remote server, for example: LAB\administrator 31 | # These must be stored within the Credentials manager in Veeam Backup & Replication 32 | $targetAdminCreds = Get-VBRCredentials -name "LAB\Administrator" 33 | 34 | # Get-VBRRestorePoint is where you find the last restore point you wish to use 35 | $restorepoint = Get-VBRRestorePoint -Backup $backup -Name $vmname | Sort-Object –Property CreationTime | Select -Last 1 36 | 37 | # Publish the disk(s) for the restore point 38 | $session = Publish-VBRBackupContent -RestorePoint $restorepoint -TargetServerName $targetServerName -TargetServerCredentials $targetAdminCreds 39 | 40 | # Obtaining information about mounted disks 41 | $contentInfo = Get-VBRPublishedBackupContentInfo -Session $session 42 | 43 | Write-Host "`nBackup Job Name:" $session.BackupName "`nRestore Point time:" $session.RestorePoint "`nVM Name:" $session.PublicationName 44 | 45 | # Produce a report showing what mount points were published and where 46 | foreach ($contentType in $contentInfo) { 47 | Write-Host "================================" 48 | $disks = $contentType.Disks 49 | Write-Host "Mounted Disk:" $disks.DiskName 50 | Write-Host "Mounted At:" $disks.MountPoints 51 | Write-Host "Mounted As:" $contentType.Mode 52 | Write-Host "Available From:" $contentType.ServerIps "(Port:" $contentType.ServerPort ")" 53 | Write-Host "Available Via:" $disks.AccessLink 54 | Write-Host "================================" 55 | } -------------------------------------------------------------------------------- /Session2/4_VirtualLabAutomation.ps1: -------------------------------------------------------------------------------- 1 | #Virtual lab automation 2 | 3 | [string]$VirtualLabName = 'VeeamON_Demo_Lab' 4 | [string]$VirtualLabDescription = 'Virtual Lab for Demo VMs' 5 | [string]$ResourcePoolName = 'VeeamON_Demo_ResourcePool' 6 | [string]$VMFolderName = 'VeeamON_Demo_Lab' 7 | 8 | [string]$SourceHostname = 'esxi1.fsglab.local' 9 | [string]$DestinationHostname = 'esxi2.fsglab.local' 10 | 11 | [string]$CacheDatastoreName = 'ESXi_AllFlash' 12 | 13 | [string]$ProxyApplianceName = 'VeeamON_Proxy_Appliance' 14 | [string]$ProxyApplianceIP = '192.168.20.200' 15 | [string]$ProxyApplianceNetmask = '255.255.255.0' 16 | [string]$ProxyApplianceGateway = '192.168.20.1' 17 | [string]$ProxyApplianceDNS1 = '192.168.20.5' 18 | [string]$ProxyApplianceDNS2 = '192.168.20.10' 19 | [string]$ProxyApplianceDatastoreName = 'ESXi_Capacity' 20 | [string]$ProxyApplianceNetworkName = 'AUSTIN-Prod' 21 | 22 | [string]$VirtualSwitchName = 'PNTLSLAB-VDS' 23 | 24 | [string]$ProdNetworkName1 = 'CORE-Prod' 25 | [string]$IsolatedNetworkName1 = 'DR-Network3' 26 | [int]$IsolatedNetworkVLANID1 = '10' 27 | 28 | [string]$ProdNetworkName2 = 'AUSTIN-Prod' 29 | [string]$IsolatedNetworkName2 = 'DR-Network4' 30 | [int]$IsolatedNetworkVLANID2 = '20' 31 | 32 | [string]$RemapIP1 = '192.168.10.1' 33 | [string]$MasqueradeIP1 = '192.168.110.0' 34 | 35 | [string]$RemapIP2 = '192.168.20.1' 36 | [string]$MasqueradeIP2 = '192.168.120.0' 37 | 38 | [string]$StaticIP1 = '192.168.10.10' 39 | [string]$AccessIP1 = '192.168.20.231' 40 | 41 | [string]$StaticIP2 = '192.168.20.10' 42 | [string]$AccessIP2 = '192.168.20.232' 43 | 44 | 45 | #Get base objects 46 | $SourceServer = Get-VBRServer -Name $SourceHostname 47 | $DestinationServer = Get-VBRServer -Name $DestinationHostname 48 | 49 | $CacheDatastore = Find-VBRViDatastore -Server $DestinationServer -Name $CacheDatastoreName 50 | $ProxyApplianceDatastore = Find-VBRViDatastore -Server $DestinationServer -Name $ProxyApplianceDatastoreName 51 | $DestinationNetworks = Get-VBRViServerNetworkInfo -Server $DestinationServer 52 | $ProxyNetwork = $DestinationNetworks | Where-Object { $_.NetworkName -eq $ProxyApplianceNetworkName } 53 | 54 | $SourceNetworks = Get-VBRViServerNetworkInfo -Server $SourceServer 55 | $ProdNetwork1 = $SourceNetworks | Where-Object { ($_.Type -eq 'ViDVS') -AND ($_.NetworkName -eq $ProdNetworkName1) } 56 | $ProdNetwork2 = $SourceNetworks | Where-Object { ($_.Type -eq "ViDVS") -AND ($_.NetworkName -eq $ProdNetworkName2) } 57 | 58 | $VirtualSwitch = Get-VBRViVirtualSwitch -Server $DestinationServer | Where-Object { ($_.Type -eq 'DVS') -AND ($_.Name -eq $VirtualSwitchName) } 59 | 60 | #Create building blocks 61 | $ProxyAppliance = New-VBRViVirtualLabProxyAppliance -Server $DestinationServer -Name $ProxyApplianceName -Datastore $ProxyApplianceDatastore -Network $ProxyNetwork ` 62 | -IPAddress $ProxyApplianceIP -SubnetMask $ProxyApplianceNetmask -DefaultGateway $ProxyApplianceGateway -PreferredDNSServer $ProxyApplianceDNS1 -AlternateDNSServer $ProxyApplianceDNS2 63 | 64 | $NetworkMapping1 = New-VBRViNetworkMappingRule -Server $DestinationServer -ProductionNetwork $ProdNetwork1 -IsolatedNetworkName $IsolatedNetworkName1 -VLANID $IsolatedNetworkVLANID1 65 | $NetworkMapping2 = New-VBRViNetworkMappingRule -Server $DestinationServer -ProductionNetwork $ProdNetwork2 -IsolatedNetworkName $IsolatedNetworkName2 -VLANID $IsolatedNetworkVLANID2 66 | 67 | $VirtualLabNetworkOptions1 = New-VBRViVirtualLabNetworkOptions -NetworkMappingRule $NetworkMapping1 -IPAddress $RemapIP1 -SubnetMask $ProxyApplianceNetmask -MasqueradeIPAddress $MasqueradeIP1 -DNSServer $ProxyApplianceDNS1 -EnableDHCP 68 | $VirtualLabNetworkOptions2 = New-VBRViVirtualLabNetworkOptions -NetworkMappingRule $NetworkMapping2 -IPAddress $RemapIP2 -SubnetMask $ProxyApplianceNetmask -MasqueradeIPAddress $MasqueradeIP2 -DNSServer $ProxyApplianceDNS1 -EnableDHCP 69 | 70 | $IPMapping1 = New-VBRViVirtualLabIPMappingRule -ProductionNetwork $ProdNetwork1 -IsolatedIPAddress $StaticIP1 -AccessIPAddress $AccessIP1 -Note "Static IP address map to access $StaticIP1" 71 | $IPMapping2 = New-VBRViVirtualLabIPMappingRule -ProductionNetwork $ProdNetwork2 -IsolatedIPAddress $StaticIP2 -AccessIPAddress $AccessIP2 -Note "Static IP address map to access $StaticIP2" 72 | 73 | 74 | #Create Virtual Lab 75 | $VirtualLab = Add-VBRViAdvancedVirtualLab -Server $DestinationServer -Name $VirtualLabName -Description $VirtualLabDescription ` 76 | -DesignatedResourcePoolName $ResourcePoolName -DesignatedVMFolderName $VMFolderName -CacheDatastore $CacheDatastore ` 77 | -ProxyAppliance $ProxyAppliance -NetworkMappingRule $NetworkMapping1, $NetworkMapping2 ` 78 | -NetworkOptions $VirtualLabNetworkOptions1, $VirtualLabNetworkOptions2 ` 79 | -EnableRoutingBetweenvNics -DVS $VirtualSwitch -IpMappingRule $IPMapping1, $IPMapping2 -Force 80 | 81 | -------------------------------------------------------------------------------- /Session2/5_LicenseCmdlets.ps1: -------------------------------------------------------------------------------- 1 | Get-Command -Noun *License* -Module VeeamPSSnapIn 2 | 3 | $VBRLicense = Get-VBRInstalledLicense 4 | $VBRLicense 5 | 6 | Enable-VBRLicenseAutoUpdate 7 | 8 | $LicenseSummary = Get-VBRInstanceLicenseSummary -License $VBRLicense 9 | $LicenseSummary 10 | 11 | $LicenseSummary.Object 12 | 13 | $LicenseSummary.Workload 14 | 15 | Get-VBRLicensedInstanceWorkload -License $VBRLicense 16 | 17 | Get-VBRCapacityLicenseSummary -License $VBRLicense 18 | -------------------------------------------------------------------------------- /Session2/6_Get-VeeamJobConfiguration.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 4 2 | #Requires -RunAsAdministrator 3 | <# 4 | .Synopsis 5 | Simple Veeam report to export quick job configurations 6 | .Notes 7 | Version: 0.2 8 | Author: Joe Houghes 9 | Modified Date: 5-24-2020 10 | .EXAMPLE 11 | Get-VeeamJobConfiguration -VBRServer ausveeambr | Export-CSV D:\temp\VeeamJobConfigDetails.csv 12 | #> 13 | 14 | function Get-VeeamJobConfiguration { 15 | 16 | param ( 17 | [Parameter(mandatory = $false)] 18 | [string] 19 | $VBRServer = 'localhost' 20 | ) 21 | 22 | begin { 23 | 24 | #Load the Veeam PSSnapin 25 | if (!(Get-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue)) { 26 | Add-PSSnapin -Name VeeamPSSnapIn 27 | Connect-VBRServer -Server $VBRServer 28 | } 29 | 30 | else { 31 | Disconnect-VBRServer 32 | Connect-VBRServer -Server $VBRServer 33 | } 34 | 35 | # Get Backup Jobs & Repositories 36 | $CompareJobs = [Veeam.Backup.Core.CBackupJob]::GetByType('Backup') 37 | $Repositories = [Veeam.Backup.Core.CBackupRepository]::GetAll() 38 | 39 | } 40 | 41 | process { 42 | 43 | [System.Collections.ArrayList]$JobDetails = @() 44 | 45 | # Loop through each job adding details to array 46 | foreach ($EachJob in $CompareJobs) { 47 | 48 | $Repository = ($Repositories | Where-Object { $_.HostId -eq $EachJob.TargetHostId -and $_.Path -eq $EachJob.TargetDir }).Name 49 | 50 | $JobProxies = $EachJob.GetSourceViProxies().Name -join ';' 51 | 52 | if ($EachJob.BackupTargetOptions.TransformFullToSyntethic -OR $EachJob.BackupTargetOptions.TransformIncrementsToSyntethic -OR $EachJob.BackupStorageOptions.EnableFullBackup) { 53 | $FullEnabled = $true 54 | } else { 55 | $FullEnabled = $false 56 | } 57 | 58 | switch ($EachJob.BackupStorageOptions.CompressionLevel) { 59 | '5' { $Compression = 'Optimal' } 60 | '4' { $Compression = 'Dedupe-friendly' } 61 | '0' { $Compression = 'None' } 62 | '6' { $Compression = 'High' } 63 | '9' { $Compression = 'Extreme' } 64 | } 65 | 66 | switch ($EachJob.BackupStorageOptions.StgBlockSize) { 67 | 'KbBlockSize1024' { $Optimization = 'Local Target' } 68 | 'KbBlockSize8192' { $Optimization = 'Local Target(16TB+ Files)' } 69 | 'KbBlockSize512' { $Optimization = 'LAN Target' } 70 | 'KbBlockSize256' { $Optimization = 'WAN Target' } 71 | } 72 | 73 | switch ($EachJob.VssOptions.GuestFSIndexingType) { 74 | 'EveryFolders' { $IndexGuest = "Enabled" } 75 | 'None' { $IndexGuest = "Disabled" } 76 | } 77 | 78 | $JobConfig = [PSCustomObject] @{ 79 | PSTypeName = 'Veeam.JobQuickConfig' 80 | Name = $EachJob.Name 81 | Scheduled = $EachJob.IsScheduleEnabled 82 | BackupMode = $EachJob.BackupTargetOptions.Algorithm 83 | FullEnabled = $FullEnabled 84 | AutoProxy = $EachJob.SourceProxyAutoDetect 85 | Proxies = $JobProxies 86 | Repository = $Repository 87 | RestorePoints = $EachJob.BackupStorageOptions.RetainCycles 88 | Deduplication = $EachJob.BackupStorageOptions.EnableDeduplication 89 | Compression = $Compression 90 | StorageOptimization = $Optimization 91 | RemoveDeletedVMs = $EachJob.BackupStorageOptions.EnableDeletedVmDataRetention 92 | DeletedVMRetention = $EachJob.BackupStorageOptions.RetainDays 93 | CBTEnabled = $EachJob.ViSourceOptions.UseChangeTracking 94 | QuiesceVMTools = $EachJob.ViSourceOptions.VMToolsQuiesce 95 | IntegrityChecks = $EachJob.BackupStorageOptions.EnableIntegrityChecks 96 | SetVMNotes = $EachJob.ViSourceOptions.SetResultsToVmNotes 97 | VMAttribute = $EachJob.ViSourceOptions.VmAttributeName 98 | VSSEnabled = $EachJob.VssOptions.Enabled 99 | IndexGuestFS = $IndexGuest 100 | } #end pscustom object 101 | 102 | $Null = $JobDetails.Add($JobConfig) 103 | 104 | } #end foreach job 105 | 106 | } 107 | 108 | 109 | end { 110 | 111 | Write-Output $JobDetails 112 | 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /Session2/7_Run-VeeamJobComparison.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 4 2 | #Requires -RunAsAdministrator 3 | <# 4 | .Synopsis 5 | Simple Veeam report to compare job configurations 6 | .Notes 7 | Version: 0.2 8 | Author: Joe Houghes 9 | Modified Date: 5-24-2020 10 | .EXAMPLE 11 | Get-VeeamJobConfiguration -VBRServer ausveeambr | Run-VeeamJobComparison -ReferenceJobName 'AUSVCENTER-TagTest' 12 | #> 13 | 14 | function Run-VeeamJobComparison { 15 | 16 | param ( 17 | [Parameter( Mandatory = $true)] 18 | [string] 19 | $ReferenceJobName, 20 | 21 | [Parameter( Mandatory = $true, ValueFromPipeline)] 22 | $VBRJobConfig 23 | 24 | ) 25 | 26 | begin { 27 | <# 28 | $VBRJobConfig[0].Name 29 | $VBRJobConfig | Get-Member 30 | $VBRJobConfig.Count 31 | #> 32 | if (!($PSBoundParameters.ReferenceJobName -in $VBRJobConfig.Name)) { 33 | throw "Failed to find backup job with name: $ReferenceJobName" 34 | } 35 | 36 | } 37 | 38 | process { 39 | 40 | $ReferenceObject = $VBRJobConfig | Where-Object { $PSItem.Name -eq $PSBoundParameters.ReferenceJobName } 41 | $DiffObject = $VBRJobConfig | Where-Object { $PSItem.Name -ne $PSBoundParameters.ReferenceJobName } 42 | 43 | $Properties = $ReferenceObject.PSObject.Properties.Name | Where-Object { $PSItem -ne 'Name' } 44 | 45 | [System.Collections.ArrayList]$CompareJobOutput = @() 46 | 47 | foreach ($RefJob in $ReferenceObject) { 48 | 49 | $RefJobDetails = [PSCustomObject] @{ } 50 | $RefJobDetails = $RefJobDetails | Select-Object Name 51 | 52 | $RefJobDetails.Name = $RefJob.Name 53 | 54 | foreach ($EachProperty in $Properties) { 55 | $Value = 'REFJOB' 56 | 57 | $PropName = $($EachProperty + "Match") 58 | $RefJobDetails = $RefJobDetails | Select-Object *, $PropName 59 | $RefJobDetails.$PropName = $Value 60 | } #end foreach property 61 | 62 | $null = $CompareJobOutput.Add($RefJobDetails) 63 | Remove-Variable RefJobDetails 64 | 65 | }# end foreach refjob 66 | 67 | 68 | foreach ($DiffJob in $DiffObject) { 69 | 70 | $CompareJobDetails = [PSCustomObject] @{ } 71 | $CompareJobDetails = $CompareJobDetails | Select-Object Name 72 | 73 | $CompareJobDetails.Name = $DiffJob.Name 74 | 75 | foreach ($EachProperty in $Properties) { 76 | $Value = [bool]($($DiffJob.$EachProperty) -eq $($ReferenceObject.$EachProperty)) 77 | 78 | $PropName = $($EachProperty + "Match") 79 | $CompareJobDetails = $CompareJobDetails | Select-Object *, $PropName 80 | $CompareJobDetails.$PropName = $Value 81 | } #end foreach property 82 | 83 | $null = $CompareJobOutput.Add($CompareJobDetails) 84 | Remove-Variable CompareJobDetails 85 | 86 | }# end foreach diffjob 87 | 88 | } 89 | 90 | 91 | end { 92 | 93 | Write-Output $CompareJobOutput 94 | 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /Session2/8_SetJobOptions&SQLVSS.ps1: -------------------------------------------------------------------------------- 1 | #NewSQLBackupShellJob 2 | $NewShellJob | Get-VBRJob -Name 'PowerShellOptions' 3 | 4 | #Otherwise, create object with default job & VSS options 5 | #$JobOptions = New-VBRJobOptions -ForBackupJob 6 | 7 | #Create specific job options object 8 | $JobOptions = Get-VBRJobOptions -Job $NewShellJob 9 | $JobOptions.BackupStorageOptions.RetainCycles = '60' 10 | $JobOptions.BackupStorageOptions.RetainDays = '21' 11 | $JobOptions.BackupStorageOptions.EnableDeletedVmDataRetention = $True 12 | $JobOptions.BackupTargetOptions.TransformToSyntethicDays = 'Friday' 13 | $JobOptions.NotificationOptions.SnmpNotification = $True 14 | $JobOptions.NotificationOptions.SendEmailNotification2AdditionalAddresses = $True 15 | $JobOptions.NotificationOptions.EmailNotificationAdditionalAddresses = 'testemail@testdomain.com' 16 | $JobOptions.ViSourceOptions.VmAttributeName = 'Veeam_Backup_Attribute' 17 | $JobOptions.ViSourceOptions.SetResultsToVmNotes = $True 18 | $JobOptions.SanIntegrationOptions.UseSanSnapshots = $False 19 | 20 | #Enable VSS integration and create VSS options object, set guest interaction proxy to new job 21 | $GuestProxy = Get-VBRServer -Name $VeeamProxyName 22 | 23 | Enable-VBRJobVSSIntegration -Job $NewShellJob 24 | 25 | $JobVSS = $NewShellJob.GetVSSOptions() 26 | $JobVSS.VssSnapshotOptions.Enabled = $True 27 | $JobVSS.VssSnapshotOptions.IgnoreErrors = $False 28 | $JobVSS.GuestProxyAutoDetect = $False 29 | $JobVSS.WinCredsId = $VSSCredential.Id 30 | [Veeam.Backup.Core.CJobProxy]::Create($NewShellJob.Id, $GuestProxy.Id, "EGuest") 31 | 32 | #Set job options & VSS options 33 | $NewShellJob.SetVssOptions($JobVSS) 34 | Set-VBRJobVssOptions -Job $NewShellJob -Credentials $SQLCredential 35 | Set-VBRJobOptions -Job $NewShellJob -Options $JobOptions 36 | 37 | #Set job proxy for backup, enable & set schedule to new job 38 | $VeeamProxyName = 'ausveeampxy01.lab.fullstackgeek.net' 39 | $SourceProxy = Get-VBRViProxy -Name $VeeamProxyName 40 | 41 | $DaysToRun = 'Everyday' 42 | $TimeToRun = '21:00' 43 | 44 | Set-VBRJobProxy -Job $NewShellJob -Proxy $SourceProxy 45 | Enable-VBRJobSchedule -Job $NewShellJob 46 | Set-VBRJobSchedule -Job $NewShellJob -Daily -At $TimeToRun -DailyKind $DaysToRun 47 | 48 | ## Code to modify existing jobs for number of restore points, job run frequency, and backup window 49 | 50 | #Set these variables to the required number of restore points, job frequency in hours, and starting & ending hour of the window when backups are not allowed 51 | #NOTE: The NoBackupWindowEnd time will be set to the 59th minute of the hour selected, so subtract 1 hour from the allowed backup start time 52 | #Example: To effectively allow backups from 6PM to 6AM, set the NoBackupWindowStart to 06 (6AM), and NoBackupWindowEnd to 17 (5:59PM) 53 | $RestorePointsToMaintain = '140' 54 | $BackupFrequency = '6' 55 | $NoBackupWindowStart = '17' 56 | $NoBackupWindowEnd = '06' 57 | 58 | $JobToModify = Get-VBRJob -Name 'PowerShellOptions' 59 | $JobOptions = Get-VBRJobOptions -Job $JobToModify 60 | $JobOptions.BackupStorageOptions.RetainCycles = $RestorePointsToMaintain 61 | Set-VBRJobOptions -Job $JobToModify -Options $JobOptions 62 | 63 | $JobBackupWindow = New-VBRBackupWindowOptions -FromHour $NoBackupWindowEnd -ToHour $NoBackupWindowStart -Enabled:$False 64 | Set-VBRJobSchedule -Job $JobToModify -Periodicaly -FullPeriod $BackupFrequency -PeriodicallyKind Hours -PeriodicallySchedule $JobBackupWindow 65 | 66 | 67 | #If necessary to terminate running jobs if they exceed the backup window, uncomment the below section 68 | <# 69 | $ScheduleOptions = Get-VBRJobScheduleOptions -Job $JobToModify 70 | $ScheduleOptions.OptionsBackupWindow = $JobBackupWindow 71 | $ScheduleOptions.OptionsBackupWindow.IsEnabled = $true 72 | 73 | Set-VBRJobScheduleOptions -Job $JobToModify -Options $ScheduleOptions 74 | 75 | Enable-VBRJobSchedule -Job $JobToModify 76 | #> -------------------------------------------------------------------------------- /Session2/9_CloneJob&Options.ps1: -------------------------------------------------------------------------------- 1 | #Connect to Veeam 2 | Add-PSSnapin -Name VeeamPSSnapIn 3 | Connect-VBRServer -Server ausveeambr 4 | 5 | #Variables 6 | $CloneRepositoryName = 'NTFS-Bulk' 7 | $CloneRepository = Get-VBRBackupRepository -Name $CloneRepositoryName 8 | 9 | #Get & show source job 10 | $SourceJob = Get-VBRJob -Name 'zPowerShellDemoJob' 11 | $SourceJob.Info.CommonInfo 12 | $SourceJob.FindTargetRepository().Name 13 | 14 | #Show jobs, clone job, show new job 15 | Get-VBRJob -WarningAction SilentlyContinue | Select-Object Name, Description 16 | $CloneJob = Copy-VBRJob -Job $SourceJob -Name 'zPowerShellDemo2' -Description 'Job cloned by PowerShell' -Repository $CloneRepository 17 | Get-VBRJob -WarningAction SilentlyContinue | Select-Object Name, Description 18 | 19 | #Get cloned job details 20 | $CloneJob.Info.CommonInfo 21 | $CloneJob.FindTargetRepository().Name 22 | $CloneJob.Options.NotificationOptions.EmailNotificationAdditionalAddresses 23 | $CloneJob.Options.BackupStorageOptions.RetainCycles 24 | 25 | #Get source job and show details 26 | $Source2Job = Get-VBRJob -Name 'SQLLogTest' 27 | $Source2Job.Options.NotificationOptions.EmailNotificationAdditionalAddresses 28 | $Source2Job.Options.BackupStorageOptions.RetainCycles 29 | 30 | #Get course job options, set to clone job, show new job options 31 | $Source2Options = $Source2Job | Get-VBRJobOptions 32 | 33 | Set-VBRJobOptions -Job $CloneJob -Options $Source2Options 34 | 35 | $CloneJobUpdate = Get-VBRJob -Name 'zPowerShellDemo2' 36 | $CloneJobUpdate.Options.NotificationOptions.EmailNotificationAdditionalAddresses 37 | $CloneJobUpdate.Options.BackupStorageOptions.RetainCycles 38 | -------------------------------------------------------------------------------- /Session2/AutomaticVMBackup/Find-UnprotectedVMs.ps1: -------------------------------------------------------------------------------- 1 | function Find-UnprotectedVMs { 2 | <# 3 | .Synopsis 4 | This function will check against a vCenter server to gather all registered VMs, the return VMs not backed up by a specific Veeam B&R server 5 | .DESCRIPTION 6 | This function will query a vCenter server to gather all registered VMs, then return VMs not backed up by a specific Veeam B&R server 7 | .EXAMPLE 8 | Find-UnprotectedVMs -VBRServerName 'ausveeambr' -vCenterName 'ausvcenter' 9 | .EXAMPLE 10 | Find-UnprotectedVMs -VBRServerName 'ausveeambr' -vCenterName 'ausvcenter' | Export-Csv 'D:\Temp\UnprotectedVMs.csv' -NoTypeInformation 11 | .INPUTS 12 | None. You cannot pipe objects to Find-UnprotectedVMs. 13 | .OUTPUTS 14 | PSCustomObject 15 | #> 16 | 17 | [CmdletBinding()] 18 | param ( 19 | 20 | [string]$VBRServerName, 21 | [string]$vCenterName 22 | 23 | ) 24 | 25 | begin { 26 | 27 | Add-PSSnapin -Name VeeamPSSnapIn 28 | Connect-VBRServer -Server $VBRServerName 29 | 30 | } #end begin block 31 | 32 | process { 33 | 34 | $Jobs = Get-VBRJob -WarningAction SilentlyContinue | Where-Object { $PSItem.JobType -eq 'Backup' -AND $PSItem.BackupPlatform.Platform -eq 'EVmware' } 35 | $JobObjects = $Jobs | Get-VBRJobObject 36 | $JobVMObjects = $JobObjects | Where-Object { $PSItem.Object.ViType -eq 'VirtualMachine' -AND $PSItem.Object.Platform.Platform -eq 'EVmware' } 37 | $JobTagObjects = $JobObjects | Where-Object { $PSItem.Object.ViType -eq 'Tag' -AND $PSItem.Object.Platform.Platform -eq 'EVmware' } 38 | 39 | $JobVMs = $JobVMObjects | Select-Object Name, @{n = 'JobID'; e = { $PSItem.JobId.Guid } }, @{n = 'MoRefID'; e = { $PSItem.Object.ObjectID } }, @{n = 'Uuid'; e = { $PSItem.Object.Uuid } }, @{n = 'vCenter'; e = { $PSItem.Object.Host.Name } } 40 | $UniqueJobVMs = $JobVMs | Select-Object Name, JobID, MoRefID, Uuid, VC -Unique 41 | 42 | $JobTags = $JobTagObjects | Select-Object Name, @{n = 'JobID'; e = { $PSItem.JobId.Guid } }, @{n = 'Path'; e = { $PSItem.Location } }, @{n = 'vCenter'; e = { $PSItem.Object.Host.Name } } 43 | $UniqueJobTags = $JobTags | Select-Object Name, JobID, Path, VC -Unique 44 | 45 | $TagPaths = foreach ($EachTag in $UniqueJobTags) { 46 | $EachTag.Path + "\*" 47 | } 48 | 49 | $vCenterServer = Get-VBRServer -Name $vCenterName 50 | 51 | $AllVMs = Find-VBRViEntity -VMsAndTemplates -Server $vCenterServer | Where-Object { $PSItem.Type -eq 'VM' } | Select-Object Name, Reference, Uuid, Path, @{n = 'vCenter'; e = { ($PSItem.Path -split '\\')[0] } } 52 | 53 | $VCTagVMs = Find-VBRViEntity -Tags -Server $vCenterServer | Where-Object { $PSItem.Type -eq 'VM' } | Select-Object Name, Reference, Uuid, Path, @{n = 'vCenter'; e = { ($PSItem.Path -split '\\')[0] } } 54 | 55 | $PathMatchVMs = foreach ($EachVM in $VCTagVMs) { 56 | foreach ($EachTag in $TagPaths) { 57 | if ($EachVM.Path -like $EachTag) { 58 | $EachVM 59 | } 60 | } 61 | } 62 | 63 | [System.Collections.ArrayList]$JobMissingVMs = @() 64 | 65 | foreach ($EachVM in $AllVMs) { 66 | 67 | $CoveredByName = [bool]($EachVM.Uuid -In ($UniqueJobVMs.Uuid)) 68 | $CoveredByTag = [bool]($EachVM.Uuid -In ($PathMatchVMs.Uuid)) 69 | 70 | if (-Not $CoveredByName -OR $CoveredByTag) { 71 | 72 | $VMResult = [PSCustomObject] @{ 73 | Name = $EachVM.Name 74 | MoRefID = $EachVM.Reference 75 | Uuid = $EachVM.Uuid 76 | Path = $EachVM.Path 77 | vCenter = $EachVM.vCenter 78 | } #end PSCustomObject 79 | 80 | $null = $JobMissingVMs.Add($VMResult) 81 | Remove-Variable VMResult 82 | 83 | } 84 | 85 | } #end foreach 86 | 87 | } #end process block 88 | 89 | end { 90 | 91 | Write-Output $JobMissingVMs 92 | 93 | Disconnect-VBRServer 94 | Remove-PSSnapin -Name VeeamPSSnapIn 95 | 96 | } #end end block 97 | 98 | } 99 | -------------------------------------------------------------------------------- /Session2/AutomaticVMBackup/Protect-MissingVMs.ps1: -------------------------------------------------------------------------------- 1 | function Protect-MissingVMs { 2 | <# 3 | .Synopsis 4 | This function will take a list of VMs, add them to Veeam backup jobs matching a specific name prefix, until a job VM limit is reached 5 | .DESCRIPTION 6 | This function will calculate the required number of Veeam backup jobs with a specified name prefix to backup VMs, until it reaches the specified maximum number of VMs per job. 7 | If additional jobs are required, it create additional jobs cloned from the highest number job matching the specified name prefix, and will set the job options from the same source job. 8 | It will then add VMs to each of the Veeam backup jobs with the specified name prefix, until the defined maximum number of VMs per job is reached. 9 | .EXAMPLE 10 | Protect-MissingVMs -VBRServerName 'ausveeambr' -vCenterName 'ausvcenter' -VMstoProtect vm1,vm2, vm3 -JobNamePrefix 'zPowerShellDemoJob-' -MaxJobVMs '8' 11 | .INPUTS 12 | None. You cannot pipe objects to Protect-MissingVMs. 13 | .OUTPUTS 14 | PSCustomObject 15 | #> 16 | 17 | [CmdletBinding()] 18 | param ( 19 | 20 | [string]$VBRServerName, 21 | [string]$vCenterName, 22 | [string[]]$VMName, 23 | [string]$JobNamePrefix, 24 | [int]$MaxJobVMs 25 | 26 | ) 27 | 28 | begin { 29 | 30 | Add-PSSnapin -Name VeeamPSSnapIn 31 | Connect-VBRServer -Server $VBRServerName 32 | 33 | } #end begin block 34 | 35 | process { 36 | 37 | [System.Collections.ArrayList]$ExistingJobs = @() 38 | $ExistingJobs = Get-VBRJob -WarningAction SilentlyContinue -Name "$JobNamePrefix*" | Where-Object { $PSItem.JobType -eq 'Backup' -AND $PSItem.BackupPlatform.Platform -eq 'EVmware' } | Select-Object Name, @{n = 'VMCount'; e = { $_.GetViOijs().Count } } 39 | 40 | [int]$TotalVMsExistingJobs = $($ExistingJobs.VMCount) | Measure-Object -Sum | Select-Object -ExpandProperty Sum 41 | [int]$TotalCapacityExistingJobs = ($ExistingJobs.Count * $MaxJobVMs) - $TotalVMsExistingJobs 42 | [int]$UnprotectedVMsBeyondCapacity = $VMName.Count - $TotalCapacityExistingJobs 43 | [int]$AdditionalJobsRequired = [math]::Round(($UnprotectedVMsBeyondCapacity / $MaxJobVMs), 0) 44 | 45 | #Create Arraylist & get VIEntities 46 | [System.Collections.ArrayList]$VMsToProtect = @() 47 | 48 | $vCenterServer = Get-VBRServer -Name $PSBoundParameters.vCenterName 49 | $VMsToProtect = Find-VBRViEntity -Name $VMName -VMsAndTemplates -Server $vCenterServer | Where-Object { $PSItem.Type -eq 'VM' } 50 | 51 | Write-Output '------------------------------------------' 52 | Write-Output "Total VMs to add: '$($VMsToProtect.Count)'" 53 | 54 | #Clone additional jobs if required 55 | if ($AdditionalJobsRequired) { 56 | 57 | $JobToClone = $ExistingJobs | Sort-Object Name | Select-Object -Last 1 -ExpandProperty Name 58 | $BaseJob = Get-VBRJob -Name $JobToClone 59 | $BaseJobOptions = $BaseJob.GetOptions() 60 | $BaseJobID = [int](($BaseJob.Name -split '(\d+)$')[1]) 61 | $CloneRepository = $BaseJob.FindTargetRepository() 62 | 63 | For ($i = 1; $i -le $AdditionalJobsRequired; $i++) { 64 | 65 | $JobName = $($JobNamePrefix + $($BaseJobID + $i)) 66 | #Write-Output "Job name: '$JobName'" 67 | #Copy-VBRJob -Job $BaseJob -Name $JobName -Description 'Job cloned by PowerShell' -Repository $CloneRepository | Out-Null 68 | 69 | $NewJob = Add-VBRViBackupJob -Name $JobName -Description 'Job cloned by PowerShell' -BackupRepository $CloneRepository -Entity $VMsToProtect[0] 70 | $NewJob = Get-VBRJob -Name $JobName 71 | 72 | #$CloneJob = Get-VBRJob -Name $JobName 73 | #$CloneJob | Get-VBRJobObject | Remove-VBRJobObject -Completely 74 | $VMsToProtect.RemoveAt(0) 75 | Set-VBRJobOptions -Job $NewJob -Options $BaseJobOptions | Out-Null 76 | Write-Output "Created new job: '$JobName'" 77 | Remove-Variable JobName, NewJob -ErrorAction SilentlyContinue 78 | 79 | } #end for loop add jobs 80 | 81 | Remove-Variable ExistingJobs 82 | 83 | [System.Collections.ArrayList]$ExistingJobs = @() 84 | $ExistingJobs = Get-VBRJob -WarningAction SilentlyContinue -Name "$JobNamePrefix*" | Where-Object { $PSItem.JobType -eq 'Backup' -AND $PSItem.BackupPlatform.Platform -eq 'EVmware' } | Select-Object Name, @{n = 'VMCount'; e = { $_.GetViOijs().Count } } 85 | 86 | } #end if AdditionalJobsRequired 87 | 88 | Write-Output '------------------------------------------' 89 | Write-Output "VMs to add after job creation: '$($VMsToProtect.Count)'" 90 | 91 | #Adding VMs to jobs 92 | for ($v = $VMsToProtect.Count; $v -gt 0; $v--) { 93 | 94 | if ($ExistingJobs.Count -gt 0) { 95 | 96 | $EachJob = $ExistingJobs[0] 97 | $VBRJob = Get-VBRJob -Name $($EachJob.Name) 98 | 99 | for ($j = $EachJob.VMCount; $j -lt $MaxJobVMs; $j++) { 100 | 101 | if ($VMsToProtect.Count -gt 1) { 102 | Add-VBRViJobObject -Job $VBRJob -Entities $VMsToProtect[0] | Out-Null 103 | $VMsToProtect.RemoveAt(0) 104 | Write-Output "Added VM: '$($VMsToProtect[0].Name)' to Job: '$($VBRJob.Name)'" 105 | } 106 | 107 | } 108 | 109 | $ExistingJobs.RemoveAt(0) 110 | 111 | } 112 | 113 | } 114 | 115 | } #end process block 116 | 117 | end { 118 | 119 | Write-Output '------------------------------------------' 120 | Write-Output "$($VMName.Count) new VMs added to jobs" 121 | Write-Output "$AdditionalJobsRequired new jobs cloned" 122 | 123 | Disconnect-VBRServer 124 | Remove-PSSnapin -Name VeeamPSSnapIn 125 | 126 | } #end end block 127 | 128 | } -------------------------------------------------------------------------------- /Session2/Session2Scripts&Demos.md: -------------------------------------------------------------------------------- 1 | # Session 2 Scripts & Demos 2 | 3 | ## Demo 1 4 | 5 | This script is a simple example of the workflow for getting a restore point of a Veeam Computer backup job (new terminology for Agent job within PowerShell), then leveraging the new "Start-VBRViComputerInstantRecovery" cmdlet to restore this Veeam Agent backup as a vSphere VM. 6 | 7 | ## Demo 2 8 | 9 | This is a simple script to show the new NAS cmdlets within Veeam v10, followed by creating a NAS backup job. 10 | 11 | The following required components are created in this walk-through: 12 | 13 | - NAS Proxy (lines 14 & 15) 14 | - NAS SMB Server (line 17 - uses already existing credentials within Veeam B&R) 15 | - NAS Backup Job Object (line 19) 16 | - NAS Backup Job (line 21) 17 | 18 | The script then displays the job object, NAS proxy, and cache repository used. 19 | 20 | ## Script 3 21 | 22 | The script shown on screen and referenced in the demo video can be found here: 23 | 24 | [BR-DataIntegrationAPI](https://github.com/VeeamHub/powershell/tree/master/BR-DataIntegrationAPI) 25 | 26 | The specific script displayed on-screen is "VBR-DataIntegrationAPI-singlevirtualmachine-lastrestorepoint.ps1" 27 | 28 | ## Script 4 29 | 30 | This script demonstrates the creation of an advanced multi-host Veeam Virtual Lab via PowerShell, leveraging vSphere Distributed Virtual Switches. 31 | 32 | In the current format it is written out to make the variable use for names of the objects used fairly easy to follow, along with specifying IPs for remapping/masquerade, and static IP mappings. 33 | 34 | It then gathers details of the datastores, source & destination host networks, and the destination distributed virtual switch. 35 | 36 | A new proxy appliance, network mapping rules, network options, static IP mapping rules, and finally the Advanced Virtual Lab are all created in lines 61-79 (lines split for easier readability on the screen) 37 | 38 | ## Demo 5 39 | 40 | This script is a simple demo of the new licensing cmdlets released within Veeam v10, which was a common request from customers for assistance. 41 | 42 | ## Demo 6 43 | 44 | This script is a basic function which gathers details of Veeam backup jobs for easy comparison of settings & compliance. 45 | 46 | This output will be also used in the script. 47 | 48 | ## Demo 7 49 | 50 | This script is a basic function which takes the job configuration details gathered in the last script and will run a comparison of settings, based on a specified "reference job" name. 51 | 52 | The output of this script will give a simple true/false view of whether the configuration of each backup job matches to the same setting of the "reference job". 53 | 54 | ## Script 8 55 | 56 | This basic script shows some examples of setting job options (lines 9-18) such as: 57 | 58 | - Number of restore points for retention policy 59 | - Enabling VM deletion and number of days for maintenance 60 | - Setting day of week for synthetic full backups 61 | - SNMP notifications 62 | - Email notifications & addresses to notify 63 | - VM attribute to be used for successful backup details 64 | - Backup from storage snapshots 65 | 66 | The script also covers setting VSS options (lines 21-46) such as: 67 | 68 | - Enabling VSS options 69 | - Setting application-aware processing to "Require successful processing" 70 | - Disabling automatic selection of backup proxy, and setting job proxy 71 | - Setting VSS credentials, and setting the guest interaction proxy 72 | - Job scheduling of daily run (not a VSS specific setting) 73 | 74 | The last section of this script covers a few specific settings all together (lines 48-76): 75 | 76 | - Number of restore points 77 | - Scheduled run every 6 hours 78 | - Setting a backup window to terminate running jobs from 6AM to 5PM (comment-block section, lines 68-76) 79 | 80 | ## Demo 9 81 | 82 | This basic script shows some examples of cloning a Veeam backup job, then copying job options from a second source job. 83 | 84 | ## Script 10 85 | 86 | These are two scripts written based on a customer request to show how to leverage some basic Veeam PowerShell & PowerCLI to deploy VMs via IP range. 87 | 88 | The "QueryVMs" script will use PowerCLI to query vCenter for VMs where the guest IP address matches a specific network octet string, and export to a CSV file. 89 | 90 | The "CreateProtectionGroup" scope creates an Agent Protection group based on the CSV file from the "QueryVMs" script, and a Computer Backup job for this protection group. The parameters used are specific to a Linux computer backup job, rather than a Windows job as in session 1. 91 | 92 | ## Script 11 93 | 94 | This script is a function which will take input from a Veeam ONE alert (warning or error for a backup job state or agent backup job state). It will then connect to a Veeam Backup & Replication server over PowerShell Remoting, and query for details of the task session and the failed VM or agent from the last job run. 95 | 96 | This was based on a customer request to send to an internal API for opening tickets for each specific host based on backup alerts, so some specific API usage has been sanitized from the end block. 97 | 98 | ## Scripts for Veeam ONE 99 | 100 | The scripts mentioned within the demo video for Veeam ONE alarm notifications can be found on VeeamHub: 101 | 102 | - [Notifications to Slack](https://github.com/VeeamHub/powershell/tree/master/VONE-Notifications/veeam_one-notification-to-slack) 103 | - [Notifications to MSTeams](https://github.com/VeeamHub/powershell/tree/master/VONE-Notifications/veeam_one-notification-to-teams) 104 | - [Creating/resolving tickets in ServiceNow](https://github.com/VeeamHub/powershell/tree/master/VONE-ServiceNow) 105 | 106 | ## Demo 12 107 | 108 | This is a repeat of a simple script to demonstrate creating a "shell" job within Veeam Backup & Replication. It was shown in session 1, but is also used to create the demo job used for script 13. 109 | 110 | _NOTE:_ You must add a VM to a job at creation, then you can delete the job object afterwards. For this purpose, I typically target my VCSA (vCenter) VM, as I know that it will exist within the environment to add to the job. 111 | 112 | **__Additional Note:__** This method to create a "shell" job will still not get you around the requirement within the GUI for there to be a VM that exists within a job, similar to creating a job within PowerShell. You will need to avoid clicking the "Virtual Machines" tab on the job within the GUI, or else you will need to remove the job object again. 113 | 114 | ## Demo 13 115 | 116 | These three simple scripts show how we can use some simple PowerShell code and text files for some basic job object management. 117 | 118 | The first script will add the VMs listed within a text file to a Veeam backup job. 119 | 120 | The second script will set exclusions for the VMs listed within a text file to a Veeam backup job. 121 | 122 | The third script will remove the VMs listed within a text file from a Veeam backup job. 123 | 124 | ## Demo 14 125 | 126 | The two scripts shown here are essentially the same code as scripts 6 & 7 from earlier in this session. 127 | 128 | The minor changes made here to demonstrate some more advanced PowerShell toolmaking concepts are: 129 | 130 | - Leveraging a basic PowerShell module for ease of distributing code, which is two separate functions in this demo 131 | - Adding a PowerShell formatting file to specify a default view (defines how to display specific properties of our custom object) 132 | 133 | ## Demo 15 134 | 135 | This script is a basic example of how to leverage PowerShell to set a VM name to initiate a QuickBackup for a VM. 136 | 137 | This code which was created by simply walking through the Veeam Enterprise Manager API to get hierarchy object and VM object references, along with the managing Veeam server entity. These details are then used to run the POST method for a Quick Backup. 138 | 139 | ## Script 16 140 | 141 | This script is a simple example of the workflow for setting a Scale-Out Backup Repository (SOBR) to enable an S3 repository as the capacity tier, followed by starting a Veeam restore to Amazon EC2. 142 | 143 | For enabling the SOBR capacity tier, the following required components are covered in this walk-through: 144 | 145 | - Add Amazon account & create S3 connection (lines 2 & 3) 146 | - Get S3 region & bucket (lines 4 & 5) 147 | - Create S3 folder (line 6) 148 | - Add the S3 object repository (line 7) 149 | - Get the SOBR, add the new S3 repository, and enable capacity tier (lines 9-10) 150 | 151 | For the Veeam restore to Amazon EC2, the following required components are covered in this walk-through: 152 | 153 | - Getting a Veeam restore point (line 13) 154 | - Getting an Amazon account, EC2 region and EC2 instance type (lines 14-16) 155 | - Creating an array of EC2 disk configurations for the source VM disks (lines 18-22) 156 | - Getting an Amazon EC2 VPC, security group, and subnet (lines 24-26) 157 | - Creating a new EC2 proxy appliance (line 27) 158 | - Performing the Veeam restore to EC2 (lines 29-31; lines split for easier readability on the screen)) 159 | 160 | ## Script 17 161 | 162 | This script is a simple example of the workflow for starting a Veeam restore to Azure. 163 | 164 | For the Veeam restore to Azure, the following required components are covered in this walk-through: 165 | 166 | - Getting a Veeam restore point (line 1) 167 | - Getting an Azure account, subscription, storage account, location, VM size, virtual network & subnet, and resource group (lines 2-9) 168 | - Performing the Veeam restore to Azure (lines 12-14; lines split for easier readability on the screen)) 169 | 170 | ## Demo 18 171 | 172 | These two scripts contain functions for finding VMs missing from Veeam backups, and automatically adding them to Veeam jobs. 173 | 174 | The "Find-UnprotectedVMs" script contains a function which will query a vCenter server to gather all registered VMs, then return VMs not backed up by a specific Veeam B&R server (this is just a function which contains the relevant code covered in Script #14 from Session 1, and returns a PSCustomObject with details of the missing VMs) 175 | 176 | The "Protect-MissingVMs" script contains a function will calculate the required number of Veeam backup jobs with a specified name prefix to backup VMs, until it reaches the specified maximum number of VMs per job. If additional jobs are required, it create additional jobs cloned from the highest number job matching the specified name prefix, and will set the job options from the same source job. It will then add VMs to each of the Veeam backup jobs with the specified name prefix, until the defined maximum number of VMs per job is reached. 177 | 178 | ## Script 19 179 | 180 | These two scripts contain functions which will launch restore sessions and gather details of the restore points, databases, and database files which match the specified parameters. 181 | 182 | There are separate scripts containing functions for MS SQL and Oracle, and these have been made available on VeeamHub as [BR-DatabaseReports](https://github.com/VeeamHub/powershell/tree/master/BR-DatabaseReports) 183 | -------------------------------------------------------------------------------- /Session2/VMsFromTextFile/AddVMs.txt: -------------------------------------------------------------------------------- 1 | veeamv102 2 | veeamv103 3 | veeamv104 4 | veeamv105 -------------------------------------------------------------------------------- /Session2/VMsFromTextFile/MaintenanceVMs.txt: -------------------------------------------------------------------------------- 1 | veeamv103 2 | veeamv104 -------------------------------------------------------------------------------- /Session2/VMsFromTextFile/RemoveVMs.txt: -------------------------------------------------------------------------------- 1 | veeamv104 2 | veeamv105 -------------------------------------------------------------------------------- /Session2/VeeamJobConfigs/Binaries/Veeam.JobQuickConfig.format.ps1xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Default 6 | 7 | Veeam.JobQuickConfig 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | Name 32 | 33 | 34 | Scheduled 35 | 36 | 37 | BackupMode 38 | 39 | 40 | FullEnabled 41 | 42 | 43 | RestorePoints 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Session2/VeeamJobConfigs/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Joe Houghes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Session2/VeeamJobConfigs/Public/Compare-VeeamJobConfiguration.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 4 2 | #Requires -RunAsAdministrator 3 | 4 | function Compare-VeeamJobConfiguration { 5 | <# 6 | .Synopsis 7 | Simple Veeam report to compare job configurations 8 | .Notes 9 | Version: 0.2 10 | Author: Joe Houghes 11 | Modified Date: 5-24-2020 12 | .EXAMPLE 13 | Get-VeeamJobConfiguration -VBRServer ausveeambr -OutVariable JobConfig; Compare-VeeamJobConfiguration -ReferenceJobName 'AUSVCENTER-NoTag' -VBRJobConfig $JobConfig 14 | #> 15 | 16 | 17 | [CmdletBinding()] 18 | Param 19 | ( 20 | [Parameter( Mandatory = $true)] 21 | [string] 22 | $ReferenceJobName, 23 | 24 | [Parameter( Mandatory = $true, ValueFromPipeline)] 25 | [PSTypeName('Veeam.JobQuickConfig')] 26 | $VBRJobConfig 27 | ) 28 | 29 | begin { 30 | 31 | Write-Output '' 32 | if (!($PSBoundParameters.ReferenceJobName -in $VBRJobConfig.Name)) { 33 | throw "Failed to find backup job with name: $ReferenceJobName" 34 | } 35 | 36 | } 37 | 38 | process { 39 | 40 | $ReferenceObject = $VBRJobConfig | Where-Object { $PSItem.Name -eq $PSBoundParameters.ReferenceJobName } 41 | $DiffObject = $VBRJobConfig | Where-Object { $PSItem.Name -ne $PSBoundParameters.ReferenceJobName } 42 | 43 | $Properties = $ReferenceObject.PSObject.Properties.Name | Where-Object { $PSItem -ne 'Name' } 44 | 45 | [System.Collections.ArrayList]$CompareJobOutput = @() 46 | 47 | foreach ($RefJob in $ReferenceObject) { 48 | 49 | $RefJobDetails = [PSCustomObject] @{ } 50 | $RefJobDetails = $RefJobDetails | Select-Object Name 51 | 52 | $RefJobDetails.Name = $RefJob.Name 53 | 54 | foreach ($EachProperty in $Properties) { 55 | $Value = 'REFJOB' 56 | 57 | $PropName = $($EachProperty + "Match") 58 | $RefJobDetails = $RefJobDetails | Select-Object *, $PropName 59 | $RefJobDetails.$PropName = $Value 60 | } #end foreach property 61 | 62 | $null = $CompareJobOutput.Add($RefJobDetails) 63 | Remove-Variable RefJobDetails 64 | 65 | }# end foreach refjob 66 | 67 | 68 | foreach ($DiffJob in $DiffObject) { 69 | 70 | $CompareJobDetails = [PSCustomObject] @{ } 71 | $CompareJobDetails = $CompareJobDetails | Select-Object Name 72 | 73 | $CompareJobDetails.Name = $DiffJob.Name 74 | 75 | foreach ($EachProperty in $Properties) { 76 | $Value = [bool]($($DiffJob.$EachProperty) -eq $($ReferenceObject.$EachProperty)) 77 | 78 | $PropName = $($EachProperty + "Match") 79 | $CompareJobDetails = $CompareJobDetails | Select-Object *, $PropName 80 | $CompareJobDetails.$PropName = $Value 81 | } #end foreach property 82 | 83 | $null = $CompareJobOutput.Add($CompareJobDetails) 84 | Remove-Variable CompareJobDetails 85 | 86 | }# end foreach diffjob 87 | 88 | } 89 | 90 | 91 | end { 92 | 93 | Write-Output $CompareJobOutput 94 | 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /Session2/VeeamJobConfigs/Public/Get-VeeamJobConfiguration.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Version 4 2 | #Requires -RunAsAdministrator 3 | function Get-VeeamJobConfiguration { 4 | <# 5 | .Synopsis 6 | Simple Veeam report to export quick job configurations 7 | .Notes 8 | Version: 0.2 9 | Author: Joe Houghes 10 | Modified Date: 5-24-2020 11 | .EXAMPLE 12 | Get-VeeamJobConfiguration -VBRServer ausveeambr | Export-CSV D:\temp\VeeamJobConfigDetails.csv 13 | #> 14 | 15 | [OutputType('Veeam.JobQuickConfig')] 16 | [CmdletBinding()] 17 | Param 18 | ( 19 | [Parameter( 20 | Mandatory = $false, 21 | Position = 0)] 22 | [string] 23 | $VBRServer = 'localhost' 24 | 25 | ) 26 | 27 | begin { 28 | 29 | #Load the Veeam PSSnapin 30 | if (!(Get-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue)) { 31 | Add-PSSnapin -Name VeeamPSSnapIn 32 | Connect-VBRServer -Server $VBRServer 33 | } 34 | 35 | else { 36 | Disconnect-VBRServer 37 | Connect-VBRServer -Server $VBRServer 38 | } 39 | 40 | # Get Backup Jobs & Repositories 41 | $CompareJobs = [Veeam.Backup.Core.CBackupJob]::GetByType('Backup') 42 | $Repositories = [Veeam.Backup.Core.CBackupRepository]::GetAll() 43 | 44 | } 45 | 46 | process { 47 | 48 | [System.Collections.ArrayList]$JobDetails = @() 49 | 50 | # Loop through each job adding details to array 51 | foreach ($EachJob in $CompareJobs) { 52 | 53 | $Repository = ($Repositories | Where-Object { $_.HostId -eq $EachJob.TargetHostId -and $_.Path -eq $EachJob.TargetDir }).Name 54 | 55 | $JobProxies = $EachJob.GetSourceViProxies().Name -join ';' 56 | 57 | if ($EachJob.BackupTargetOptions.TransformFullToSyntethic -OR $EachJob.BackupTargetOptions.TransformIncrementsToSyntethic -OR $EachJob.BackupStorageOptions.EnableFullBackup) { 58 | $FullEnabled = $true 59 | } else { 60 | $FullEnabled = $false 61 | } 62 | 63 | switch ($EachJob.BackupStorageOptions.CompressionLevel) { 64 | '5' { $Compression = 'Optimal' } 65 | '4' { $Compression = 'Dedupe-friendly' } 66 | '0' { $Compression = 'None' } 67 | '6' { $Compression = 'High' } 68 | '9' { $Compression = 'Extreme' } 69 | } 70 | 71 | switch ($EachJob.BackupStorageOptions.StgBlockSize) { 72 | 'KbBlockSize1024' { $Optimization = 'Local Target' } 73 | 'KbBlockSize8192' { $Optimization = 'Local Target(16TB+ Files)' } 74 | 'KbBlockSize512' { $Optimization = 'LAN Target' } 75 | 'KbBlockSize256' { $Optimization = 'WAN Target' } 76 | } 77 | 78 | switch ($EachJob.VssOptions.GuestFSIndexingType) { 79 | 'EveryFolders' { $IndexGuest = "Enabled" } 80 | 'None' { $IndexGuest = "Disabled" } 81 | } 82 | 83 | $JobConfig = [PSCustomObject] @{ 84 | PSTypeName = 'Veeam.JobQuickConfig' 85 | Name = $EachJob.Name 86 | Scheduled = $EachJob.IsScheduleEnabled 87 | BackupMode = $EachJob.BackupTargetOptions.Algorithm 88 | FullEnabled = $FullEnabled 89 | AutoProxy = $EachJob.SourceProxyAutoDetect 90 | Proxies = $JobProxies 91 | Repository = $Repository 92 | RestorePoints = $EachJob.BackupStorageOptions.RetainCycles 93 | Deduplication = $EachJob.BackupStorageOptions.EnableDeduplication 94 | Compression = $Compression 95 | StorageOptimization = $Optimization 96 | RemoveDeletedVMs = $EachJob.BackupStorageOptions.EnableDeletedVmDataRetention 97 | DeletedVMRetention = $EachJob.BackupStorageOptions.RetainDays 98 | CBTEnabled = $EachJob.ViSourceOptions.UseChangeTracking 99 | QuiesceVMTools = $EachJob.ViSourceOptions.VMToolsQuiesce 100 | IntegrityChecks = $EachJob.BackupStorageOptions.EnableIntegrityChecks 101 | SetVMNotes = $EachJob.ViSourceOptions.SetResultsToVmNotes 102 | VMAttribute = $EachJob.ViSourceOptions.VmAttributeName 103 | VSSEnabled = $EachJob.VssOptions.Enabled 104 | IndexGuestFS = $IndexGuest 105 | } #end pscustom object 106 | 107 | $Null = $JobDetails.Add($JobConfig) 108 | 109 | } #end foreach job 110 | 111 | } 112 | 113 | 114 | end { 115 | 116 | Write-Output $JobDetails 117 | 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /Session2/VeeamJobConfigs/VeeamJobConfigs.psd1: -------------------------------------------------------------------------------- 1 | # 2 | # Module manifest for module 'VeeamJobConfigs' 3 | # 4 | # Generated by: Joe Houghes 5 | # 6 | # Generated on: 5/31/2020 7 | # 8 | 9 | @{ 10 | 11 | # Script module or binary module file associated with this manifest. 12 | RootModule = 'VeeamJobConfigs.psm1' 13 | 14 | # Version number of this module. 15 | ModuleVersion = '0.0.0.1' 16 | 17 | # Supported PSEditions 18 | # CompatiblePSEditions = @() 19 | 20 | # ID used to uniquely identify this module 21 | GUID = 'a87fc9f1-2b4b-4657-a903-a28a69c84ba8' 22 | 23 | # Author of this module 24 | Author = 'Joe Houghes' 25 | 26 | # Company or vendor of this module 27 | CompanyName = 'Unknown' 28 | 29 | # Copyright statement for this module 30 | Copyright = '(c) 2020 Joe Houghes. All rights reserved.' 31 | 32 | # Description of the functionality provided by this module 33 | Description = 'Quick Demo of Module to Report on Veeam Job Configs & Differences' 34 | 35 | # Minimum version of the Windows PowerShell engine required by this module 36 | # PowerShellVersion = '' 37 | 38 | # Name of the Windows PowerShell host required by this module 39 | # PowerShellHostName = '' 40 | 41 | # Minimum version of the Windows PowerShell host required by this module 42 | # PowerShellHostVersion = '' 43 | 44 | # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 45 | # DotNetFrameworkVersion = '' 46 | 47 | # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. 48 | # CLRVersion = '' 49 | 50 | # Processor architecture (None, X86, Amd64) required by this module 51 | # ProcessorArchitecture = '' 52 | 53 | # Modules that must be imported into the global environment prior to importing this module 54 | # RequiredModules = @() 55 | 56 | # Assemblies that must be loaded prior to importing this module 57 | # RequiredAssemblies = @() 58 | 59 | # Script files (.ps1) that are run in the caller's environment prior to importing this module. 60 | # ScriptsToProcess = @() 61 | 62 | # Type files (.ps1xml) to be loaded when importing this module 63 | # TypesToProcess = @() 64 | 65 | # Format files (.ps1xml) to be loaded when importing this module 66 | FormatsToProcess = @('Binaries/Veeam.JobQuickConfig.format.ps1xml') 67 | 68 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess 69 | # NestedModules = @() 70 | 71 | # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. 72 | FunctionsToExport = '*' 73 | 74 | # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. 75 | CmdletsToExport = '*' 76 | 77 | # Variables to export from this module 78 | VariablesToExport = '*' 79 | 80 | # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. 81 | AliasesToExport = '*' 82 | 83 | # DSC resources to export from this module 84 | # DscResourcesToExport = @() 85 | 86 | # List of all modules packaged with this module 87 | # ModuleList = @() 88 | 89 | # List of all files packaged with this module 90 | # FileList = @() 91 | 92 | # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. 93 | PrivateData = @{ 94 | 95 | PSData = @{ 96 | 97 | # Tags applied to this module. These help with module discovery in online galleries. 98 | # Tags = @() 99 | 100 | # A URL to the license for this module. 101 | # LicenseUri = '' 102 | 103 | # A URL to the main website for this project. 104 | # ProjectUri = '' 105 | 106 | # A URL to an icon representing this module. 107 | # IconUri = '' 108 | 109 | # ReleaseNotes of this module 110 | # ReleaseNotes = '' 111 | 112 | } # End of PSData hashtable 113 | 114 | } # End of PrivateData hashtable 115 | 116 | # HelpInfo URI of this module 117 | # HelpInfoURI = '' 118 | 119 | # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. 120 | # DefaultCommandPrefix = '' 121 | 122 | } 123 | 124 | 125 | -------------------------------------------------------------------------------- /Session2/VeeamJobConfigs/VeeamJobConfigs.psm1: -------------------------------------------------------------------------------- 1 | $functionFolders = @('Public', 'Internal', 'Classes') 2 | ForEach ($folder in $functionFolders) 3 | { 4 | $folderPath = Join-Path -Path $PSScriptRoot -ChildPath $folder 5 | If (Test-Path -Path $folderPath) 6 | { 7 | Write-Verbose -Message "Importing from $folder" 8 | $functions = Get-ChildItem -Path $folderPath -Filter '*.ps1' 9 | ForEach ($function in $functions) 10 | { 11 | Write-Verbose -Message " Importing $($function.BaseName)" 12 | . $($function.FullName) 13 | } 14 | } 15 | } 16 | $publicFunctions = (Get-ChildItem -Path "$PSScriptRoot\Public" -Filter '*.ps1').BaseName 17 | Export-ModuleMember -Function $publicFunctions 18 | --------------------------------------------------------------------------------