Changing your Windows Terminal background image

I use Windows Terminal to run scripts, connect to SSH hosts, or start a WSL Ubuntu session. You can customize Windows Terminal in many ways, and in this blog post, I will show you how to change the background in your Profiles to a fixed or randomly selected one.

What is Windows Terminal?

“The Windows Terminal is a modern, fast, efficient, powerful, and productive terminal application for users of command-line tools and shells like Command Prompt, PowerShell, and WSL. Its main features include multiple tabs, panes, Unicode and UTF-8 character support, a GPU accelerated text rendering engine, and custom themes, styles, and configurations.”

Source: https://apps.microsoft.com/store/detail/windows-terminal/9N0DX20HK701

What does the Set-WindowsTerminalBackGroundImage.ps1 script do?

The script changes the background image of your Windows Terminal Profile(s). You can specify parameters to finetune the background image changes in the Profile(s). The parameters are:

  • The -All parameter will change all the configured Profiles.
  • The -DefaultProfile parameter will only change the Default Profile. Every new Profile being added will inherit the background image setting from it.
  • The -Profiles parameter allows you to specify one or more specific Profiles of which the background image will be changed. (These must be separated by a comma and enclosed by the ‘-sign).
  • The -RandomBackgroundFolder parameter allows you to specify a folder path in which you have one or more background pictures (*.jpg, *.jpeg, *.png, *.bmp, *.gif, *.tiff, *.ico) stored.
  • The -BackgroundPath parameter allows you to specify a specific image for the background image.

The script imports the Settings.json file from Windows Terminal and adds or changes the background setting.

Note: You can’t use both -RandomBackgroundFolder and -BackgroundPath parameters together. The script will exit if that’s the case.

How to use the script

Changing all Profiles to a random background image

In the example below, I changed the background image for all Profiles to a random one from the C:\Temp\Wallpaper folder.

PS D:\Data\GitHub\PowerShell\PowerShellisfun scripts> .\Set-WindowsTerminalBackgroundImage.ps1 -RandomBackgroundFolder C:\Temp\Wallpaper -All
7 Wallpapers were found in C:\Temp\Wallpaper, continuing... 
Changing Wallpaper for Profile PowerShell v5 to C:\Temp\Wallpaper\desktop-wallpaper-powershell-thumbnail.jpg
Changing Wallpaper for Profile PowerShell v5 NoProfile to C:\Temp\Wallpaper\powershell1.jpg
Changing Wallpaper for Profile Command Prompt to C:\Temp\Wallpaper\featured_image_powershell.png
Changing Wallpaper for Profile PowerShell v7 NoProfile to C:\Temp\Wallpaper\DevOps-practices-for-PowerShell-programming.jpg
Changing Wallpaper for Profile Azure Cloud Shell to C:\Temp\Wallpaper\download.jpg
Changing Wallpaper for Profile SSH UNMS to C:\Temp\Wallpaper\featured_image_powershell.png
Changing Wallpaper for Profile SSH PiHole to C:\Temp\Wallpaper\superman_wallpaper_small.png
Changing Wallpaper for Profile SSH EdgeRouter to C:\Temp\Wallpaper\download.jpg
Changing Wallpaper for Profile SSH EdgeSwitch to C:\Temp\Wallpaper\superman_wallpaper_small.png
Changing Wallpaper for Profile PowerShell7 to C:\Temp\Wallpaper\download.jpg
Changing Wallpaper for Profile Ubuntu-20.04 to C:\Temp\Wallpaper\DevOps-practices-for-PowerShell-programming.jpg

For example, when opening the Command Prompt profile, the background image changed to c:\temp\featured_image_powershell.png:

Changing two specific Profiles to a specific background image

In the example below, I changed the background image for two specific Profiles to C:\Temp\Wallpaper\DevOps-practices-for-PowerShell-programming.jpg:

PS D:\Data\GitHub\PowerShell\PowerShellisfun scripts> .\Set-WindowsTerminalBackgroundImage.ps1 -Profiles 'PowerShell v5', 'Ubuntu-20.04' -BackgroundPath C:\temp\Wallpaper\DevOps-practices-for-PowerShell-programming.jpg
Changing Wallpaper for Profile PowerShell v5 to C:\temp\Wallpaper\DevOps-practices-for-PowerShell-programming.jpg
Changing Wallpaper for Profile Ubuntu-20.04 to C:\temp\Wallpaper\DevOps-practices-for-PowerShell-programming.jpg

