Is it possible to set screen saver settings without logout/login?

Hi all,

This is actually not really powershell per say but maybe someone have a solution to the problem.
Basically I’ve a customer where the windows userbase are really small (mainly mac users) but we need to push out some changes to the windows users.
They are not in an AD, otherwise this would have been a 5min thing with a GPO :slight_smile:
But we need to set the screen saver lockout settings and apply them.

It’s easy to set the settings in the registry via powershell.
But it seems that the user have to login twice, one for setting the regkeys for that user.
The second time for the settings to be in effect.
Possibly I could solve one login by running a scheduled task that loads the user profiles and set the settings before even a login.
But it seems like a band aid solution :slight_smile:

Have tried various solutions that I found on the net but nothing really seem to work reliably on Windows 10:

E.g. using C# and SendMessageTimout, example of code:

Or using the command line:
RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters ,1 ,True

Has anyone succeeded to update registry settings and had them take effect without a reboot or logout?
Even better if you’ve succeeded with the screen saver settings like “On resume, display logon screen”.

Thanks in advance.

If the user already exists on the computer. You could load a user’s ntuser.dat file with reg.exe and then set the registry with powershell. The code below is from a function I played around with to transfer one user’s setting to another user. Anyways the code shows how to load a user’s profile so you can use powershell’s registry drive.

 

Function Set-ProgID{
param(

    [Object[]]$User,
    [Object[]]$Ext,
    [Object[]]$ProgID
)

If ($user -NE $env:USERNAME)
    {

$UserRoot = "$ENV:SystemDrive\users\$User\ntuser.dat"
reg.exe load "HKLM\$user" $USERROOT

New-ItemProperty -Force -path "HKU:\$user\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\$Ext\userchoice"  -Name ProgID -Value $ProgID

reg.exe unload "HKLM\$user" 

[GC]::Collect()
 
    }

} #End set-progID

Yeah, I thought about it and I might do it that way.

Actually tested the command line option in a VM now and it seems to work.
But sometimes you have to run it twice with a time delay.
Not sure whats up with that but I’ll report back if I can get it working reliably.

Please let me know what you do. Good luck

So it seems it’s possible but had to jump through some hoops to get there.
Will probably write a blog post about it, when I get the time.

So what seems to work (still in testing) and we were using Puppet for the script deployment.

  1. Deploy the two powershell scripts via puppet.
  2. Run the script that will create the scheduled task. (puppet triggers the create scheduled task powershell script)
    The scheduled task will be created to run in the currently logged in user context.
  3. The second script to check/set settings will check the registry if the settings are correct, if not reset them.
    At the end of the script run the command line example in the first post above.
    Pause for a while (I used 60 seconds)
    Run the same command again

The key to make it work was that the “refresh” command line had to be run in the user context.
Doesn’t work to run the task as e.g. SYSTEM, the sessions are isolated and it only seem to affect the current session.
The puppet agent runs as SYSTEM so couldn’t AFAIK just run it under the user context without going via a scheduled task.
And then we have the pause between refresh commands.

To reliably make it work it seems that I had to trigger it twice and with a pause in between.
Haven’t checked the lowest possible time interval but 60 seconds worked.
Sometimes it worked on the first run but most of the time it had to be triggered twice with a pause.
Used a 45 second screen saver timout during testing to see at which point it kicked in.
Of course I could have skipped the pause and second command and just wait for the next scheduled run.
But it was possible to do it one task run.