Set-Wallpaper Powershell Function

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

39 Comments

  1. 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

  2. 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"

  3. forget about it

  4. Perfect !

    Finally a script that works reliably on Windows 10 !

    Many BIG THANKS !

  5. 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

  6. 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.

  7. Just great !

  8. 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 ?

  9. It would be great if set-wallpaper takes in monitorID as additional parameter, so it only sets wallpaper for particular monitor.

  10. 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.

  11. 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.

  12. 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.

  13. 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.

      • 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.

  14. 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!

  15. I’m wondering if this can be modified to change the folder of a slideshow instead of a specific image?

    • Jose Espitia

      April 9, 2021 at 5:07 pm

      I’m sure you could use a ForEach loop to go through and loop through the images from the folder.

  16. 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.

  17. Perfect! I Update your script with an Help parameter that show the informations and how use the script! Well done!

  18. 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.

  19. 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

  20. 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

  21. 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 🙂

  22. Thank you! works like a charm! Setting multiple notebooks with a special background this way helps a lot!
    PS: A coomand line (linux) admin…

  23. Worked like a charm, brother! Thank you so much.

Leave a Reply