For example, when opening the Ubuntu 20.04 profile, the background image changed to the one specified in the -BackgroundPath parameter:

Adding it to your PowerShell profile

You can also add the Set-WindowsTerminalBackGroundImage.ps1 script to your PowerShell Profile. (Edit it by running notepad $profile in a PowerShell prompt) Adding this line below will give you a random background for all profiles when starting PowerShell in Windows Terminal:

C:\Scripts\Set-WindowsTerminalBackgroundImage.ps1 -RandomBackgroundFolder C:\Temp\Wallpaper -All

After running it, the script will update the background images in your Profiles even when they are already open in Windows Terminal.

Resetting all Profiles to an empty background image

If you want to reset the background image to an empty one for all your profiles, you can run the two commands below to reset all Profiles and the Default Profile:

PS D:\Data\GitHub\PowerShell\PowerShellisfun scripts> .\Set-WindowsTerminalBackgroundImage.ps1 -All -BackgroundPath $null
Changing Wallpaper for Profile PowerShell v5 to 
Changing Wallpaper for Profile PowerShell v5 NoProfile to 
Changing Wallpaper for Profile Command Prompt to 
Changing Wallpaper for Profile PowerShell v7 NoProfile to 
Changing Wallpaper for Profile Azure Cloud Shell to 
Changing Wallpaper for Profile SSH UNMS to 
Changing Wallpaper for Profile SSH PiHole to 
Changing Wallpaper for Profile SSH EdgeRouter to 
Changing Wallpaper for Profile SSH EdgeSwitch to 
Changing Wallpaper for Profile PowerShell7 to 
Changing Wallpaper for Profile Ubuntu-20.04 to 
PS D:\Data\GitHub\PowerShell\PowerShellisfun scripts> .\Set-WindowsTerminalBackgroundImage.ps1 -DefaultProfile -BackgroundPath $null
Changing Wallpaper for Default Profile to 

This will result in a plain/dull black background for all of your Windows Terminal Profiles πŸ™‚

The script

Below are the contents of the Set-WindowsTerminalBackgroundImage.ps1 script. Copy/paste it and save it somewhere on your system and change your background image πŸ™‚

#Parameter usage:
# -All changes all configured profiles except the Default Profile
# -DefaultProfile changes the Default Profile settings. Every new profile will inherit the wallpaper setting from it
# -Profiles can be used for specifying one or multiple profiles separated by ','. Example Set-WindowsTerminalBackgroundImage "PowerShell 5" or Set-WindowsTerminalBackgroundImage "PowerShell 5", "Azure Cloud Shell"

[CmdletBinding(DefaultParameterSetName = 'None')]
param(
    [Parameter(Mandatory = $true, ParameterSetName = 'All')]
    [Switch]$All,
    
    [Parameter(Mandatory = $true, ParameterSetName = 'DefaultProfile')]
    [Switch]$DefaultProfile,
    
    [Parameter(Mandatory = $true, ParameterSetName = 'Profiles')]
    [String[]]$Profiles,
       
    [Parameter(Mandatory = $false, ParameterSetName = 'All')]
    [Parameter(Mandatory = $false, ParameterSetName = 'DefaultProfile')]
    [Parameter(Mandatory = $false, ParameterSetName = 'Profiles')]
    [String]$RandomBackgroundFolder,
    
    [Parameter(Mandatory = $false, ParameterSetName = 'All')]
    [Parameter(Mandatory = $false, ParameterSetName = 'DefaultProfile')]
    [Parameter(Mandatory = $false, ParameterSetName = 'Profiles')]
    [String]$BackgroundPath
)

#Check if RandomWallpaperFolder and WallpaperPath were used at the same time. Exit if they were
if ($RandomBackgroundFolder -and $BackgroundPath) {
    Write-Warning ("RandomBackgroundFolder and BackgroundPath parameters can't be used both, Set-WindowsTerminalBackgroundImage is exiting")
    break
}

#Check $BackgroundPath location
if ($BackgroundPath) {
    if (-not (Get-ChildItem -Path $BackgroundPath -ErrorAction SilentlyContinue | where-object Extension -In '.jpg', '.jpeg', '.png', '.bmp', '.gif', '.tiff', '.ico')) {
        Write-Warning ("Specified Wallpaper {0} has no .jpg, .jpeg, .png, .bmp, .gif, .tiff, .ico extension, check spelling or permissions. Set-WindowsTerminalBackgroundImage is exiting..." -f $BackgroundPath)
        break
    }
}

