Intro
This post was inspired by a question posted to the Modern Endpoint Management LinkedIn group about syncing/backing up users’ teams backgrounds to OneDrive. I work with Teams a lot, so this was something I was interested in solving. Teams backgrounds are stored in the user’s %appdata% folder. So, the challenge was to sync the user’s %appdata%\Microsoft\Teams\Backgrounds\Uploads folder to OneDrive somewhere. Step 2 for was to get this synced downstream on any other PC the users log into (so their backgrounds travel with them). Originally, I using Microsoft’s instructions here to make a symbolic link – Can’t synchronize OneDrive files and folders from a local file location other than the default OneDrive path (microsoft.com). I thought I had this working until it failed on the second PC I logged into. The reason – you can’t set up a junction link if a directory already exists. The first time this deployed, it worked properly on PC1 and created a directory junction from the %appdata%\Microsoft\Teams\Backgrounds\Uploads folder to a directory I created named Teamsbackgrounds in OneDrive. Everything worked as expected and the backgrounds synced to OneDrive. However, I couldn’t get OneDrive to sync the files downstream to the %appdata%\Microsoft\Teams\Backgrounds\Uploads folder on PC2 since the directory already existed in OneDrive. After messing with this for a couple hours, I had no choice but to go back to the drawing board.
I ended up having to get creative with a solution. I also work with many clients using Windows 10 Pro, so I wanted to stay clear of proactive remediations for those without the required licenses. After a bunch of testing, I found a solution that accomplishes my original goal, but does so in an old school way. However, I learned some tricks about deploying scheduled tasks with Intune. A separate blog post was spawned with more details on how to deploy scheduled tasks with intune here. At a high level, we will deploy two Win32 apps targeted at a user group. The first app creates the %appdata%\Microsoft\Teams\Backgrounds\Uploads and %userprofile%\OneDrive – orgname\TeamsBackgrounds directories for the user if they don’t exist. This is important because by default, the uploads directory does not exist until a user saves a custom background. If they’re signing into a PC for the first time, it won’t be there, so we need the app to create it. The next Win32 app is dependent on the first, and does two things – It copies a robocopy script and VB script to the c:\temp directory, and also creates a scheduled task to perform regular two-way file copies between the two folders created by app 1. Technically, one drive isn’t “natively” syncing the directories, but this still accomplishes the goal, and I couldn’t find a better way to do this. Also, this post assumes you have a configuration profile applied to automatically set up OneDrive sync for your users.
Win32 App #1
Step one is to create the necessary directories if they don’t exist. Make sure you edit the path to your organization’s one drive in the script. If you don’t know what that is, the easiest way to locate is to use a machine where OneDrive sync is already set up. Open Windows Explorer, and look at your OneDrive sync locations in the left pane. The default path should be c:\users\username\OneDrive – org\. Like shown in the screenshot below.
$uploads = "c:\users\$env:UserName\appdata\roaming\Microsoft\Teams\Backgrounds\Uploads"
$teamsbackgrounds = "c:\users\$env:UserName\OneDrive - changeme\Teamsbackgrounds"
New-Item $uploads -ItemType Directory -Force
New-Item $teamsbackgrounds -ItemType Directory -Force
Wrap the script as a Win32 app and configure it in Intune. You can download the IntuneWinAppUtil here.
Create a new Win32 app in your tenant and import the intunewin file. Name the app whatever you’d like:
I use the same install command for the uninstall command since these directories are harmless to keep around. Make sure we select to install for USER.
Set a requirement rule, and create two detection rules to look for the two directories we are creating – %appdata%\Microsoft\Teams\Backgrounds\Uploads and c:\users\%username%\onedrive – orgname\Teamsbackgrounds
Optionally, you can create a dependency on your Teams installation if you’re deploying it as an Intune app. Complete the rest of the steps and assign to a user group. The app should begin deploying after the next check-in. Here is my test user I signed into three devices with:
Win32 App #2
This app creates c:\temp if it doesn’t exist, copies a robocopy & VB script to that directory, and imports a scheduled task that has two triggers with the same action of running the two-way robocopy script:
Trigger 1. 10 minutes after the task is created. This allows some time for the one drive sync settings to take effect.
Trigger 2. 10 minutes after user logon, and again every hour (it runs as the logged-on user). This allows the one drive sync settings to go into effect if a user is signing into a machine for the first time, but already has the task created.
All the scripts are shown below and are available on Github here. We also have an uninstall script to remove the scheduled task if needed. For the scheduled task, you can use my XML file, or create your own scheduled task with your own parameters (details on that here). Remember to change the robocopy script to use your OneDrive organization name path. There’s also a VBS file. Once I finally got everything working properly, I had the issue of the command window displaying on the user screen for the 1-2 seconds it took to execute the task and run the robocopy script. I tried a few things to get the window suppressed before finding this vbs script online. It calls the cmd file, but executes it silently with no window or user interaction.
VBS Script:
Set WshShell = CreateObject("Wscript.Shell")
WshShell.Run chr(34) & "C:\Temp\TeamsBackgroundSync.cmd" & Chr(34), 0, True
Set WshShell = Nothing
Robocopy script:
robocopy %appdata%\Microsoft\Teams\Backgrounds\Uploads\ "%userprofile%\OneDrive - orgname\TeamsBackgrounds\ " /XO
robocopy "%userprofile%\OneDrive - orgname\TeamsBackgrounds\ " %appdata%\Microsoft\Teams\Backgrounds\Uploads\ /XO
Script to create directory, copy file, and create scheduled task:
$tempdir = "c:\temp"
New-Item $tempdir -ItemType Directory -Force
Copy-Item ".\SilentCMD.vbs" -Destination $tempdir -Force
Copy-Item ".\TeamsBackgroundSync.cmd" -Destination $tempdir -Force
Register-ScheduledTask -xml (Get-Content '.\TeamsBackgroundSync.xml' | Out-String) -TaskName "TeamsBackgroundSync" -Force
Removal Script:
Unregister-ScheduledTask -TaskName TeamsBackgroundSync -Confirm:$false
Remove-Item -Path C:\temp\SilentCMD.vbs -Force
Remove-Item -Path C:\temp\TeamsBackgroundSync.cmd -Force
Here are details on the scheduled task. This can be adjusted however you want. Export it as an XML after you have it set up how you want. Additional details on deploying scheduled tasks with Intune can be found in my previous post linked above.
The triggers to run the script 10 minutes after user logon, and then repeat every hour for the rest of the day.
The other trigger to run the task 10 minutes after its created/modified:
And the action to run our VBS file, which silently executes the robocopy script:
Put all four scripts and the XML in the same directory and wrap as an intunewin package with ImportTask.ps1 as the setup file:
Create another Win32 app and configure like below, or change what you’d like to:
The install and uninstall commands reference are two PowerShell scripts. We want to install this app as system:
We will add three detection rules. One will make sure the scheduled task exists, the other two make sure the robocopy script and VBS script exist. All scheduled tasks are located as XML files (but without the file extension) in c:\windows\system32\tasks\
Make this app dependent on the previous app so we know our necessary directories exist:
Complete the rest of the app creation and assign to your user group. Wait for your apps to deploy and start syncing user backgrounds 😊. Here’s a bunch of additional screenshots post deployment, and after the task runs.
Post deployment
Our Win32 Sync App completing successfully:
The scheduled task that gets created:
Task Triggers how we had them setup previously:
With the action to run our robocopy script silently, called by the VBS script:
Task being registered at 6:12 AM, and then kicking off 10 minutes after at 6:22 AM:
Here are two machines demonstrating how this works with the same user signed into two separate machines. Machine A on the left logged in several seconds seconds before machine B on the right, so the tasks are separated by roughly 5-10 seconds. User originally had two backgrounds synced to OneDrive (Metallica and Motorhead), but added two more backgrounds on machine A, as shown in the bottom left (Ozzy and pinkfloyd). When the task runs, you can see the sync happening clockwise from bottom left and ending at bottom right. The Teams “uploads” folder containing the backgrounds from machine A syncs to OneDrive. OneDrive sync on Machine B sees the newly synced images. When the task runs on Machine B, it pulls all images from OneDrive into the Teams backgrounds uploads folder on machine B (on bottom right).