ViciousXUSMC Posted March 31, 2020 Posted March 31, 2020 So due to the pandemic we had to send about 2000 people home to work, some of these people are using RDP to get to the office computer that has licensed software or access that they cant use in our VDI environment. An issue we have is that many of these computers will go to sleep when left unattended, and we do not want to do a mass change in power policy, so I wanted to just create a one off script for users that they can run on their machine to keep it awake. I had had a "keep alive" script that I wrote for myself that works perfectly when run locally, but it also keeps the workstation from locking and I can't have that for security reasons. So I added to this and made sure that it would lock the work station. The "keep alive" still works when used locally the workstation locks, and never goes to sleep. However soon as somebody RDP's to the workstation it seems like it stops functioning. I thought maybe this was because my original script used a mouse movement to keep the computer awake and with RDP the mouse may not exist when you are not active in the session, so I added some key sends as well. Yet it seems like it still does not work. I did some creative stuff here to determine if the session is RDP or not as to determine if the workstation should lock, and also I had to get creative about how to send F15 because that was a safe key to send. Here is my current version of my script where I have F15, Mouse and just a left control all happening to ensure that something was happening to keep the computer alive. What is strange is the script is running, like if the computer goes to sleep or I log into it locally and kick myself out of the RDP session the script is still going, it just seems that it does not work when accessing via RDP, but I can run a script in a RDP session and it works fine the mouse moves, keys send. I suppose this is some kind of limitation on how Windows intercepts these and so they do not work the same if its not a local session. expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Icon=icon_4Mo_icon.ico #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #Include <WinAPI.au3> #Include <WindowsConstants.au3> #include <WinAPISys.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #Region ### START Koda GUI section ### Form= $HCBOCC = GUICreate("HCBOCC", 270, 57, 192, 124) $Label1 = GUICtrlCreateLabel("Current RDP Status", 0, 0, 264, 24) GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif") $Label2 = GUICtrlCreateLabel("Lock Status", 2, 22, 264, 24) GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif") GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### GLOBAL $oOBJ = ObjCreate("WScript.Shell") IsRDP() ;Check Current RDP Status MsgBox(0, "HCBOCC Automation", "Keeping the RDP Status Window Open or Minimized will keep this computer from going to sleep." & @CRLF & @CRLF & "Closing the Status Window will exit the script and resume normal operation.", 10) AdlibRegister("_LockMe", 1000*60*5) ;Lock after 5 minutes when RDP is not Active AdlibRegister("IsRDP", 1000*10) ;Check if RDP Session is running and set GUI Status AdlibRegister("_KeepAlive", 1000*55) ;Keeps the computer from sleeping AdlibRegister("_Caffeine", 1000*59) ;Keeps the computer from sleeping While 1 Sleep(10) $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd #Region Functions Func _KeepAlive() $aPos = MouseGetPos() MouseMove($aPos[0] + 1, $aPos[1], 1) MouseMove($aPos[0], $aPos[1], 1) Send("{ASC 0x7E}") Send("{LCTRL}") EndFunc Func _Caffeine() $oOBJ.SendKeys('+{F15}') EndFunc Func _Lockme() If NOT IsRDP() Then ShellExecute("rundll32.exe", 'user32.dll,LockWorkStation') EndFunc Func IsRDP() ; Returns True or False $iTest = _WinAPI_GetSystemMetrics ($SM_REMOTESESSION) If NOT $iTest Then GUICtrlSetData($Label1, "RDP Session Not Connected") GUICtrlSetData($Label2, "Desktop Will Lock Automatically") Else GUICtrlSetData($Label1, "RDP Session Connected") GUICtrlSetData($Label2, "Desktop Will Not Lock") EndIf Return $iTest EndFunc #EndRegion Functions Basically just looking for any information on what might be happening, also figured I would share part of the code for sending F15 and Checking RDP session as those both took some research to figure out as we had some older methods posted that no longer seem to work and our standard Send() function only goes to F12 and I am not sure sending the ASC code works properly.
TheXman Posted March 31, 2020 Posted March 31, 2020 Have you checked to make sure that your users aren't bumping up against one of the RDP session limits, especially the "Active Session Limit", if they are configured? https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc754272(v=ws.11)?redirectedfrom=MSDN https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc726057(v=ws.10) CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman
ViciousXUSMC Posted March 31, 2020 Author Posted March 31, 2020 (edited) No, its not a RDP session limit. I have tested on my own device. Just RDP and let it sit overnight to come in in the morning to find my computer asleep. Wake it up, log in and see the script running! I can only assume that once there is no RDP session in focus that the session does not "receive" mouse or keyboard input from the script, but while you are in the RDP session you will see it working like normal. If you run it locally with no session, it works just fine. Edited March 31, 2020 by ViciousXUSMC
Gianni Posted March 31, 2020 Posted March 31, 2020 (edited) so, I understand that is your "home" computer that goes to sleep and not the "office" computer that instead keeps running (right?) you could try to run a copy of your "keep alive" script on the remote client (the office client) and also another copy on the "home" PC where you are running the RDP software. Also, when you connect from home to the office computer via RDP, there should not be the need to lock the "office" computer because it results and appears already locked to a person in front of the monitor at the office PC, that is, a person sitting in front of the office PC can't see what you are doing on that computer from home. Edited March 31, 2020 by Chimp Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....
ViciousXUSMC Posted April 1, 2020 Author Posted April 1, 2020 So how it works is that there is a computer in the office. It is under power policy to fall asleep. The user can from the office before they go home to work remote or the weekend run this script on the machine in the office, It should then make sure that workstation gets locked for security reasons, but also keep it from falling asleep so they can remote into it later from home. You can also remote into the machine if it is still awake and run the script remotely, either way should work. It will never be run on the machine that is initiating the RDP session as the user will be able to operate that machine locally. If you run this script locally it works perfectly, but once you establish a RDP session to the machine running the script it seems like it fails to work properly even though its still running and while you are active in a RDP session you can see that it is working.
Earthshine Posted April 1, 2020 Posted April 1, 2020 can you just make it a simple service to move the mouse around? that way it doesn't need be logged in to work. My resources are limited. You must ask the right questions
JohnTWI Posted June 9, 2020 Posted June 9, 2020 Did anyone every find a solution to the RDP disconnect issue. I am having a similar issue when I disconnect from a script running on a windows 16 server via RDP, I get unexpected results after the disconnect. I there anyway to keep the session alive after an RDP disconnect? Thank you in advance.
ViciousXUSMC Posted June 10, 2020 Author Posted June 10, 2020 This is my full code dump that I had working. I tried to use a AutoIT version of Caffine since mouse move and key sends didn't work for me. The real fix I think was disabling sleep mode. expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Icon=icon_4Mo_icon.ico #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #Include <WinAPI.au3> #include <MsgBoxConstants.au3> #include <WinAPIProc.au3> #Include <WindowsConstants.au3> #include <WinAPISys.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> Stopwatch(3) ; reset to 0 and starts #Region ### START Koda GUI section ### Form= $HCBOCC = GUICreate("HCBOCC", 270, 77, 192, 124) $Label1 = GUICtrlCreateLabel("Current RDP Status", 2, 0, 264, 24) GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif") $Label2 = GUICtrlCreateLabel("Lock Status", 2, 24, 264, 24) GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif") $LapsedTime = GUICtrlCreateLabel("In 10 Minutes 00:00:00.0", 4, 47, 300, 25) GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif") GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### GLOBAL $oOBJ = ObjCreate("WScript.Shell") Local $aRet = DllCall("kernel32.dll", "long", "SetThreadExecutionState", "long", 0x80000003) ;0x80000003 to disable windows sleep mode IsRDP() ;Check Current RDP Status MsgBox(0, "HCBOCC Automation", "Keeping the RDP Status Window Open or Minimized will keep this computer from going to sleep." & @CRLF & @CRLF & "Closing the Status Window will exit the script and resume normal operation.", 10) AdlibRegister("_LockMe", 1000*60*10) ;Lock after 10 minutes when RDP is not Active AdlibRegister("IsRDP", 1000*10) ;Check if RDP Session is running and set GUI Status AdlibRegister("_KeepAlive", 1000*55) ;Keeps the computer from sleeping AdlibRegister("_Caffeine", 1000*59) ;Keeps the computer from sleeping While 1 ;Sleep(2) $aMouseCord1 = MouseGetPos() $x = Int(Stopwatch() / 100) $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Local $aRet = DllCall('kernel32.dll', 'long', 'SetThreadExecutionState', 'long', 0x80000000) ;Remove the always on so it will go to sleep Exit EndSwitch If $x <> Int(Stopwatch() / 100) Then $totsec = Int(Stopwatch() / 1000) ; ms to sec $hr = Int($totsec / 3600) ; hours $mn = Int(($totsec - ($hr * 3600)) / 60) ; minutes $sc = Int(($totsec - ($hr * 3600) - ($mn * 60))) ; seconds $tn = Int((Int(Stopwatch() / 100) - ($hr * 36000) - ($mn * 600) - ($sc * 10))) ; tenths of a second GUICtrlSetData($LapsedTime, "In 10 Minutes " & StringFormat("%02s", $hr) & ":" & StringFormat("%02s", $mn) & ":" & StringFormat("%02s", $sc) & "." & StringFormat("%01s", $tn)) EndIf $aMouseCord2 = MouseGetPos() If $aMouseCord1[0] <> $aMouseCord2[0] Then Renew() WEnd #Region Functions Func _KeepAlive() $aPos = MouseGetPos() MouseMove($aPos[0] + 1, $aPos[1], 1) MouseMove($aPos[0], $aPos[1], 1) ;Send("{ASC 0x7E}") ;Send("{LCTRL}") EndFunc Func _Caffeine() $oOBJ.SendKeys('+{F15}') EndFunc Func _Lockme() If NOT IsRDP() Then ShellExecute("rundll32.exe", 'user32.dll,LockWorkStation') EndFunc Func IsRDP() ; Returns True or False $iTest = _WinAPI_GetSystemMetrics ($SM_REMOTESESSION) If NOT $iTest Then GUICtrlSetData($Label1, "RDP Session Not Connected") GUICtrlSetData($Label2, "Desktop Will Lock Automatically @ 10 Minutes") GUICtrlSetState($LapsedTime, $GUI_SHOW) Else GUICtrlSetData($Label1, "RDP Session Connected") GUICtrlSetData($Label2, "Desktop Will Not Lock") GUICtrlSetState($LapsedTime, $GUI_HIDE) EndIf Return $iTest EndFunc Func _Example() ; disable ScreenSaver and other windows sleep features _WinAPI_SetThreadExecutionState(BitOR($ES_DISPLAY_REQUIRED, $ES_CONTINUOUS, $ES_SYSTEM_REQUIRED, $ES_AWAYMODE_REQUIRED)) MsgBox($MB_OK, 'Testing', 'Close this tester window when you be sure that your ScreeSaver not runing.') ; back to normal windows behavior _WinAPI_SetThreadExecutionState($ES_CONTINUOUS) EndFunc ;==>_Example Func Renew() Stopwatch(3) AdlibRegister("_LockMe", 1000*60*10) EndFunc ;End Renew Func AutoLogoff() Run(@ComSpec & " /c shutdown -L") EndFunc ;End AutoLogoff Func Stopwatch($ToggleTo = 4) Static Local $Paused = True Static Local $Stopwatch = 0 Static Local $TotalTime = 0 Switch $ToggleTo Case 0 ; pause counter If $Paused Then SetExtended($Paused) ; $Paused status Return $TotalTime ; already paused, just return current $TotalTime Else $TotalTime += TimerDiff($Stopwatch) $Paused = True SetExtended($Paused) Return $TotalTime EndIf Case 1 ; unpause counter If $Paused Then $Stopwatch = TimerInit() $Paused = False SetExtended($Paused) Return $TotalTime Else SetExtended($Paused) Return $TotalTime + TimerDiff($Stopwatch) EndIf Case 2 ; reset to 0 and pause $Paused = True $TotalTime = 0 SetExtended($Paused) Return $TotalTime Case 3 ; reset to 0 and restart $Paused = False $TotalTime = 0 $Stopwatch = TimerInit() SetExtended($Paused) Return $TotalTime Case 4 ; return status SetExtended($Paused) If $Paused Then Return $TotalTime Else Return $TotalTime + TimerDiff($Stopwatch) EndIf EndSwitch EndFunc ;==>Stopwatch #EndRegion Functions
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now