Wake up monitor with ssh

0

After giving up for months i'd like to revisit the idea that seems so incredibly simple. I want to have a script that wakes up my monitors after they were send to sleep. I tried almost any approach i can think of, please someone save me from adopting a dog that fetches a bone shaped bluetooth mouse wiggling it in the process (yes, i'm that desperate)

What i did so far:

1) Installing OpenSSH on the remote Win10 Machine (works)

2) Getting the interactive Windows session to have authority over the actual session:

FOR /F "usebackq tokens=4" %s IN (tasklist /nh /fo table /fi "imagename eq explorer.exe") DO ...

3a) Starting one of the many keep windows awake programs. Those don't work because they are never launched by psexec or powershell. Or at least if they run they fail to display and do nothing. That's for any process i try to start.

3b) Use SendMessage like i do for the sending it to sleep:

psexec -accepteula -nobanner -d -i %%s -w "%windir%" powershell (Add-Type '[DllImport(\"user32.dll\")]^public static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);' -Name a -Pas)::SendMessage(-1,0x0112,0xF170,-1) Passing 2 as the last parameter works perfect to turn the monitor off. Passing anything else (e.g. -1 for ON) does nothing.

3c) Now desperate i try to do a mouse wiggle/keypress simulation etc.:

FOR /F "usebackq tokens=4" %%s IN (tasklist /nh /fo table /fi "imagename eq explorer.exe") DO psexec -accepteula -nobanner -d -i %%s -w "%windir%" powershell (Add-Type '[DllImport(\"user32.dll\")]^public static extern void mouse_event(uint dwFlags, int dx, int dy, uint dwData, int dwExtraInfo);' -Name user32 -PassThru)::mouse_event(1,40,0,0,0) Works locally executed with elevated rights. Does pop up powershell briefly when used with SSH. Does not do any mouse wiggling.

3d) using good old nircmd.exe monitor off or similar dedicated turn monitor on utilities. Same result as 3a)

Many of the linked threads have supposed solutions, but not of them works for me. The only difference i can glance from executing the script locally vs via ssh is that there is a output of something like

powershell started on with process ID xxxxx

Other than that i have no way of telling what is going on. I put an echo 0 at the end of the scripts to check if it was executed or not. It always gives me the 0. Anyone got an idea what i am missing? Especially 3b) is weird to me since it works for sending the monitor to sleep.

narfelchen

Posted 2019-06-24T09:37:03.717

Reputation: 23

Answers

1

The issue is that waking the monitor and setting the computer to an active state are two different things. Sending -1 to wake the monitor does wake the display. Unfortunately, it's insufficient to wake the computer, too. For this you can use SetThreadExecutionState. Here's a working batch example:

@ECHO OFF

:: gather session handle
FOR /F "usebackq tokens=4" %%s IN (`tasklist /nh /fo table /fi "imagename eq explorer.exe"`) DO SET hsession=%%s

:: wake display
psexec -accepteula -nobanner -d -i %hsession% -w "%windir%" powershell -NoProfile -NoLogo -Command "(Add-Type '[DllImport(\"user32.dll\")]public static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);' -Name a -Pas)::SendMessage(-1,0x0112,0xF170,-1)"
CALL :wait 2

:: reactivate session
psexec -accepteula -nobanner -d -i %hsession% -w "%windir%" powershell -NoProfile -NoLogo -Command "$x=Add-Type '[DllImport(\"kernel32.dll\")]public static extern void SetThreadExecutionState(uint esFlags);' -name System -namespace Win32 -passThru;$x::SetThreadExecutionState([uint32]\"0x03\");Sleep 5;$x::SetThreadExecutionState([uint32]\"0x40\");"
CALL :wait 2
GOTO:EOF

:wait
SET dowait=%~1
IF "%dowait%"=="" SET dowait=10
ping -n %dowait% 127.0.0.1 >NUL
GOTO:EOF

It is possible in some environments use only the SetThreadExecutionState commands, but it isn't 100% reliable in my testing. This also will not wake devices that don't support it.

shawn

Posted 2019-06-24T09:37:03.717

Reputation: 612

Thank you very much. This does exactly what i was looking for. Just for clarification, when you say "wake the computer" you are not referring to a power state in this case, right? What magic does the parameter 0x03 do? I couldn't find it in the SetThreadExecutionState docs. – narfelchen – 2019-11-11T09:38:16.410

1@narfelchen when displays are turned off the computer is automatically set to idle state. The setthreadexecutionstate call basically tells the computer it is no longer idle. This effectively wakes it. – shawn – 2019-11-11T16:07:43.597

0

You might be really overthinking this. Do you just want to keep the monitors awake? Or do you specifically want them to turn on only after they have turned off? I have used a program called Wiggle Mouse in the past. It simply moves the mouse 1 pixel left and right after a duration you specify. You don't notice the movement when you are actually using the mouse, but it will keep the screens active (and has the added benefit of showing you as active in most instant messaging applications like Lync or Slack)

Randomhero

Posted 2019-06-24T09:37:03.717

Reputation: 804

I want what your program does. But initiated via ssh from a remote machine. It's a monitor showing stats that i only want to read from time to time. But not automated in fixed intervalls. The problem appears dead easy but the aforementioned authority over the physical logged in session is needed to wiggle a mouse via script. If i try to temporaily run/close such wiggle programs they just fail :( – narfelchen – 2019-06-25T11:55:01.870

Ah I see. thanks for clarifying that for me. – Randomhero – 2019-06-26T10:01:19.210