Desktop photo for all PC's in the domain



  • I found this PowerShell script, that does what you are trying to do.
    https://smulpuru.wordpress.com/2015/04/01/change-wallpaper-using-windows-api-systemparametersinfo-from-user32-dll/

    $setwallpapersource = @"
    using System.Runtime.InteropServices;
    public class wallpaper
    {
    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 )
    {
    SystemParametersInfo( SetDesktopWallpaper, 0, path, UpdateIniFile | SendWinIniChange );
    }
    }
    "@
    Add-Type -TypeDefinition $setwallpapersource
    [wallpaper]::SetWallpaper("\\SERVER1\wallpaper.jpg")
    

    The only thing I've noticed with this script is how fast these locations get updated with the new background.

    %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Themes\TranscodedWallpaper
    %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Themes\CachedFiles\

    For some reason in the CachedFiles, it will still so the previous background instead of the new one and TranscodedWallpaper file doesn't update.

    Even running this command requires multiple attempts before the wallpaper show up.
    RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters 1, True



  • @black3dynamite said in Desktop photo for all PC's in the domain:

    I found this PowerShell script, that does what you are trying to do.
    https://smulpuru.wordpress.com/2015/04/01/change-wallpaper-using-windows-api-systemparametersinfo-from-user32-dll/

    $setwallpapersource = @"
    using System.Runtime.InteropServices;
    public class wallpaper
    {
    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 )
    {
    SystemParametersInfo( SetDesktopWallpaper, 0, path, UpdateIniFile | SendWinIniChange );
    }
    }
    "@
    Add-Type -TypeDefinition $setwallpapersource
    [wallpaper]::SetWallpaper("\\SERVER1\wallpaper.jpg")
    

    The only thing I've noticed with this script is how fast these locations get updated with the new background.

    %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Themes\TranscodedWallpaper
    %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Themes\CachedFiles\

    For some reason in the CachedFiles, it will still so the previous background instead of the new one and TranscodedWallpaper file doesn't update.

    Even running this command requires multiple attempts before the wallpaper show up.
    RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters 1, True

    So it's not really a reliable script/method then?



  • @ccwtech said in Desktop photo for all PC's in the domain:

    @black3dynamite said in Desktop photo for all PC's in the domain:

    I found this PowerShell script, that does what you are trying to do.
    https://smulpuru.wordpress.com/2015/04/01/change-wallpaper-using-windows-api-systemparametersinfo-from-user32-dll/

    $setwallpapersource = @"
    using System.Runtime.InteropServices;
    public class wallpaper
    {
    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 )
    {
    SystemParametersInfo( SetDesktopWallpaper, 0, path, UpdateIniFile | SendWinIniChange );
    }
    }
    "@
    Add-Type -TypeDefinition $setwallpapersource
    [wallpaper]::SetWallpaper("\\SERVER1\wallpaper.jpg")
    

    The only thing I've noticed with this script is how fast these locations get updated with the new background.

    %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Themes\TranscodedWallpaper
    %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Themes\CachedFiles\

    For some reason in the CachedFiles, it will still so the previous background instead of the new one and TranscodedWallpaper file doesn't update.

    Even running this command requires multiple attempts before the wallpaper show up.
    RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters 1, True

    So it's not really a reliable script/method then?

    No, Windows is the not reliable thing. Not the commands.



  • @jaredbusch said in Desktop photo for all PC's in the domain:

    @ccwtech said in Desktop photo for all PC's in the domain:

    @black3dynamite said in Desktop photo for all PC's in the domain:

    I found this PowerShell script, that does what you are trying to do.
    https://smulpuru.wordpress.com/2015/04/01/change-wallpaper-using-windows-api-systemparametersinfo-from-user32-dll/

    $setwallpapersource = @"
    using System.Runtime.InteropServices;
    public class wallpaper
    {
    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 )
    {
    SystemParametersInfo( SetDesktopWallpaper, 0, path, UpdateIniFile | SendWinIniChange );
    }
    }
    "@
    Add-Type -TypeDefinition $setwallpapersource
    [wallpaper]::SetWallpaper("\\SERVER1\wallpaper.jpg")
    

    The only thing I've noticed with this script is how fast these locations get updated with the new background.

    %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Themes\TranscodedWallpaper
    %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Themes\CachedFiles\

    For some reason in the CachedFiles, it will still so the previous background instead of the new one and TranscodedWallpaper file doesn't update.

    Even running this command requires multiple attempts before the wallpaper show up.
    RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters 1, True

    So it's not really a reliable script/method then?

    No, Windows is the not reliable thing. Not the commands.

    Non-deterministic behaviour 😞



  • @ccwtech said in Desktop photo for all PC's in the domain:

    @black3dynamite said in Desktop photo for all PC's in the domain:

    I found this PowerShell script, that does what you are trying to do.
    https://smulpuru.wordpress.com/2015/04/01/change-wallpaper-using-windows-api-systemparametersinfo-from-user32-dll/

    $setwallpapersource = @"
    using System.Runtime.InteropServices;
    public class wallpaper
    {
    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 )
    {
    SystemParametersInfo( SetDesktopWallpaper, 0, path, UpdateIniFile | SendWinIniChange );
    }
    }
    "@
    Add-Type -TypeDefinition $setwallpapersource
    [wallpaper]::SetWallpaper("\\SERVER1\wallpaper.jpg")
    

    The only thing I've noticed with this script is how fast these locations get updated with the new background.

    %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Themes\TranscodedWallpaper
    %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Themes\CachedFiles\

    For some reason in the CachedFiles, it will still so the previous background instead of the new one and TranscodedWallpaper file doesn't update.

    Even running this command requires multiple attempts before the wallpaper show up.
    RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters 1, True

    So it's not really a reliable script/method then?

    The PowerShell script worked correctly when I ran it locally. I have not tried it when the wallpaper was set to a server.

    I just not sure if the GPO uses SystemParametersInfo or RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters 1, True



  • @ccwtech said in Desktop photo for all PC's in the domain:

    @kelly said in Desktop photo for all PC's in the domain:

    @ccwtech said in Desktop photo for all PC's in the domain:

    @kelly said in Desktop photo for all PC's in the domain:

    @ccwtech said in Desktop photo for all PC's in the domain:

    @kelly said in Desktop photo for all PC's in the domain:

    @ccwtech said in Desktop photo for all PC's in the domain:

    @kelly said in Desktop photo for all PC's in the domain:

    @ccwtech said in Desktop photo for all PC's in the domain:

    @dustinb3403 said in Desktop photo for all PC's in the domain:

    The easiest way I've found to get a GPO to update, is to one, set it to "update" and in cases like screensavers (backgrounds etc), literally just name the anything else.

    "bg.jpg" the new one gets changed to "bg1.jpg" etc.

    Trying to do this without the user touching GPO. I'm still fuzzy on how to set the GPO to update?

    You only change the file copy GPO. I would have a different file name in your source file like 20180907_info.jpg. That way the GPO will process because it detects a change event. You can have the same destination file.

    That would require editing of the GPO that applies the wallpaper.

    It depends on how you set it up. My preferred method, and I believe best practice, is that you split your policies. The User policy applies the wallpaper based on <localpath>\picture.jpg. The computer policy copies the wallpaper from <remotepath>\20180907_picture.jpg to <localpath>\picture.jpg. When you need to update the wallpaper you place 2018xxxxx_picture.jpg in <remotepath> and update the policy to the new file name. When the machine reboots or refreshes its policies it copies the file from <remotepath> to <localpath>. When the user logs in the user policy is applied which uses the same file name (because as far as it is concerned nothing changed), but the new wallpaper is loaded because it is a different image.

    Does that make sense?

    Yes, so I need to point the wallpaper to load it from the computer not the server?

    Yes, for the user policy it is the local path on the computer.

    Kelly, when you move the file will it update if you don't update the policy with the new file name but instead keep the name the same in the wallpaper gpo?

    So if you move photo.jpg from C:\Users\Public\ to C:\Temp\Shared? I'm not completely sure I understand the scenario you're describing?

    What I want to do is to put a photo names info.jpg either on the server and have a GPO to point to that file to use as wallpaper.

    Without touching the GPO that points to info.jpg I want the end user to be able to replace info.jpg with another file called info.jpg that has the same name but it's a different photo with the same name. Then the desktop updates on each workstation.

    It seems like either copying the file from the server to the local workstation or pointing to the file on the server both require that you change the GPO for wallpaper and do a info1.jpg, info2.jpg to update the wallpaper GPO each time you change the photo.

    I don't want the end user to mess with GPO but do trust them to simply save another file with the same name.

    If you are allowing end users to change their desktop images why are you setting it via GPO? That is a lot of effort for little return.

    As for your third paragraph I'm not sure how to answer what you're stating without restating my posts above. I guess I don't understand what you want to achieve as your end goal and what you want to avoid along the way.



  • @kelly said in Desktop photo for all PC's in the domain:

    @ccwtech said in Desktop photo for all PC's in the domain:

    @kelly said in Desktop photo for all PC's in the domain:

    @ccwtech said in Desktop photo for all PC's in the domain:

    @kelly said in Desktop photo for all PC's in the domain:

    @ccwtech said in Desktop photo for all PC's in the domain:

    @kelly said in Desktop photo for all PC's in the domain:

    @ccwtech said in Desktop photo for all PC's in the domain:

    @kelly said in Desktop photo for all PC's in the domain:

    @ccwtech said in Desktop photo for all PC's in the domain:

    @dustinb3403 said in Desktop photo for all PC's in the domain:

    The easiest way I've found to get a GPO to update, is to one, set it to "update" and in cases like screensavers (backgrounds etc), literally just name the anything else.

    "bg.jpg" the new one gets changed to "bg1.jpg" etc.

    Trying to do this without the user touching GPO. I'm still fuzzy on how to set the GPO to update?

    You only change the file copy GPO. I would have a different file name in your source file like 20180907_info.jpg. That way the GPO will process because it detects a change event. You can have the same destination file.

    That would require editing of the GPO that applies the wallpaper.

    It depends on how you set it up. My preferred method, and I believe best practice, is that you split your policies. The User policy applies the wallpaper based on <localpath>\picture.jpg. The computer policy copies the wallpaper from <remotepath>\20180907_picture.jpg to <localpath>\picture.jpg. When you need to update the wallpaper you place 2018xxxxx_picture.jpg in <remotepath> and update the policy to the new file name. When the machine reboots or refreshes its policies it copies the file from <remotepath> to <localpath>. When the user logs in the user policy is applied which uses the same file name (because as far as it is concerned nothing changed), but the new wallpaper is loaded because it is a different image.

    Does that make sense?

    Yes, so I need to point the wallpaper to load it from the computer not the server?

    Yes, for the user policy it is the local path on the computer.

    Kelly, when you move the file will it update if you don't update the policy with the new file name but instead keep the name the same in the wallpaper gpo?

    So if you move photo.jpg from C:\Users\Public\ to C:\Temp\Shared? I'm not completely sure I understand the scenario you're describing?

    What I want to do is to put a photo names info.jpg either on the server and have a GPO to point to that file to use as wallpaper.

    Without touching the GPO that points to info.jpg I want the end user to be able to replace info.jpg with another file called info.jpg that has the same name but it's a different photo with the same name. Then the desktop updates on each workstation.

    It seems like either copying the file from the server to the local workstation or pointing to the file on the server both require that you change the GPO for wallpaper and do a info1.jpg, info2.jpg to update the wallpaper GPO each time you change the photo.

    I don't want the end user to mess with GPO but do trust them to simply save another file with the same name.

    If you are allowing end users to change their desktop images why are you setting it via GPO? That is a lot of effort for little return.

    As for your third paragraph I'm not sure how to answer what you're stating without restating my posts above. I guess I don't understand what you want to achieve as your end goal and what you want to avoid along the way.

    I think you aren't understanding what I am asking. I'm allowing the office manager to put a jpg in a directory, that's it. Not the end users to change their desktops.



  • @ccwtech said in Desktop photo for all PC's in the domain:

    Without touching the GPO that points to info.jpg I want the end user to be able to replace info.jpg with another file called info.jpg that has the same name but it's a different photo with the same name..

    Here's the source of my confusion.

    If you do allow the office manager to do that it will work fine until the file copy GPO needs to run, and then if you are setting it with a REPLACE then it will overwrite the info.jpg. If you have a specific site where you are allowing an office manager to do this and it is properly configured in sites and settings then you can exclude that site from the GPO (either one).



  • So if the process is.... manager puts file at X location. Awaits GPO to roll it out.

    Maybe just as easy is making a script that takes a file and pushes it out. Assuming most computers are on at the same time. Make a single script that the manager runs and it just pushes out the file directly.



  • If this was Linux (and you can do almost the exact some with windows)...

    for i in $(cat desktoplist); do scp file $i:/filelocation/l done
    

    That easy. And you can wrap that in a command to make it even easier.

    update_desktop file


  • @kelly Here is the gpresult.html
    2_1536679679265_2018-09-11 10_24_45-Microsoft Edge.png 1_1536679679265_2018-09-11 10_25_04-Microsoft Edge.png 0_1536679679263_2018-09-11 10_25_19-Microsoft Edge.png



  • @i3 It looks like you're setting the wallpaper twice. Once with pure group policy and then again with a reg key.



  • @kelly I noticed that once I exported the gpresult. I had since removed it but it didn't change anything. I made sure to run gpupdate and even rebooted a few times. Still shows a black background, however, the correct file is selected in the "personalize" menu to manually set the background.



  • @i3 said in Desktop photo for all PC's in the domain:

    @kelly I noticed that once I exported the gpresult. I had since removed it but it didn't change anything. I made sure to run gpupdate and even rebooted a few times. Still shows a black background, however, the correct file is selected in the "personalize" menu to manually set the background.

    And the user can open the file and it shows not a black background? Just making sure it isn't a permissions issue. Are you viewing the desktop of the user at their screen or through a remote access tool like TeamViewer or RDP?



  • Thank you for the help. By posting the screenshots, I realized I had a typo in the file extension. .png vs .jpg
    Once I double checked them all it now works.