Deploy custom Microsoft Teams backgrounds, easily, with PowerShell and Intune

This one has been in my blog queue for a while. @stuffygibbon did a shout out on Twitter so I thought I’d bring this post forward and show you how you can deploy a PowerShell script from Intune to install a custom background for your Microsoft Teams users!

Custom Backgrounds for Teams?

Microsoft announced a new background feature within Microsoft Teams. Towards the end of March/beginning of April 2020 we were able to use custom backgrounds in our Microsoft Teams meetings – whaaaa I hear you cry!

What some eagle eyed cherries started to realise is that you could add your own backgrounds to Teams by placing your background/s in the following folder

%AppData%\Microsoft\Teams\Backgrounds\Uploads

The Next Level

That is a cool feature right there – but as Admins we always ask “How do I automate this for my users?

There are many ways to cook this beast, @stuffygibbon was using Intune so I pondered. Shall I just create a batch file and package it with an image using IntuneWinAppUtil to copy the image file to the users %AppData% folder? Sure – perfectly reasonable. But I want to show you another way – a way which means you DON’T have to repackage scripts and images each time you want to send out a new background to your Teams users.

I will show you how we can retrieve background images from a URL and put them in the users profile to be used as a custom background in a Teams meeting.

Q: “Ben – So you can package only PowerShell scripts using the Win32 Content Prep tool without a payload?” – YES! “And the Script (disguised as an app) will appear in the Company Portal?” – YES! “And you can pass parameters to the installation command line meaning you won’t need to modify and re-package the script each time you copy it to create a new app in Intune?” YES!

Let’s cook.

PowerShell

I wanted the solution to use a single script for both Install and Uninstall. I also didn’t want to have to re-write and re-package the script should I need to use it again. I should be able to create a new App in Intune and reuse the same Win32App again. In order to achieve this, I would need to specify the image name and URL as a parameter in the installation command line.

I also love the flexibility of using a Win32App to deploy my script. The script attempts to download a file using the Invoke-WebRequest method and I liked the idea that I could get the Intune Management Extension to retry deployment if it failed. I will set an exit code in the script on download failure and tell Intune to retry the script again if it see’s that exit code (Intune will attempt 3 retires every 5mins if you specify an exit code to force a retry)

I will need to pass 3 parameters to my script.

  1. Install or Uninstall
  2. Filename
  3. URL where the file is hosted *

* You may not want your corporate Teams Background to sit on a Public URL so consider using Azure Active Directory Application Proxy to host the image. You can find more about that here https://byteben.com/bb/azure-ad-application-proxy-accessing-your-internal-web-apps-from-the-internet/

So the script is fairly simple. I will deploy it as a Win32 App in the user context so I can target the %AppData% Environment Variable. Intune also supports the use of the %AppData% variable when deploying an app in the User context – this makes our Detection Rule quite straight forward too. If the download fails I will set an Exit Code of 1. I will tell the App to “Retry” if it sees an Exit code of 1. Exit code 0 indicates a successful deployment.

Update

Version 1.3 – 11/01/21
-Fixed an issue with the script not downloading content in some scenarios in PoSh 5 by using the “UseBasicParsing” option for invoke-webrequest and changing how the Full URL is created. Thanks/Credit to @DirkHaex
-Changed URI formatting

Source: https://github.com/byteben/MSTeams/blob/b8db126f4dd6af91f14dd6b1a2fa2b0447e67b9b/Custom_Teams_Background.ps1

Putting it all together

Create the .Intunewin File

1 . Download the Win32 Content Prep Tool Zip file in order to create the .intunewin file for deployment https://github.com/microsoft/Microsoft-Win32-Content-Prep-Tool/archive/master.zip

2 . Extract the tool to a local folder, e.g. C:\Microsoft-Win32-Content-Prep-Tool-master

You should see the following files

3 . Make sure you “Unblock” IntuneWinAppUtil.exe

4 . Download the PowerShell Script and save it into the same directory. Do not rename it. Script here :- Custom_Teams_Background.ps1

Your directory should now look like this

5 . Double click IntuneWinAppUtil.exe

Specify the following Values:-

Source Folder: C:\Microsoft-Win32-Content-Prep-Tool-master
Setup File: Custom_Teams_Background.ps1
Output Folder: .\
Specify Catalog Folder?: N

Your directory should now look like this

Create the Win32 App in Intune

1 . Navigate to the Microsoft Endpoint Manager admin Centre https://devicemanagement.microsoft.com and Select Apps > All apps > + Add

2 . Choose Other > Windows app (Win32)

3 . Click Select

4 . Choose Select app package file

5 . Browse to the Custom_Teams_Background.intunewin file we created previously and Select OK

6 . Fill in the application information, the items highlighted in the orange boxes are required – other boxes are optional.

7 . Click Next

