Set custom Teams backgrounds with Powershell

I got a request at work that it would be nice if users already have got some of the companies custom teams background that they can select as their background in a meeting. They wouldn’t have to upload the images themselves but they would already be in teams to select. It also should be easy to add new custom backgrounds if needed. So I made a powershell script with a colleague of mine that would do this. In this post I will show you how this script works and you can use it yourself.

There is an user voice about this topic, but until teams doesn’t have such a feature you can use this script to get backgrounds added in teams for users.

Create network folders for content

In order for the powershell script to work you will need 2 folders on a netwerkshare that can be accessible for the users where you want to deploy the backgrounds to (read only).

Lets name them:

Set-Teams-Backgrounds (for the content needed to run the script)
Teams-Backgrounds (for the images to distribute as teams backgrounds)

The images that you will place in Teams-Backgrounds will have some requirements:

  • Minimum size: 360 x 360 pixels
  • Maximum size: 2048 x 2048 pixels
  • File type: jpeg, png, bmp
  • Aspect ratio: Greater than 4

Set teams Backgrounds script

The powershell script SetTeamsBackgrounds.ps1 wil do the following actions:

  1. Create the variables need for the script to run. (You will only have to change the $sourcefolder variable to the Teams-Backgrounds folder created above.)
  2. Checks if the logfolder is present, if not it will create the logfolder and a logfile (%localappdata%\Logs\BG-copy.log).
  3. Create the writelog function.
  4. Checks if teams is already started once before by the user (%appdata%\Microsoft\Teams), if not the script will do nothing.
  5. If teams is started once before it will check if the background folder is present (%appdata%\Microsoft\Teams\Background), if not it will be created.
  6. Checks if the Uploads folder is present, if not it will be created. (%appdata%\Microsoft\Teams\Background\Uploads)
  7. Checks if the device is connected to your corporate network.
  8. If the device is within the coporate network it will copy the background images from the folder on the share to the teams background location of the user.
  9. It will write important information in the log. (%localappdata%\Logs\BG-copy.log)
# Script to copy companies teams backgrounds to users %appdata%\Microsoft\Teams\Backgrounds.
# Created by: Remy Kuster
# Website: www.iamsysadmin.eu
# Modified by: Remco Janssen (19-01-2021)
# Creation date: 13-01-2021

# Create variables

$sourcefolder = "{put your networkfolder here}" # Set the share and folder where you put the custom backgrounds
$TeamsStarted = "$env:APPDATA\Microsoft\Teams"
$DirectoryBGToCreate = "$env:APPDATA\Microsoft\Teams\Backgrounds"
$Uploadfolder = "$env:APPDATA\Microsoft\Teams\Backgrounds\Uploads"
$Logfile = "$env:LOCALAPPDATA\Logs\BG-copy.log"
$Logfilefolder = "$env:LOCALAPPDATA\Logs"

# Create logfile and function

# Check if %localappdata%\Logs is present, if not create folder and logfile

if (!(Test-Path -LiteralPath $Logfilefolder -PathType container)) 
    {
    
        try 
            {
                New-Item -Path $Logfilefolder -ItemType Directory -ErrorAction Stop | Out-Null #-Force
                New-Item -Path $Logfilefolder -Name "BG-copy.log" -ItemType File -ErrorAction Stop | Out-Null #-Force

                Start-Sleep -s 10

            }

        catch 

            {
                Write-Error -Message "Unable to create directory '$Logfilefolder' . Error was: $_" -ErrorAction Stop    
            }

    "Successfully created directory '$Logfilefolder' ."

    }

else 

    {
        "Directory '$Logfilefolder' already exist"
    }

# Clear the logfile before starting

Clear-Content $Logfile

# Create the logwrite function

Function LogWrite
{
   Param ([string]$logstring)
   $Stamp = (Get-Date).toString("dd/MM/yyy HH:mm:ss")
    $Line = "$Stamp $logstring"
 
   Add-content $Logfile -value $Line
}

