Powershell change wallpaper on windows 10 for current logged on user

I was given a challenge to solve for making a little fun in the office. So I’ve tried to setup a VM lab with a windows server 2012 R2 & client Windows 10 to test this on. Tried to create a thread on Stackoverflow, but did not really got any good response regarding powershell and how this can be done.

See also the thread I’ve tried to create here on Stackoverflow:

https://stackoverflow.com/questions/64731177/powershell-change-wallpaper-on-windows-10-for-current-logged-on-user

The challenge I am facing:

Windows 10 is not always refreshing wallpaper when set, using the command by using the psexec:
rundll32.exe user32.dll, UpdatePerUserSystemParameters, 1, true
This seems to be due to a limitation in rundll32.exe or user32.dll not sure why.

I instead have to use a new theme that I have created by copy that to the client and load it with psexec to present it to the user instantly without logoff or restart. Although sometimes it does just not work or it simply just make the background black, like it’s removing the wallpaper completely when I run the script more times to ensure that it works even though how many times I run it. Keep in mind this script is dependent on the client is online by that means that the DNS is working proper and you can also ping the host.

How can I ensure that the wallpaper is always being refreshed and working? - and is there a better method of this you can find, then kindly let me know because I tried to search on the internet but could not find anything working as good as this I’ve made so far on Windows 10 through powershell.

The script I currently got working right now is the following:

Download the source code here:

  • save this as ChangeDesktopBackgroundRemotely.ps1 -- Main script you run
  • save this as newtheme.theme in "C:\tmp" on your server
  • save this as refreshbg.ps1 in "C:\tmp" on your server
  • save FCK.jpg as FCK.jpg in "C:\tmp" on your server
  • save aalborg.jpg as aalborg.jpg in "C:\tmp" on your server

Personally, if I was in the office and someone toggled my wallpaper, I would think my system was infected with malware (which = calls to help desk)as that is a common practice for malware. Aside from that, it would piss me off. I enjoy a blank walpaper and like it kept that way.

Just my $.02 :slight_smile:

@TonyD05 Sure. But keep in mind this was only with approval of my boss beacuse he like to make some fun in the office (yes there is some types who actually likes doing that) in this example the whole point was because of a football team had won a match he wanted to show the result of the match some persons background. This got me thinking and curious because I found it as a funny task, so that is why, there is no harm done here :-). Of course, some would be pissed if they just lost a match for their winning team and then seeing that background, but what the heck - that is the fun of it haha. So the short version, everything above was with approval of my manager and only for good intentions under control of course ;-)…

This is not trivial as the action you’re trying to take has purposefully been blocked/made extremely difficult. As the commenters on the stack overflow thread said you have to run as that user. Without knowing the users credentials you are left with scheduled tasks or windows API. I’ve had success doing your desired task using the windows API code below in combination with two modules. I won’t provide the entire code as I feel uncomfortable doing so, but assure you with the three items listed below, you can achieve your goal.

You already have the code below, as I copied it from your previously commented link.

$imgPath="C:\temp\Picture 1.jpg"

$code = @' 
using System.Runtime.InteropServices; 
namespace Win32{ 
 
     public class Wallpaper{ 
        [DllImport("user32.dll", CharSet=CharSet.Auto)] 
         static extern int SystemParametersInfo (int uAction , int uParam , string lpvParam , int fuWinIni) ; 
 
         public static void SetWallpaper(string thePath){ 
            SystemParametersInfo(20,0,thePath,3); 
         }
    }
 } 
'@
 
add-type $code 
 
#Apply the Change on the system 
[Win32.Wallpaper]::SetWallpaper($imgPath)

The combination of the following two modules.

RunAsUser

Install-Module RunAsUser

Invoke-CommandAs

Install-Module Invoke-CommandAs

Push BGinfo to the machines and call that to update the wallpaper:

@Matt Bloomfield - thanks, that actually works every time running bginfo.exe with psexec, although I am kinda missing a way to remove all the text it also includes within that bginfo config file. Don’t know how to do that yet. Do you have any suggestion to that?

 

You need to copy a .bgi config file with no text in it (you can create it the first time you run bginfo) and call that config file when you run bginfo:

c:\temp\bginfo.exe c:\temp\myblankconfigfile.bgi /timer:0