8. Enter the following information

Install Command:
Powershell.exe -windowstyle hidden -file “Custom_Teams_Background.ps1” -Install -BackgroundName “Teams_Back_1.jpg” -BackgroundUrl “https://byteben.com/bb/Downloads/Teams_Backgrounds/”
Uninstall Command:
Powershell.exe -windowstyle hidden -file “Custom_Teams_Background.ps1” -Uninstall -BackgroundName “Teams_Back_1.jpg”
Install behaviour: User
Device restart behaviour: No specific action
Return code: 1, Code type: Retry

9 . Click Next

10 . Fill in the app requirements. The settings highlighted require you to enter a value that is suitable for your environment.

11 . Click Next

12 . Under Detection rules, Select Manaully configure detection riles from the Rules format drop down box

13 . Click +Add

14 . Enter the following settings:-

Rule Type: File
Path: %AppData%\Microsoft\Teams\Backgrounds\Uploads
File or Folder: Teams_Back_1.jpg (or the name of your image file)
Detection Method: File or folder exists

15 . Click OK

16 . Click Next

17 . Review Dependencies and Click Next (we don’t have any specific dependencies for this app)

18 . Assign the App to you Users / User Group *

19 . Click Next

20 . Review your Settings and Click Create

* Don’t forget to make this deployment “Available” for enrolled devices to ensure it gets installed in the user context. If you deploy it as “Required” the app will attempt to install in the SYSTEM context and follow the ENV:Appdata variable for the SYSTEM profile.

Testing it Out

Log on to a Windows device with an account that you deployed the application to and open the Company Portal to view your recently created app. At the same time, open file explorer to %AppData%\Microsoft\Teams\Backgrounds\Uploads so you can see the magic happen.

Click Install

The PowerShell window will flash and disappear (we specified the -windowstyle hidden parameter earlier). Check file explorer to view the downloaded custom background – exciting!

Verify you can use the downloaded file as a custom background in Microsoft Teams

Review the Intune Management Extension Logs at C:\ProgramData\Microsoft\IntuneManagementExtension

Summary

In this post, we deployed a PowerShell script as a Win32 app to get a background image from a URL and set it as an available background to use in a Microsoft Teams meeting.

To me this seemed a simple way to create apps in Intune to perform different tasks by simply altering some installation parameters and detection logic without having to edit scripts and repackage them with the Win32 Content Prep tool

Thanks for reading. Ben

5/5 - (1 vote)

11 thoughts on “Deploy custom Microsoft Teams backgrounds, easily, with PowerShell and Intune”

  1. Excellent post Ben, weirdly, I got asked this question today at work.
    I am subscribed to Adam and Steve’s InTune training series, watched the latest video, with yourself on it, viewed your blog , low and behold you saved me a job 😀

    1. Hey Wesley, thanks for the feedback! I’m interested in your Intune Management extension log…I’ve seen a couple
      Of reports where the app detection occurs in the SYSTEM context. Setting the deployment to required rather than available seems to be the reason but I’d love to see others experience on this. Thanks!

  2. Hey Ben,

    Have you run into the issue with the “Access is denied. (0x80070005)” when attempting to deploy it to users without admin rights to their machines? I’m assuming it’s having trouble fetching the elevated token for the current user. We use a privilege mgmt solution on our endpoints so I’m thinking this is blocking the ability to fetch that token. In that case, do you know what directory/process that would need to be whitelisted to allow this?

    1. Hi Steve,

      Not come across that particular scenario. This script runs in the user context so the token is obtained for personation – elevation is not required. What scenario are you using where the standard user requires elevation?

      1. Hi Ben and Steve,

        It seems to me that a regular user doens’t have the authority to use “-ExecutionPolicy bypass” method. And as this app is executed in user context, the user would need to have admin rights I guess ?

        1. Hey, the user would not require admin access to run the win32app in the user context.
          But yes, I missed the “-Scope CurrentUser” off by accident – good spot!

  3. Hi Ben,

    I’ve been doing something similar to this however having to package the images with the script as there are multiple of them.

    Would you be able to suggest any better way of using this script with about 20 or so web locations for the images?

    Cheers

    1. you could just use a foreach *.jpg in the source directory to copy them to %appdata% – But you wouldn’t be able to use a single image as the detection method.

      $ScriptPath = $MyInvocation.MyCommand.Path
      $CurrentDir = Split-Path $ScriptPath
      $TeamsDir = Join-Path $ENV:Appdata “Microsoft\Teams\Backgrounds\Uploads”
      foreach ($Image in $(Get-ChildItem -Path $CurrentDir -Include *.jpg -Recurse)) {
      Copy-Item $Image $TeamsDir -Force
      }

Leave a Reply to Wesley Cancel Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.

 

This site uses Akismet to reduce spam. Learn how your comment data is processed.