Imagine that there’s a webcast that you absolutely need to record and your girlfriend calls because she had a bad dream and you need to go to give her consolation, or it’s your daughter’s birthday, or simply 11 pm because the Earth is huge and the timezones suck. Your first reaction is to simply try to record the webcast but this is a corporate PC and group policy is configured to lock the desktop after x minutes of inactivity. What do you do?
I found myself in this situation a few days ago, and did not want to search the internet and download a random executable simulating user activity and doing who knows what else on my computer.
Instead I wrote this simple PowerShell script:
param($minutes = 60) $myshell = New-Object -com "Wscript.Shell" for ($i = 0; $i -lt $minutes; $i++) { Start-Sleep -Seconds 60 $myshell.sendkeys(".") }
All the script does is creates a Windows scripting shell com object, and then for the specified number of minutes (which is a script parameter) every minute presses the “.” key.
Then I saved the script as Prevent-Screensaver.ps1 file (“prevent” is not a proper PowerShell verb, but disable- or stop- do not seem quite right…) and started it from PowerShell command-line: & c:\Prevent-Screensaver.ps1 120
One other thing which I also did was starting a notepad and clicking into it. This made the script output the dots into the application rather than overload Windows input buffer (which would have caused the OS to start beeping.)
Oh, and before anyone adds comments on how I have just ruined desktop security in the enterprise… By using this you might be circumventing security measures which your company might have for a reason. Check with your HR/IT/legal department/manager when in doubt. 😉
[UPDATE] Check out what Claus posted in his comments here – an even better way of preventing the screensaver by moving the mouse cursor a bit.
Tags: PowerShell, hack
Using Jaykul’s WASP to send mouse clicks would help with the input buffer problem, and remove the need for launching notepad to accept the keys.
Actually I did this a while back with a simple autoit script that I compiled as an .exe. So when I need this functionality I just run that program, and kill it when I’m done.
I did the same thing with AutoIt … however I just had the mouse move 1 pixel.
Hi can u share that 1pixel mouse moving program
Yep, good comments. I love Jaykul’s stuff but wanted something simple and self-contained so I ended up with the keys approach.
talk about using the wrong tool for the job, why is powershell even involved, just some excuse not to use a WSH script (I know its tagged a hack and you are a powershell guy, but still) The proper way to do this would be to use the windows api (You can call the native api with autoit, so using a key pressing hack there is even worse)
And a “.”? why not toggle the start menu with ctrl+esc or something (print screen maybe if the scripting supports an escape code for that)?
I did something similar in AutoIt as well, just moving the mouse one “pixel”.
So I thought I would try the same in PowerShell, here is what I ended up with, it will move the mouse one “Pixel” to the right, which is hardly noticeable.
$Pos = [System.Windows.Forms.Cursor]::Position
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point((($Pos.X) + 1) , $Pos.Y)
What happen when your program move the mouse enough times that the screen end, do yo get bips or what ?
So, how do you make the script stop. Would a restart do the job? I don’t want the sleep suppression to be permanent.
In PowerShell, you can press Ctrl + C to stop a script that is currently running.
Just to make easier for others. Following script will move move left 11 pixel then right 1 pixel. For 600 minutes (10 hours), after every 300 seconds.
Add-Type -AssemblyName System.Windows.Forms
for ($i = 0; $i -lt 600; $i++) {
$Pos = [System.Windows.Forms.Cursor]::Position
if (($i % 2) -eq 0) {
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point((($Pos.X) + 1) , $Pos.Y)
}
else {
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point((($Pos.X) – 1) , $Pos.Y)
}
Start-Sleep -Seconds 300
}
#This is how to execute it — powershell -ExecutionPolicy ByPass -File path_to_script\name_of_file.ps1
This script worked for me on win 10. Thank you so much Dmitry!
Claus,
This is way-way better than what I originally used!
Learning something new every day. Thanks a lot for the tip!
Dmitry
My guess is that it will just stop at the border.
However, you can just make it move to the side and back by doing something like:
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point((($Pos.X) + 1) , $Pos.Y)
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point($Pos.X , $Pos.Y)
i tried the same but this is not preventing the screesaver from starting, so i landed on this page, but a keypress is also not good because it writes where the Focus is. Next I tried to consume the pressed key immedialtly but no chance 😦
My problem is that my screen saver starts even though Powershell is moving the mouse pointer around.
“this is a corporate PC and group policy is configured to lock the desktop after x minutes of inactivity.”
So how do you install PowerShell?
Comes standard on Win 7. But yes, I hear you: in some environments it might be not present and policies might prevent installation… Luckily in my situation this was not the case.
Here’s something similar I’ve used in VBScript
Dim WSHShell
Set WSHShell = CreateObject(“WScript.Shell”)
‘ Press key every 1.5 minutes
Do While True
WSHShell.SendKeys “.”
WScript.Sleep 90000
Loop
I know you are looking to avoid 3rd party tools, but this app has saved my life a thousand times, and would be perfect for what you’re doing It’s SO EASY!!
http://www.autohotkey.com/docs/Tutorial.htm
Combining Delon’s approach with the F15 keypress from Caffeine, I came up with this:
Dim WshShell
Set WshShell = WScript.CreateObject(“WScript.Shell”)
Do While True
WshShell.SendKeys(“{F15}”)
WScript.Sleep(55000)
Loop
It works on Windows XP SP3 and Windows 2008 R2, so I assume it works on everything else in between (2003, 2008, Vista, 7). And the F15 keypress does not seem to have any side effects. Pasting the above script in a *.vbs file and putting it in my user’s Startup folder works for me like a charm.
(Note: if you use this hack in a Terminal Service session and minimize the Terminal Service client’s window, the screen will get locked locked just as usual. I guess you cannot send keys in the session via SendKeys() if it’s minimized.)
Hey the scripts does work like a charm.Thank you!
– just wondering which process to kill in task manager, in case I want to stop the script from working.
If you kill WSCRIPT.EXE that’s the Windows Scripting Host, which the process that’s running the script. If the script is running in a console window, the process might be called CSCRIPT.EXE instead.
Sendkeys F15 on my system makes my num-lock toggle on and off.
Win 8.1 pro x64
Logitech K350 keyboard.
Hi. .. I have a script In which i run a ‘.exe’. This .exe waits for an input from user to log some events in a file. I want to develop an automated script that runs the .exe and also simulates the key press that will be an input to the .exe for it to continue. Can anybody help me. Thanks in advance.
Hi Dmitry,I used the code of claus for moving the mouse pointer.
The following is the error am getting in my cmd prompt.Thanks in advance.
Unable to find type [System.Windows.Forms.Cursor]: make sure that the assembly
containing this type is loaded.
At D:\myscript.ps1:1 char:37
+ $Pos = [System.Windows.Forms.Cursor] <<<< ::Position
+ CategoryInfo : InvalidOperation: (System.Windows.Forms.Cursor:S
tring) [], RuntimeException
+ FullyQualifiedErrorId : TypeNotFound
New-Object : Cannot find type [System.Drawing.Point]: make sure the assembly co
ntaining this type is loaded.
At D:\myscript.ps1:2 char:53
+ [System.Windows.Forms.Cursor]::Position = New-Object <<<< System.Drawing.Poi
nt((($Pos.X) + 1) , $Pos.Y)
+ CategoryInfo : InvalidType: (:) [New-Object], PSArgumentExcepti
on
+ FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewOb
jectCommand.
Please advise on how to load the assemblies.
Which version of PowerShell are you using? 3.0, right? If so, see which architecture that is. Chances are that you are on x64 Windows and the assembly only exists for the architecture different from the one that you are using. Try the same code in regular PowerShell and PowerShell x86 and see whether one of these works.
its not a x86 or 64 issue. you need to run this command
[System.Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”)
param($minutes = 60)
$myshell = New-Object -com “Wscript.Shell”
for ($i = 0; $i -lt $minutes; $i++) {
Start-Sleep -Seconds 50
$myshell.sendkeys(“{F15}”)
}
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! above in C:\lock.ps1
powershell.exe -windowstyle hidden -file C:\lock.ps1
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! above in .bat extension
This works good for me in win 7 64bit thanks #Dmitry
There’s an android app called “Timeout Blocker” that vibrates at intervals you set and you can put your mouse on it. Says not to use it at work though 🙂 https://play.google.com/store/apps/details?id=com.isomerprogramming.application.timeoutblocker&hl=en
old topic but thought to share experience in case some1 comes here:
I confirm mouse position does not prevent screensaver or sleep (probably because mouse is actually not moved, just redrawn).
However sendkey does prevent!
I did not experience with f15 – I needed to see the script is/was working 🙂 just start the script with notepad.exe, and you don’t have to open manually.
also for the loop, why not timeless? my code:
notepad.exe
$myshell = New-Object -com “Wscript.Shell”
$i=1
while ($I -eq 1) {
$myshell.sendkeys(“.”)
start-sleep -Seconds 30
}
thanks for all
cheers
K
@cgsilver….sorry for the noob/basic question….I’m trying to use this script you posted but don’t exactly undertsand what to script it in, how to save it, and how to run it?
I literally copied the scipt, pasted it into notepad, saved as “MouseMove.ps1” and that doesn’t seem to work!
Can you give me a basic step 1-10 on how to copy, paste, save, and then run at start-up or Task Schedule.
I have the same issue some of you all do. We have a PC at our Hospital that needs to never go to sleep, lock-screen, screensave, etc. and our Group Policy keeps reverting back to our standard 20min lock-screen setting (we can’t figure out why the setting won’t hold, it works for a day or so then breaks again). So, if this could keep the PC “awake/active” that would allow the PC to always be on until it reboots every 7am to refresh the Citrix session.
Makes sense!?! Please help!!!!
Great thread, Kirk, I don’t know if you got a resolution but copying and pasting the code, for me from IE9, gave me the wrong quotation marks; ” “.
i had to change them manually in notepad after pasting. HTH
Good update Dara. To be honest I think we got around it with an AutoIT script one of our affiliates came up with. I also stumbled upon this not too long ago as well. This ScrSlayer might help some folks if they find this article.
http://daniel-lange.com/archives/34-Disabling-a-group-policyd-screensaver-on-Windows.html
This was useful too….
I harvested the ideas above and wrapped it into a re-usable function
Function Pause-ScreenSaver
{
Param(
[Bool]$Continue = $True, #If This Is True, The Function Will Run Forever
[Int]$DefaultSleepTime = 60 #Time To Wait Before Re-Looping
)
#Create A New Shell Com Object
$Shell = New-Object -COM “WScript.Shell”
#While $Continue Is Tue, Loop
While ($Continue -EQ $True)
{
$Shell.SendKeys(“F15”)
Start-Sleep $DefaultSleepTime
}
}
#########################################################
# Prevent-Screensaver
#########################################################
# This script moves the mouse cursor
# (or “presses” a keyboard key) every minute
# for specified number of minutes which makes
# Windows “think” you are at your desktop
# so the screensaver does not start and the desktop
# does not get locked.
#########################################################
# Usage:
# & c:\filepath\Prevent-Screensaver.ps1 -Minutes 120
# Makes the script move the mouse (press “.”) for 120 minutes.
# Start notepad or another app and put focus there
# to see the dots appear and prevent beeping
########################################################
# (c) Dmitry Sotnikov + T.H. Schmidt
# https://dmitrysotnikov.wordpress.com
########################################################
param($minutes = 60)
[void] [System.Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”)
$myshell = New-Object -com “Wscript.Shell”
for ($i = 0; $i -lt $minutes; $i++) {
Start-Sleep -Seconds 60
# $myshell.sendkeys(“.”)
$Pos = [System.Windows.Forms.Cursor]::Position
[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point((($Pos.X) + 1) , $Pos.Y)
}
Hi,
When I run this code I keep on getting the num lock toggled on and off. I see at least two posts where people have experienced this. Has anyone found an explanation or resolution for this issue?
I run it on Windows 7, 64 bit.
Thanks
$Shell = New-Object -ComObject Wscript.Shell
$Shell.SendKeys(‘{PRTSC}’)
Sends a Print Screen to the computer resulting in absolutely nothing happening. It just overwrites the clipboard with the screen’s contents. I’ve used this since the beginning of time to prevent my screen from locking – or IM services showing that I’m “away” for managers that insist on using IM status as an indicator of whether or not you’re working.
I use a script (called Keep-Alive.ps1):
param(
[parameter(Mandatory=$true)][string] $Until,
[parameter(Mandatory=$false)][switch] $Logoff = $false
)
$Shell = New-Object -ComObject Wscript.Shell
Start-Sleep -Seconds 1
Do {
$Shell.SendKeys(‘{PRTSC}’)
If ((Get-Date) -gt (Get-Date $Until)) {
If ($Logoff -eq $true) {
logoff.exe
}
Else {
Break
}
}
Else { Start-Sleep -Seconds 60 }
}
While ($true)
I start this from a batch file with a command like one of the following:
powershell.exe -WindowStyle Hidden -File .\Keep-Alive.ps1 -Until 17:30
or
powershell.exe -WindowStyle Hidden -File .\Keep-Alive.ps1 -Until 17:30 -Logoff
As soon as the provided time (-Until) is exceeded, the script loop stops and the computer will lock itself dependent on the policy affecting the screen lock/screensaver. If you provide the -Logoff switch (As per second command), the computer will log off for you.
We have a similar script for preventing the idle time with keystrokes too. if the host system is a windows OS and then starting the published desktop with the script it works flawlessly, but if the host system is a linux it doesn’t work, anybody knows why?
Improved the script with PowerShell code only and cleaned up a bit of the timer loop for readability:
Param (
[Parameter(Mandatory)]
[String]$Until,
[Switch]$Logoff
)
Do {
[void][System.Reflection.Assembly]::LoadWithPartialName(‘System.Windows.Forms’)
[System.Windows.Forms.SendKeys]::SendWait(“{PRTSC}”)
Start-Sleep -Seconds 60
If ((Get-Date) -gt (Get-Date $Until)) {
If ($Logoff) {
logoff.exe
}
Else {
Break
}
}
} While ($true)
Hi, I am getting an error with the [String] $Until,
When I run through Powershell ISE.
I have the bat file setup with Until info in it.
powershell.exe -WindowStyle Hidden -File C:\Users\xxx\Documents\MyScripts_Local\Keep-Alive.ps1 -Until 19:59 -Logoff
But the script itself is expecting a value for “Until,”
******************************************
Param (
[Parameter(Mandatory)]
[String]$Until,
[Switch]$Logoff
)
Do {
[void][System.Reflection.Assembly]::LoadWithPartialName(‘System.Windows.Forms’)
[System.Windows.Forms.SendKeys]::SendWait(“{PRTSC}”)
Start-Sleep -Seconds 60
If ((Get-Date) -gt (Get-Date $Until)) {
If ($Logoff) {
logoff.exe
}
Else {
Break
}
}
} While ($true)
**************************
Output in PS ISE
PS C:\Windows\system32>
C:\Users\xxx\Documents\MyScripts_Local\KeppAliveTK.ps1
cmdlet KeppAliveTK.ps1 at command pipeline position 1
Supply values for the following parameters:
Until:
PS C:\Windows\system32>
Thanks in advance for any suggestions.
Tim
I found the dot being randomly placed in the active window annoying, however a simple change to
$myshell.sendkeys(“{NUMLOCK}{NUMLOCK}”)
does the trick since it toggles it on and off so quickly that the keyboard doesn’t even have time to change so you can happily type away without being interrupted
Just going to leave this here. https://xkcd.com/196/
Thank you very much
This script helped solve my task :)))
Awesome… simply awesome.
c:\Prevent-Screensaver.ps1 120 means it willl press . for 2 hours right.
Thanks
So it seems like an easy solution to the buffer issue is to have the code simulate the press of the shift key every 60 seconds for a set amount of minutes such as “Anonymous” suggested. How would the code change to emulate a shift key press?
Just tested in Windows 10 Pro – build 19042.985 and screen is still locked.👎
This is really helpful, Thank you Dmitry!