#Check $RandomBackgroundFolder for files (β‰₯ 1) and set $BackgroundPath to random wallpaper
if ($RandomBackgroundFolder) {
    if (-not ((Get-ChildItem -Path $RandomBackgroundFolder -Include *.jpg, *.jpeg, *.png, *.bmp, *.gif, *.tiff, *.ico -Recurse -ErrorAction SilentlyContinue).count -ge 1 )) {
        Write-Warning ("No Wallpapers found in {0}. (Searched for *.jpg, *.jpeg, *.png, *.bmp, *.gif, *.tiff, *.ico files). Set-WindowsTerminalBackgroundImage is exiting..." -f $RandomBackgroundFolder)
        break
    }
    else {
        Write-Host ("{0} Wallpapers were found in {1}, continuing... " -f (Get-ChildItem -Path $RandomBackgroundFolder -Include *.jpg, *.jpeg, *.png, *.bmp, *.gif, *.tiff, *.ico -Recurse).count, $RandomBackgroundFolder) -ForegroundColor Green
    }
}
    
#Retrieve Settings.json location
try {
    $json = Get-Content $env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\Settings.json -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop
}
catch {
    Write-Warning ("Windows Terminal Settings.json was not found. Is Windows Terminal installed? Check permissions if it is, Set-WindowsTerminalBackgroundImage is exiting...")
    break
}

#Loop through all specified Profiles in $profiles and change the wallpaper to the one specified in $BackgroundPath or random one from $RandomBackgroundFolder
#Check if the profile exists and skip if not found
if ($Profiles) {
    foreach ($Profile in $Profiles) {
        if ($profilesettings = $json.profiles.list | Where-Object name -eq $profile -ErrorAction Stop) {
            if ($RandomBackgroundFolder) {
                $BackgroundPath = (Get-ChildItem -Path $RandomBackgroundFolder -Include *.jpg, *.jpeg, *.png, *.bmp, *.gif, *.tiff, *.ico -Recurse | Get-Random).Fullname
            }
            $profilesettings | Add-Member -NotePropertyName 'backgroundImage' -NotePropertyValue $BackgroundPath -Force:$true
            Write-Host ("Changing Wallpaper for Profile {0} to {1}" -f $Profile, $BackgroundPath) -ForegroundColor Green
        }
        else {
            Write-Warning ("Specified Profile {0} was not found, Set-WindowsTerminalBackgroundImage is skipping profile..." -f $Profile)
        }
    }
}

#Loop through all Profiles in and change the wallpaper to the one specified in $BackgroundPath or the random one from $RandomBackgroundFolder
if ($All) {
    foreach ($Profile in $json.profiles.list) {
        $profilesettings = $json.profiles.list | Where-Object name -eq $profile.name -ErrorAction Stop
        if ($RandomBackgroundFolder) {
            $BackgroundPath = (Get-ChildItem -Path $RandomBackgroundFolder -Include *.jpg, *.jpeg, *.png, *.bmp, *.gif, *.tiff, *.ico -Recurse | Get-Random).Fullname
        }
        $profilesettings | Add-Member -NotePropertyName 'backgroundImage' -NotePropertyValue $BackgroundPath -Force:$true
        Write-Host ("Changing Wallpaper for Profile {0} to {1}" -f $Profile.name, $BackgroundPath) -ForegroundColor Green
    }
}

#Change the wallpaper for the Default Profile to the one specified in $BackgroundPath or the random one from $RandomBackgroundFolder
if ($DefaultProfile) {
    if ($RandomBackgroundFolder) {
        $BackgroundPath = (Get-ChildItem -Path $RandomBackgroundFolder -Include *.jpg, *.jpeg, *.png, *.bmp, *.gif, *.tiff, *.ico -Recurse | Get-Random).Fullname
    }
    $json.profiles.defaults | Add-Member -NotePropertyName 'backgroundImage' -NotePropertyValue $BackgroundPath -Force:$true
    Write-Host ("Changing Wallpaper for Default Profile to {0}" -f $BackgroundPath) -ForegroundColor Green
}

#Save modified Settings.json, overwriting the existing one
try {
    $json | ConvertTo-Json -Depth 10 | Out-File $env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\Settings.json -Force -Encoding utf8
}
catch {
    Write-Warning ("Error saving {0}, check permissions..." -f "$($env:LOCALAPPDATA)\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\Settings.json")
}

Download the script(s) from GitHub here

Leave a Reply

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