# Check if teams is started once before for current user

if ( (Test-Path -LiteralPath $TeamsStarted) ) 
    { 
        logwrite "Teams started once before by the current user."
    }

else

    {
        logwrite "Teams has never been started by user"
        Exit 1
    }

# Check if %appdata%\Microsoft\Teams\Background is present, if not create folder

if (!(Test-Path -LiteralPath $DirectoryBGToCreate -PathType container)) 
    {
    
        try 
            {
                New-Item -Path $DirectoryBGToCreate -ItemType Directory -ErrorAction Stop | Out-Null #-Force
            }
        catch 
            {
                Write-Error -Message "Unable to create directory '$DirectoryBGToCreate' . Error was: $_" -ErrorAction Stop    
            }

    logwrite "Successfully created directories '$DirectoryBGToCreate' ."
    }

else 
    {
        logwrite "Directory '$DirectoryBGToCreate' already exist"
    }

# Check if %appdata%\Microsoft\Teams\Background\Uploads is present, if not create folder

if (!(Test-Path -LiteralPath $Uploadfolder -PathType container)) 
    {
    
        try 
            {
                New-Item -Path $Uploadfolder -ItemType Directory -ErrorAction Stop | Out-Null #-Force
            }
        catch 
            {
                Write-Error -Message "Unable to create directory '$Uploadfolder' . Error was: $_" -ErrorAction Stop    
            }

     logwrite "Successfully created directories '$Uploadfolder' ."
    }

else 
    {
        logwrite "Directory '$Uploadfolder' already exist"
    }

# Check if machine is connected to your corporate network

#$getoutput = (Test-Connection -ComputerName (hostname) -Count 1).IPV4Address.IPAddressToString # process active IP-address
$getoutput = Get-NetIPAddress -AddressFamily IPv4 | Out-String -stream | Select-String -Pattern "IPAddress" # process IP-address list

# You can multiple adres ranges if your company has got vpn, wireless and physical different subnets. 
# This because we don't want to start the copy action from the share if the device is not connected to the corperate network.

if (($getoutput -like '*192.168.*.*') -or ($getoutput -like '*10.10.*.*') -or ($getoutput -like '*140.*.*.*'))

    {
        logwrite "Corporate network detected"
        $connected="YES"
    }
else
    {
        logwrite "Corporate network not detected"
        logwrite "Copy action of uploads folder from share not started"
        Exit 1
    }

# copy content from share to teams background location

if($connected -eq "YES")
    {
        logwrite "Start copy action of uploads folder from share"
        $sourcefiles = (Get-ChildItem -Path $sourcefolder -erroraction SilentlyContinue).Name
        
        if($sourcefiles -ne $null)

        {
        
        foreach($sourcefile in $sourcefiles)
            {
                if(!(Test-Path $Uploadfolder\$sourcefile))
                    {
                        Copy-Item -Path $sourcefolder\$sourcefile -Destination $Uploadfolder\$sourcefile -Recurse -Force
                        if(Test-path -Path "$Uploadfolder\$sourcefile")
                            {
                                logwrite "File $sourcefile was copied"
                            }
                        else
                            {
                                logwrite "Failed to copy file $sourcefile"
                                Exit 1
                            }
                    }
                else
                    {
                        logwrite "File $sourcefile already exists"
                    }            
                            
            }
        }

        else

        {
        logwrite "Failed to connect to $sourcefolder "
        }
    }

You can download the script and additional files to run the script completely silent from my GitHub repository.
The run-silent.vbs and the shortcut to the powershell script are needed to run the script completely silent, the xml is for the creation of the task we will create on the device to run the script at an interval. If you want to modify task settings like the task run interval you can edit the SetTeamsBGTask.xml.

Place al the content in the network folder Set-Teams-Backgrounds.

Set Teams Backgrounds task script

