Powershell - Exclude Teams object(s) from VBO Backup Job

  • 29 January 2021

Userlevel 2

Last year Veeam Backup for Microsoft Office 365 v5 added purpose-built backup and recovery for Microsoft Teams. Since then many customer and partners asked me "How can we protect all of our teams and exclude specific teams objects based on names automatically?".

As there is no filter logic within the UI for the Backup Job object exclusion list, I solved this "problem" using the script down below. First we store the credentials (encrypted) in a txt file:

$credential = Get-Credential
$credential.Password | ConvertFrom-SecureString | Set-Content <path to secure.txt>

And here's the script. Just change the values for the following variables: 

$organizationname Name of the tenant - Only needed if more than one is configured
$backupjob            Name of existing the Backup Job
$filter                    Name of the team that needs to be excluded. Regular expressions can be used
$userName            Username for retrieving the existing Teams in M365
$passwordText       Path to the secure.txt file that has been created in advance

#Some Variables
# $organizationname = "<tenant>"
$backupjob = "MS Teams Backup"
$org = Get-VBOOrganization #-Name $organizationname
$job = Get-VBOJob -Name $backupjob
$filter = "Test"

# Credentials
$userName = "<yourusername@here.com>"
$passwordText = Get-Content "<path to secure.txt>"

# Convert to secure string
$securePwd = $passwordText | ConvertTo-SecureString

# Create credential object
$credObject = New-Object System.Management.Automation.PSCredential -ArgumentList $userName, $securePwd

# Check and Import-Module
if ((Get-InstalledModule -Name "MicrosoftTeams" -ErrorAction SilentlyContinue) -eq $null) {
Install-Module MicrosoftTeams
if ((Get-InstalledModule -Name "ExchangeOnlineManagement" -ErrorAction SilentlyContinue) -eq $null) {
Install-Module ExchangeOnlineManagement
# Import
Import-Module MicrosoftTeams
Import-Module "C:\Program Files\Veeam\Backup365\Veeam.Archiver.PowerShell\Veeam.Archiver.PowerShell.psd1"
Connect-MicrosoftTeams -Credential $credObject
Connect-ExchangeOnline -UserPrincipalName $userName -Credential $credObject

$Teams = (Get-Team |Select GroupId, DisplayName)
#Test# Get-Team |Select GroupId, DisplayName | out-file -filepath C:\Scripts\teams_Dump.txt
ForEach ($T in $Teams) {
$TeamId = (Get-UnifiedGroup -ResultSize unlimited -Identity $T.GroupId | Select -ExpandProperty ExternalDirectoryObjectId)
$Team = Get-VBOOrganizationTeam -Organization $org -id $TeamId
$FilteredTeam = $Team.DisplayName -match "$filter"
if ($FilteredTeam) {
$exclTeam = New-VBOBackupItem -Team $Team
Add-VBOExcludedBackupItem -Job $Job -BackupItem $exclTeam

Write-Host "Excluded a total of " -NoNewline
Write-Host $exclTeam.count -NoNewline -ForegroundColor Green
Write-Host " Team Site(s) in the Backup Job " -NoNewline
Write-Host $backupjob -ForegroundColor Green

Disconnect-ExchangeOnline -Confirm:$false


Notes: - The MS Teams Powershell module is needed
          - Object type in Backup Job is Teams


Userlevel 1

You can add the following to your script to check for the module.

# Do not change below unless you know what you are doing
if ((Get-InstalledModule -Name "MicrosoftTeams" -ErrorAction SilentlyContinue) -eq $null) {
Install-Module MicrosoftTeams


Userlevel 6
Badge +2

Great stuff Steve and a nice addition Niel

Userlevel 7
Badge +4

Nice script @SteveHeart 

And your addition @nielsengelen is great, too.

With this I will build a query to distinguish the V10 powershell plugin and the V11 powershell module and load the correct one in my scripts… Did not look for this up to now, but your snippet should do the job with some modification.

Userlevel 2

I just updated the script, adding some community/customer feedback. One change is to use the Team id instead of the Team name, because the script ran into issues when there were Teams using the same name.