Automatically backing up user profile data with Intune

Whilst Enterprise state roaming is an excellent addition to Azure/Inune, I’ve found it doesn’t capture everything in a user profile and can lead to complaints about lost data in the event of a PC failure. Whilst we all backup when rebuilding a machine, how many people do regular backups of anything other than documents?

For this backup script, we are going to be using a mixture of Powershell and batch scripts. Whilst Powershell could do the file copying as well, I’ve found it doesn’t play as nicely with Onedrive when using Files on Demand.

As usual, all content on Github:
Powershell script: Here
Batch scripts: Here

Starting with the powershell script. This we will deploy with Intune as a standard Device Script, run in the Device context:

The script itself is fairly straight forward:

Create a folder for the files (if you change the path here, make sure you do in the task as well)

#Create path for files
$DirectoryToCreate = "c:\backup-restore"
if (-not (Test-Path -LiteralPath $DirectoryToCreate)) {
    
    try {
        New-Item -Path $DirectoryToCreate -ItemType Directory -ErrorAction Stop | Out-Null #-Force
    }
    catch {
        Write-Error -Message "Unable to create directory '$DirectoryToCreate'. Error was: $_" -ErrorAction Stop
    }
    "Successfully created directory '$DirectoryToCreate'."

}
else {
    "Directory already existed"
}

Now we download the scripts (I’ll cover those shortly)

##Download Backup Script
$backupurl="https://raw.githubusercontent.com/andrew-s-taylor/public/main/Batch%20Scripts/backup.bat"
$backupscript = "c:\backup-restore\backup.bat"
Invoke-WebRequest -Uri $backupurl -OutFile $backupscript -UseBasicParsing

##Download Restore Script
$restoreurl="https://raw.githubusercontent.com/andrew-s-taylor/public/main/Batch%20Scripts/NEWrestore.bat"
$restorescript = "c:\backup-restore\restore.bat"
Invoke-WebRequest -Uri $restoreurl -OutFile $restorescript -UseBasicParsing

##Download Silent Launch Script
$launchurl="https://raw.githubusercontent.com/andrew-s-taylor/public/main/Batch%20Scripts/run-invisible.vbs"
$launchscript = "c:\backup-restore\run-invisible.vbs"
Invoke-WebRequest -Uri $launchurl -OutFile $launchscript -UseBasicParsing

We have a backup script which does the hard work, a restore script and a small vbs file which runs the backup in a hidden window

Then finally, create the scheduled task

##Create scheduled task
# Create a new task action
$taskAction = New-ScheduledTaskAction -Execute 'c:\backup-restore\run-invisible.vbs' 

##Create Trigger (login)
$taskTrigger = New-ScheduledTaskTrigger -AtLogOn

# Register the new PowerShell scheduled task

#Name it
$taskName = "UserBackup"

#Describe it
$description = "Backs up User profile to OneDrive"

# Register it
Register-ScheduledTask `
    -TaskName $taskName `
    -Action $taskAction `
    -Trigger $taskTrigger `
    -Description $description

As for the backup script, this will back up (to a folder called Backup in users Onedrive):

  • Desktop (unless already in Onedrive)
  • Music
  • Documents
  • Outlook signature
  • Outlook roaming data (email drop-downs)
  • IE Favourites
  • Links (does anyone use these??)
  • Excel Startup items
  • Word startup items
  • PST files
  • Word Normal.dot
  • Office UI (any buttons on the ribbon etc.)
  • Sticky notes
  • Chrome bookmarks
  • Mapped drives (to a text file for review)

I’m not going to post the whole thing, but here is a sample

::GET SIGNATURES
echo CopyingSignatures >> "%Onedrive%\backup\log.txt"
echo CopyingSignatures >> "%OneDriveCommercial%\backup\log.txt"
SET BSig=%APPDATA%\Microsoft\Signatures
SET RSig="%Onedrive%\Backup\Signature"
if not exist "%Onedrive%\Backup\Signatures" mkdir "%Onedrive%\Backup\Signature"
XCopy "%BSig%\*" "%Onedrive%\Backup\Signature" /E /Y /C /Z /D >> "%Onedrive%\backup\log.txt"
if not exist "%OneDriveCommercial%\Backup\Signatures" mkdir "%OneDriveCommercial%\Backup\Signature"
XCopy "%BSig%\*" "%OneDriveCommercial%\Backup\Signature" /E /Y /C /Z /D >> "%OneDriveCommercial%\backup\log.txt"

I’ve seen issues on some older machines with Onedrive running in either the %Onedrive% or the %OneDriveCommercial% variables so I copy to both just in case. Log file is useful if you want to pipe it into an email, azure blob etc.

The vbs file simply launches the batch script

Set WshShell = CreateObject("WScript.Shell")
WshShell.RUN "cmd /c c:\backup-restore\backup.bat", 0

Finally, the restore does the backup, but the other way around. The only difference is StickyNotes is more tricky:

::GET SICKYNOTES
echo CopyingStickyNotes >> "%OneDriveCommercial%\backup\restorelog.txt"
SET BSticky=%LOCALAPPDATA%\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState\legacy
SET RSticky=%OneDriveCommercial%\Backup\Sticky
if not exist "%LOCALAPPDATA%\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState\legacy" mkdir "%LOCALAPPDATA%\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState\legacy"
XCopy /s "%RSticky%" "%BSticky%" /E /Y /C /Z /D >> "%OneDriveCommercial%\backup\restorelog.txt" 2>> %error% 
copy "%BSticky%\StickyNotes.snt" "%BSticky%\ThresholdNotes.snt"

That’s it, every login the script will run quietly in the background ready to restore when needed

Leave a Comment