Changing Desktop Wallpaper using Windows PowerShell

Today I was asked ‘how can I change my desktop wallpaper using Windows PowerShell? Actually the truth is, I was asked if there was any way of changing the wallpaper based on the resolution of the display. So if the computer was running a 1440×900 desktop then show a small wallpaper…if it was running 1920×1200 then show a higher resolution wallpaper.

It turns out, it’s not that difficult. But I will admit up front, that this is a very basic script. There’s no error checking and it’s only doing a simple check for one resolution and if it’s not that resolution it just assumes its the other one. If this was something I was putting in as a real solution, I’d want the script to cater for a lot more than 2 resolutions.

Anyway, regardless here it is:

$CurrentRes = (Get-WmiObject -Class Win32_VideoController).VideoModeDescription;
If (($CurrentRes.Trim()).Contains(“1440 x 900”))
{
reg add “HKCU\Control Panel\Desktop” /v WallPaper /d “C:\Wallpaper\1440×900.jpg” /f
RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters ,1 ,True
}
else
{
reg add “HKCU\Control Panel\Desktop” /v WallPaper /d “C:\Wallpaper\1920×1200.jpg” /f
RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters ,1 ,True
}

 

Now even though this script works great, it only worked ‘some of the time’… It would update the registry key, but the desktop wallpaper wouldn’t always refresh (A log off, log back on would fix it, but who want’s to do that?).

So another option is to access the Win32 API directly. The code below I didn’t write, I think I found it on PoshCode…apologies to the actual author if that’s not the case.

# Script to change the desktop wallpaper depending on the resolution of the monitor.
# Change the resolution at the bottom of this script to your first resolution and provide the wallpaper name
# If the script detects a different resolution, it will load and display the second wallpaper.
# 0: Tile 1: Center 2: Stretch 3: No Change

Add-Type @”
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace Wallpaper
{
public enum Style : int
{
Tile, Center, Stretch, NoChange
}
public class Setter {
public const int SetDesktopWallpaper = 20;
public const int UpdateIniFile = 0x01;
public const int SendWinIniChange = 0x02;
[DllImport(“user32.dll”, SetLastError = true, CharSet = CharSet.Auto)]
private static extern int SystemParametersInfo (int uAction, int uParam, string lpvParam, int fuWinIni);
public static void SetWallpaper ( string path, Wallpaper.Style style ) {
SystemParametersInfo( SetDesktopWallpaper, 0, path, UpdateIniFile | SendWinIniChange );
RegistryKey key = Registry.CurrentUser.OpenSubKey(“Control Panel\\Desktop”, true);
switch( style )
{
case Style.Stretch :
key.SetValue(@”WallpaperStyle”, “2”) ;
key.SetValue(@”TileWallpaper”, “0”) ;
break;
case Style.Center :
key.SetValue(@”WallpaperStyle”, “1”) ;
key.SetValue(@”TileWallpaper”, “0”) ;
break;
case Style.Tile :
key.SetValue(@”WallpaperStyle”, “1”) ;
key.SetValue(@”TileWallpaper”, “1”) ;
break;
case Style.NoChange :
break;
}
key.Close();
}
}
}
“@

# And this part of the script is pretty much the same. Do a quick check on the resolution and choose a wallpaper based on the result

$CurrentRes = (Get-WmiObject -Class Win32_VideoController).VideoModeDescription;
If (($CurrentRes.Trim()).Contains(“1440 x 900”))
{
[Wallpaper.Setter]::SetWallpaper( ‘C:\Wallpaper\1440×900.jpg’, 0 )
}
else
{
[Wallpaper.Setter]::SetWallpaper( ‘C:\Wallpaper\1920×1200.jpg’, 0 )
}

 

And that’s pretty much it. Personally I’d prefer to use the second option and access the Win32 API because in my own tests I found that it worked flawlessly every single time on my Windows 8.1 machine.

 

 
Comments

thank you, your post is very helpful for me, i have successfully composed both of 2 as 1 script. also thank for both of 2 actual author for this kind of way to change wallpaper.

You’re very welcome. Glad it helped you!

Leave a Reply