In order to create a scheduled task with the currently logged on user, we will copy the content needed for the script locally to the device.

In order to achieve this we will use a powershell script to set the task and a remove task powershell script:

Set-Teams-Backgrounds-task

# Script to copy content for task creation to run powershell script.
# Created by: Remy Kuster
# Website: www.iamsysadmin.eu
# Creation date: 02-07-2021

# Create variables

$sourcefolder = "{\\share-to-content-folder-Set-Teams-Backgrounds}" #Enter the share to the folder where the content of the script will be in (Set-Teams-Backgrounds).
$DirectorySetTBGToCreate = "$env:ProgramData\Set-Teams-Backgrounds"
$taskName = "SetTeamsBGTask-$Env:UserName"
$taskExists = Get-ScheduledTask | Where-Object {$_.TaskName -like $taskName }
$MECMDetectionFolder = "$env:LOCALAPPDATA\Set-Teams-BG-task-done"
$MECMDetecionFile = "Set-Teams-BG-task-done.txt"

# Check if $env:ProgramData\Set-Teams-Backgrounds is present, if not create folder

if (!(Test-Path -LiteralPath $DirectorySetTBGToCreate -PathType container)) 
    {
    
        try 
            {
                New-Item -Path $DirectorySetTBGToCreate -ItemType Directory -ErrorAction Stop | Out-Null #-Force
            }
        catch 
            {
                Write-Host -Message "Unable to create directory '$DirectorySetTBGToCreate' . Error was: $_" -ErrorAction Stop    
            }

    Write-Host "Successfully created directories '$DirectorySetTBGToCreate' ."
    }

else 
    {
        Write-Host "Directory '$DirectorySetTBGToCreate' already exist"
    }

# copy content from share to Set-Teams-Backgrounds folder

        Write-Host "Start copy action of uploads folder from share"
        $sourcefiles = (Get-ChildItem -Path $sourcefolder -erroraction SilentlyContinue).Name
        
        if($sourcefiles -ne $null)

        {
        
        foreach($sourcefile in $sourcefiles)
            { if(!(Test-Path $DirectorySetTBGToCreate\$sourcefile))

                       {
                        Copy-Item -Path $sourcefolder\$sourcefile -Destination $DirectorySetTBGToCreate\$sourcefile -Recurse -Force
                        if(Test-path -Path "$DirectorySetTBGToCreate\$sourcefile")
                            {
                                Write-Host "File $sourcefile was copied"
                            }
                        else
                            {
                                Write-Host "Failed to copy file $sourcefile"
                                Exit 1
                            }
                    }
                else
                    {
                        Write-Host "File $sourcefile already exists"
                    }            
                            
            }

                        }
            
        else

        {
        Write-Host "Failed to connect to $sourcefolder"
        exit
        }

Start-Sleep -s 10

# Create the task

if(!($taskExists)) {

                        Register-ScheduledTask -TaskName $taskName  -Xml (Get-Content "$env:ProgramData\Set-Teams-Backgrounds\SetTeamsBGTask.xml" | Out-String) -Force

                        Start-Sleep -s 10
    
                  } 

else  

    { 

 Write-Host "$taskName already exists"
   exit
    
    }

#check if task has been created
$taskExists = Get-ScheduledTask | Where-Object {$_.TaskName -like $taskName}

 if(!($taskExists)) {

 Write-Host "$taskName creation failed"
    
                    } 
                    
                        else 
                        
                        {

                          Write-Host "$taskName created"

                          #Start the task


                         Start-ScheduledTask -TaskName "$taskName"

                        #Create the folder for MECM detection methode


                        new-item -itemtype "directory" -path $MECMDetectionFolder -erroraction SilentlyContinue

   
                         #Create the txt file for MECM detection methode


                        new-item $MECMDetectionFolder\$MECMDetecionFile -erroraction SilentlyContinue

                       }


Remove-Teams-Backgrounds-task

