The following Powershell function will change the current user’s desktop wallpaper automatically using the SystemParametersInfo function that can be located in the User32.dll.
Function Set-WallPaper($Image) {
<#
.SYNOPSIS
Applies a specified wallpaper to the current user's desktop
.PARAMETER Image
Provide the exact path to the image
.EXAMPLE
Set-WallPaper -Image "C:\Wallpaper\Default.jpg"
#>
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class Params
{
[DllImport("User32.dll",CharSet=CharSet.Unicode)]
public static extern int SystemParametersInfo (Int32 uAction,
Int32 uParam,
String lpvParam,
Int32 fuWinIni);
}
"@
$SPI_SETDESKWALLPAPER = 0x0014
$UpdateIniFile = 0x01
$SendChangeEvent = 0x02
$fWinIni = $UpdateIniFile -bor $SendChangeEvent
$ret = [Params]::SystemParametersInfo($SPI_SETDESKWALLPAPER, 0, $Image, $fWinIni)
}
Example:
Set-WallPaper -Image “C:\Wallpaper\Default.jpg”
For more information about the SystemParametersInfo function, please see this link to MSDN.
Update 08/10/2020:
Per request, I have included a new parameter for the Set-Wallpaper function to configure wallpaper styles. See the updated function below:
Function Set-WallPaper {
<#
.SYNOPSIS
Applies a specified wallpaper to the current user's desktop
.PARAMETER Image
Provide the exact path to the image
.PARAMETER Style
Provide wallpaper style (Example: Fill, Fit, Stretch, Tile, Center, or Span)
.EXAMPLE
Set-WallPaper -Image "C:\Wallpaper\Default.jpg"
Set-WallPaper -Image "C:\Wallpaper\Background.jpg" -Style Fit
#>
param (
[parameter(Mandatory=$True)]
# Provide path to image
[string]$Image,
# Provide wallpaper style that you would like applied
[parameter(Mandatory=$False)]
[ValidateSet('Fill', 'Fit', 'Stretch', 'Tile', 'Center', 'Span')]
[string]$Style
)
$WallpaperStyle = Switch ($Style) {
"Fill" {"10"}
"Fit" {"6"}
"Stretch" {"2"}
"Tile" {"0"}
"Center" {"0"}
"Span" {"22"}
}
If($Style -eq "Tile") {
New-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name WallpaperStyle -PropertyType String -Value $WallpaperStyle -Force
New-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name TileWallpaper -PropertyType String -Value 1 -Force
}
Else {
New-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name WallpaperStyle -PropertyType String -Value $WallpaperStyle -Force
New-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name TileWallpaper -PropertyType String -Value 0 -Force
}
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class Params
{
[DllImport("User32.dll",CharSet=CharSet.Unicode)]
public static extern int SystemParametersInfo (Int32 uAction,
Int32 uParam,
String lpvParam,
Int32 fuWinIni);
}
"@
$SPI_SETDESKWALLPAPER = 0x0014
$UpdateIniFile = 0x01
$SendChangeEvent = 0x02
$fWinIni = $UpdateIniFile -bor $SendChangeEvent
$ret = [Params]::SystemParametersInfo($SPI_SETDESKWALLPAPER, 0, $Image, $fWinIni)
}
Set-WallPaper -Image "C:\Wallpaper\Background.jpg" -Style Fit
Martin
hello to start with i say i don’t know english i write google translate
I need help in the script is about enabling streaming in windows 10
Jose Espitia
Hi Martin, what do you mean by enabling streaming?
ernesto
how to execute the script?
Jose Espitia
Ernesto, just copy the function in ISE and run the function.
Set-WallPaper -Image "C:\Wallpaper\Default.jpg"
ernesto
forget about it
Bill
Perfect !
Finally a script that works reliably on Windows 10 !
Many BIG THANKS !
Jose Espitia
Great to hear that it works Bill 🙂
bostongeorge
nice. What if I want to change a parameter for fitting the image to the screen resolution. Exemple: paramenter “fit screen”?
Jose Espitia
Hi Boston George,
I updated the function for you to include wallpaper styles. So now you can configure the wallpaper to Fill, Fit, Stretch, Tile, Center, or Span with the Style parameter.
Function Set-WallPaper {
<# .SYNOPSIS Applies a specified wallpaper to the current user's desktop .PARAMETER Image Provide the exact path to the image .PARAMETER Style Provide wallpaper style (Example: Fill, Fit, Stretch, Tile, Center, or Span) .EXAMPLE Set-WallPaper -Image "C:\Wallpaper\Default.jpg" Set-WallPaper -Image "C:\Wallpaper\Background.jpg" -Style Fit #>
param (
[parameter(Mandatory=$True)]
# Provide path to image
[string]$Image,
# Provide wallpaper style that you would like applied
[parameter(Mandatory=$False)]
[ValidateSet('Fill', 'Fit', 'Stretch', 'Tile', 'Center', 'Span')]
[string]$Style
)
$WallpaperStyle = Switch ($Style) {
"Fill" {"10"}
"Fit" {"6"}
"Stretch" {"2"}
"Tile" {"0"}
"Center" {"0"}
"Span" {"22"}
}
If($Style -eq "Tile") {
New-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name WallpaperStyle -PropertyType String -Value $WallpaperStyle -Force
New-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name TileWallpaper -PropertyType String -Value 1 -Force
}
Else {
New-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name WallpaperStyle -PropertyType String -Value $WallpaperStyle -Force
New-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name TileWallpaper -PropertyType String -Value 0 -Force
}
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class Params
{
[DllImport("User32.dll",CharSet=CharSet.Unicode)]
public static extern int SystemParametersInfo (Int32 uAction,
Int32 uParam,
String lpvParam,
Int32 fuWinIni);
}
"@
$SPI_SETDESKWALLPAPER = 0x0014
$UpdateIniFile = 0x01
$SendChangeEvent = 0x02
$fWinIni = $UpdateIniFile -bor $SendChangeEvent
$ret = [Params]::SystemParametersInfo($SPI_SETDESKWALLPAPER, 0, $Image, $fWinIni)
}
Set-WallPaper -Image "C:\it\wallpaper\LockScreen.jpg" -Style Fit
Dan
Can this be used to set the wallpaper of a different user than the current-logged-on user? Specifically, we have a script that runs under the built-in administrator account during the unattend step after imaging a machine, which creates a new local admin account and then disables the built-in one. I’d like to also set the wallpaper of that new account at the same time.
Jose Espitia
Unfortunately the script will only work for the current logged on user. In your situation, I would just replace the wallpapers in C:\windows\web\Wallpaper\Windows and C:\windows\web\4k\Wallpaper\Windows with your own custom wallpaper.
Jeff
Just great !
muath
many thanks for your great script , i just need to know if there is any way to do the following :
we have more than 5000 Domain PCs and we need to push a package or script or any way to change the background every 3 hour or specific time silently and remotely and without log off/on, we have SCCM managed all PCs ,
so is there any way to do so ?
Jose Espitia
muath, that should be easy to achieve with a a reoccurring SCCM job or scheduled task. You would configure it to run every 3 hours and then use the function to apply different wallpapers.
muath
many thanks Jose for your comment , could you please help in this way in more details
my email : eng.muath@hotmail.com
many thanks
vmiheer
It would be great if set-wallpaper takes in monitorID as additional parameter, so it only sets wallpaper for particular monitor.
David Ferro
Is there a way to edit this script to allow different wallpapers for multiple monitors? I’m not finding an easy way to do it with just file paths to the images without using the Windows 10 UI.
Jose Espitia
David, that is not something you can do natively within Windows 10 so you would need to find some type of third party software to handle something like this.
Joseph McEvoy
Thanks for the helpful function, Jose.
I used Set-Wallpaper to make a script that gets and saves an image to the Pictures home directory. Hopefully others will find it useful: https://github.com/JosephMcEvoy/PowerShell/blob/master/Misc/randomWallpaper.ps1.
I modified Set-Wallpaper to take pipeline input, and also outputs the filename at the end so that I could make it as simple as:
Get-Wallpaper | Set-Wallpaper | Remove-item.
Jose Espitia
Thank you for linking to my site Joseph. Great work on updating the function too!
Frank Ward
FYI – If I run from the command line it works fine, but as a task using Windows 10, either manual or triggered, it will not change the wallpaper. I’ve tried numerous settings for the task (user, security, arguments, etc.) to no avail. Any idea what’s happening?
Jose Espitia
Hi Frank, You must run this function as the current logged on user that you are changing the wallpaper for.
Peter Busch
I get a error because of a missing “}”.
Can you help?
Jose Espitia
Did you copy everything exactly? As you can tell from the comments, the function does work.
It would helpful if you can share the exact error too.
Paul
I have seen the same error. It occurred for me when pasting the Code into Visual Studio Code embedded in another Script that performs logging and some other funktions. What happens is, the code gets indented. Apparently thsi does not get along with the “@ that ends the type definition. That has to be always at the very start of the line. As soon as I removed the indent that was fixed.
Robin Herbert
Small point, but in the updated script if you don’t use the ‘style’ parameter, then the image is always Centered. $Wallpaper = 0 by default, and $style is not equal to Tile…
So surround those lines with an “if ($style -ne “”) {etc…}” and the style should be left as is.
Interesting that a unused parameter is not equal to $null but just “”.
But neat work otherwise, thanks!
JR
I’m wondering if this can be modified to change the folder of a slideshow instead of a specific image?
Jose Espitia
I’m sure you could use a ForEach loop to go through and loop through the images from the folder.
Rohan
I’m wondering if we can run this with a storage account link, where it grabs the image and creates the wallpaper just like this.
A. Angelo
Perfect! I Update your script with an Help parameter that show the informations and how use the script! Well done!
vinay
Hi Jose,
Thanks for the informaiton. Do you have any option to change the wallpaper for every user.
I referred the link:
https://appuals.com/set-a-default-background-wallpaper-for-all-users-in-windows-10/
But myself couldn’t able to do programmatically. Can you please assist me how can we change the local computer policy ?
Jose Espitia
Vinay, you could use Group Policy’s Logon Scripts to change the wallpaper for everyone in your organization.
Rafael
Hey there!
I’m trying this but the background is getting solid color, insted to change. So al goes black… What should be done?
And… is there any script to replace for all users? Ho can I insert the default replacement on this script?
C:\windows\web\Wallpaper\Windows and C:\windows\web\4k\Wallpaper\Windows with your own custom
Sourov
I’m having the same problem. It was working perfectly. Now it is broken.
Owen Reynolds
Jose, my man! Thanks so much
Just added your function to my post-OSBuild script, I wanted a tetris wallpaper while the build was running, your function worked great!
https://github.com/getvpro/Standard-WinBuilds/blob/master/Offline_Builds/Start-PostOSInstall.ps1
Thanks again!
Owen
Jose Espitia
I’m glad I could help 🙂
Venturic
Hello,
vscode grunts a bit on this line (Variable not used):
$RET = [Params]::SystemParametersInfo($SPI_SETDESKWALLPAPER, 0, $Image, $fWinIni)
So I changed it to this, and it works:
[Params]::SystemParametersInfo($SPI_SETDESKWALLPAPER, 0, $Image, $fWinIni) | Out-Null
I also added on the register property changes, this at the end: | Out-Null
Thank you for your script, it’s great 🙂
Martin
Thank you! works like a charm! Setting multiple notebooks with a special background this way helps a lot!
PS: A coomand line (linux) admin…
Samir
Worked like a charm, brother! Thank you so much.
Seabass
This still helps me to this day every time I lose this function and my boss asks me to change everyone’s wallpaper. Thanks, Joe!
Jose Espitia
Haha! Welcome back, I’ll be here for a while
Antonio
FINALLY A SCRIPT THAT WORKS!!!! Thank you!!!! This is one script that does what it is intended to do: set an image, as the background, with the style you choose. You would think this would be simple, but 5 scripts later, I landed here. I’m done looking since this finally works.
Jose Espitia
I’m glad it worked out for you!
Mo Ash
Hi,
Thanks for your very useful script. How do you replace the “C:\it\wallpaper\LockScreen.jpg” with a url?
I have tried to upload the background and use the url address but it doesn’t work.
Thanks
Élio
Hi Jose,
Thanks for the nice function that you created. It worked just fine!
Do you know if there is a way to modify the function so that it does not print an output to the terminal when being run?
Kind regards,
Élio
Breno
Amazing work! Thanks a lot!
Louie
I used the script but my original background overlaps the new image, so I have the color bars on the top and bottom (Because I used fit) but I don’t see the image.
Marc
A bunch of years later … Still usefull.
If it could be a Powershell default function it would be great.