Remove-Item 'C:\ProgramData\Set-Teams-Backgrounds' -Recurse -force

Remove-Item $env:LOCALAPPDATA\Set-Teams-BG-task-done -Recurse -force

schtasks /delete /TN "SetTeamsBGTask"

Start-Sleep -s 10

exit

You can download the 2 scripts mentioned above from my GitHub repository.

Deploy the set Teams BG task with MECM

The last thing you have to do is to create an application of the set teams BG task script mentioned above. So that we can deploy this to all the users with a required deployment.

Extract the Set-Teams-Backgrounds-Task.zip to your content folder that you juse to create MECM applications.

Open your MECM console and go to \Software Library\Overview\Application Management\Applications.

Create a new application and select Manually specify the application information and click Next.

In the General information section enter the fields you want. In this case I added Name, Admin comments, Publisher, Software version and Admin categorie. Click Next.

In the Software Center section I won’t enter anything because this application will run hidden and will not be shown in Softwarecenter. But you can if you want. Click Next.

In the deployment type section, click Add.

Select the deployhmenttype type Script installer. Click Next.

Enter the name of the deploymenttype and click Next.

Set the Content location to the network folder where you put the content from the Set-Teams-Backgrounds-Task.zip.

Put this line in the Installation program:
powershell.exe -ExecutionPolicy bypass -WindowStyle Hidden -file Set-Teams-Backgrounds-task.ps1

Put this line in the Uninstall program:
powershell.exe -ExecutionPolicy bypass -WindowStyle Hidden -file Remove-Teams-Backgrounds-task.ps1

Click Next.

In the Detection methode section, select Use a custom script to detect the presence of this deployment type and click Edit.

Select Script type: PowerShell and place the script below in the Script contents and click OK.

$Path = "$env:LOCALAPPDATA\Set-RU-Teams-BG-task-done\Set-RU-Teams-BG-task-done.txt"

If (Test-Path $Path){ $true }

Click Next.

In the User Experience section set the Installation Behavior to: Install for user.
Set the Installation program visibility to: Hidden.
Set the allowed and estimated runtime and click Next.

In the Requirements section, click Next.

In the Dependencies section, click Next.

Confirm the settings for the deploymenttype and click Next.

Click Close.

You are now back in the Deployment Types section, click Next.

Confirm the settings for the application and click Next.

ClickClose.

By creating an application with detection based on a text file in the users appdata and deploy it to users, each user that logs in to a device will get this application. So the task to set the teams background is created for each user and will run every hour. So if content is added to the folder Teams-Backgrounds the script will copy the added content to the teams upload folder for backgrounds for each user that is logged on..

Deploy the application to an usercollection.

But make sure it is a required deployment and set Hide in Software Center and all notifications.

NOTE: The Teams app will have to be restarted to make the newly added backgrounds active.

What happens on the device?

After the application is installed:

You can check the AppEnforce.log to see if the deployed application is installed correctly.

The application did the following on the device:

It downloaded the content needed for the script SetTeamsBackgrounds.ps1 to run.

It also created the scheduled task named: SetTeamsBGTask-username that will run the SetTeamsBackgrounds.ps1 every hour.

For MECM to detect the application as installed the application also created the text file.

After the SetTeamsBackgrounds.ps1 had run:

It downloaded the background images to the teams upload folder.

It created a log.

Now the teams app has to be restarted and the teams background will be available for the user to select.

Now when another user logs on the device, the Set-Teams-BG-task-done.txt won’t exist so the application will be installed again. The task will be created once more and so will the logfile, the content is already there so won’t be copied again.

One thought on “Set custom Teams backgrounds with Powershell

  1. I noticed that when an other users logged on the device the task wasn’t created. This because the taskname already was used. So I added the $env:username to the creation of the taskname. Now every taskname will be unique.

    I changed the script on github and in the post.

Comments are closed.

Theme: Overlay by Kaira