rudi Posted July 27, 2009 Share Posted July 27, 2009 Hi.For Terminal Server Session Admin Tasks I need to check, if certain EXEs are running for THIS session.Currently I use a ugly CMD script to catch processes started from *THIS* session.REM search for the program "DVWIN.EXE", started from "THIS SESSION" REM REM for /f "usebackq ... -> use new semantic, allowing commands in the brackets REM ... tokens=3" %%a in -> return 3rd column of each matching result line only. (Default separator = WhiteSpace) REM (`query session^|find ">"`) REM query session -> this returns all currently existing TS sesstions. The line of "This session" is preceeded by a ">" REM ^| -> pipe the results to the next command, "^" is required to "escape |" REM find ">" -> find the line for "This session" (">") REM REM the next search is basically the same, just looking for DVWIN.EXE running in "THIS SESSION ID". REM %%r = explicit variable, %%s & %%t = implicit, by the "tokens" statement. REM to run not from CMD file but directly a the command line, replace the "%%" by "%". REM the following is ONE line. for /f "usebackq tokens=3" %%a in (`query session^|find ">"`) do for /f "usebackq tokens=3,4,5" %%r in (`qprocess /ID:%%a ^| find /i "dvwin"`) do echo Session: %%r - PID: %%s - Process Name: %%t REM Then I can processclose() the DVWIN.EXE started from this session, %%sIsn't there a possibility to do such a usual thing with pure Autoit? If so, then I miss it 100% >_< Any suggestions appreciated, Rudi. Earth is flat, pigs can fly, and Nuclear Power is SAFE! Link to comment Share on other sites More sharing options...
spudw2k Posted July 27, 2009 Share Posted July 27, 2009 You could WMI, just one solution. I'm sure there prob a way to do it via DLL, but that's a bit beyond my expertise. #include <Array.au3> $arrProcesses = _GetProcessIds(@ComputerName) _ArrayDisplay($arrProcesses) Func _GetProcessIds($strHost) If Not Ping($strHost,200) Then SetError(1) $objWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strHost & "\root\CIMV2") If Not IsObj($objWMI) Then SetError(2) $colItems = $objWMI.ExecQuery ("SELECT * FROM Win32_Process") Dim $arrResults[1][3] = [["Processname","ProcessID","SessionID"]] For $objItem In $colItems ReDim $arrResults[UBound($arrResults)+1][3] $arrResults[UBound($arrResults)-1][0] = $objItem.Name $arrResults[UBound($arrResults)-1][1] = $objItem.ProcessId $arrResults[UBound($arrResults)-1][2] = $objItem.SessionId Next Return $arrResults EndFunc Spoiler Things I've Made: Always On Top Tool ◊ AU History ◊ Deck of Cards ◊ HideIt ◊ ICU ◊ Icon Freezer ◊ Ipod Ejector ◊ Junos Configuration Explorer ◊ Link Downloader ◊ MD5 Folder Enumerator ◊ PassGen ◊ Ping Tool ◊ Quick NIC ◊ Read OCR ◊ RemoteIT ◊ SchTasksGui ◊ SpyCam ◊ System Scan Report Tool ◊ System UpTime ◊ Transparency Machine ◊ VMWare ESX BuilderMisc Code Snippets: ADODB Example ◊ CheckHover ◊ Detect SafeMode ◊ DynEnumArray ◊ GetNetStatData ◊ HashArray ◊ IsBetweenDates ◊ Local Admins ◊ Make Choice ◊ Recursive File List ◊ Remove Sizebox Style ◊ Retrieve PNPDeviceID ◊ Retreive SysListView32 Contents ◊ Set IE Homepage ◊ Tickle Expired Password ◊ Transpose ArrayProjects: Drive Space Usage GUI ◊ LEDkIT ◊ Plasma_kIt ◊ Scan Engine Builder ◊ SpeeDBurner ◊ SubnetCalcCool Stuff: AutoItObject UDF ◊ Extract Icon From Proc ◊ GuiCtrlFontRotate ◊ Hex Edit Funcs ◊ Run binary ◊ Service_UDF Link to comment Share on other sites More sharing options...
rudi Posted July 28, 2009 Author Share Posted July 28, 2009 You could WMI, just one solution. I'm sure there prob a way to do it via DLL, but that's a bit beyond my expertise. #include <Array.au3> $arrProcesses = _GetProcessIds(@ComputerName) _ArrayDisplay($arrProcesses) Func _GetProcessIds($strHost) If Not Ping($strHost,200) Then SetError(1) $objWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strHost & "\root\CIMV2") If Not IsObj($objWMI) Then SetError(2) $colItems = $objWMI.ExecQuery ("SELECT * FROM Win32_Process") Dim $arrResults[1][3] = [["Processname","ProcessID","SessionID"]] For $objItem In $colItems ReDim $arrResults[UBound($arrResults)+1][3] $arrResults[UBound($arrResults)-1][0] = $objItem.Name $arrResults[UBound($arrResults)-1][1] = $objItem.ProcessId $arrResults[UBound($arrResults)-1][2] = $objItem.SessionId Next Return $arrResults EndFunc Great, thanks! With Scriptomatic V2 I just went through all the TerminalServ* and TS*, but couldn't figure out, how to retrieve the session ID of THIS session. Any idea, how to pull that info as well? I'm thinking of using fileinstall() to a random temp EXE file name, an autoit script that will just run a few seconds to pull from your array the seesion ID first. Then I can lookup what programs are running with the same session ID. Regards, Rudi. Earth is flat, pigs can fly, and Nuclear Power is SAFE! Link to comment Share on other sites More sharing options...
99ojo Posted July 28, 2009 Share Posted July 28, 2009 Great, thanks!With Scriptomatic V2 I just went through all the TerminalServ* and TS*, but couldn't figure out, how to retrieve the session ID of THIS session. Any idea, how to pull that info as well?I'm thinking of using fileinstall() to a random temp EXE file name, an autoit script that will just run a few seconds to pull from your array the seesion ID first. Then I can lookup what programs are running with the same session ID.Regards, Rudi.Hi Rudi,search in Forum for WTSQuerySessionInformation. Maybe this helps you.;-))Stefan Link to comment Share on other sites More sharing options...
rudi Posted July 29, 2009 Author Share Posted July 29, 2009 Hi Stefan.search in Forum for WTSQuerySessionInformation. Maybe this helps you.I did readup all the hits for WTSQuerySessionInformation, as well as all the WTS* entries nearby this MSDN topic.It was quite interesting, BUT still I'ven't got a clue how to use these DLL calls to1.) retrieve the session ID of THIS Session2.) then to pull a list of all processes started from that Session ID.To me that's like nice descriptions how to smoothly fly a complicated looping -- but up to now I can't fly at all :/In the autoit help file there are several "DLL*" entries in the "Process Management" section: Well, I don't know almost anything about DLL calls, so all I can do is to test the sample snippets provided there, but honestly, I don't get the whole thing about calling DLLs, that's all too far beyond my current skills. >_<I'll try to move on searching for DLL*() calls in the sample code forum here.Frustrated, Rudi. Earth is flat, pigs can fly, and Nuclear Power is SAFE! Link to comment Share on other sites More sharing options...
rudi Posted July 29, 2009 Author Share Posted July 29, 2009 Hi. My (ugly) workaround to avoid the DLL*() stuff I'm unable to deal with is this: #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_outfile=z:\TSThisSessionsProcesses.exe #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <Constants.au3> Dim $CMD = ' /c @for /f "usebackq tokens=3" %a in (`query session^|find ">"`) do @for /f "usebackq tokens=3,4,5" %r in (`qprocess /ID:%a^|find /i ">"`) do @echo %r\%s\%t' Dim $MyRead $PID = Run(@ComSpec & $CMD, @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) Sleep(2000) ; then the first stdoutread() will already return the results While 1 $MyRead = StdoutRead($PID) If @error Then ExitLoop ; here I do what's needed. Next line just to demonstrate... MsgBox(0, "Session-ID\PID\Process", $MyRead,5) WEnd While 1 $MyRead = StderrRead($PID) If @error Then ExitLoop MsgBox(0, "STDERR read:", $MyRead,5) WEnd MsgBox(0, "Done", "Exiting...",3) From there I use stringsplit to do what's needed. >_< DLLCall() or some WMI stuff would be much more nifty Now Frustrated AND unhappy Rudi. Earth is flat, pigs can fly, and Nuclear Power is SAFE! Link to comment Share on other sites More sharing options...
rudi Posted August 10, 2009 Author Share Posted August 10, 2009 Hi. Bump. Anyone >_<, who knows a much more easy way to retrieve a list of all process IDs started on a Terminal Server from *THIS* session? Any further suggestions mostly appreciated, regards, Rudi. Earth is flat, pigs can fly, and Nuclear Power is SAFE! Link to comment Share on other sites More sharing options...
Solution rudi Posted February 2, 2023 Author Solution Share Posted February 2, 2023 (edited) Just found a quite straight forward solution, so I update this thread, I've opened quite a number of years ago, in case someone else should search for it: Choose a $ProcessName, you would like to see just the PIDs started by "ThisUser". To create some "Differen-User-Processes" start them for a user, you know the password of with: open CMD.EXE box runas /user:yourdomain\someotheruser cmd.exe <blind type the pwd of other user> --> a new CMD box will open, there type whoami ... to see, it's running as a different user expandcollapse popup; #RequireAdmin - to retrieve the user's *OWN* process information RequireAdmin is not required #include <Array.au3> #include <WinAPIProc.au3> $ProcessName = "cmd.exe" $BackSlash="\" ; " to fix forum highlighting $whoami=@LogonDomain & $BackSlash & @UserName Local $aAdjust, $aList = 0 Local $hToken = _WinAPI_OpenProcessToken(BitOR($TOKEN_ADJUST_PRIVILEGES, $TOKEN_QUERY)) ; Retrieve user names for all processes the system If Not (@error Or @extended) Then $aList = ProcessList($ProcessName) If $aList[0][0] = 0 Then MsgBox(0, $ProcessName, "No processes found matching """ & $ProcessName & """.") Else Local $aData For $i = 1 to $aList[0][0] $aData = _WinAPI_GetProcessUser($aList[$i][1]) If IsArray($aData) Then if $whoami = $aData[1] & $BackSlash & $aData[0] then ; this is a process of *THIS* user if ProcessClose($aList[$i][1]) Then $aList[$i][1] = $aList[$i][1] & " - " & $aData[1] & $BackSlash & $aData[0] & " - Process closed successfully." Else $aList[$i][1] = $aList[$i][1] & " - " & $aData[1] & $BackSlash & $aData[0] & " - Process could *NOT* be closed!" EndIf Else if $aData[1]="" Then $aList[$i][1] = $aList[$i][1] & " - " & $aData[1] & $BackSlash & $aData[0] & " - user couldn't be retrieved." Else $aList[$i][1] = $aList[$i][1] & " - " & $aData[1] & $BackSlash & $aData[0] & " - other user." EndIf ConsoleWrite( $ProcessName & @TAB & $aList[$i][1] & @TAB & $aData[1] & $BackSlash & $aData[0] & @TAB & "not this user / user cannot be retrieved." & @CRLF) EndIf Else $aList[$i][1] = $aList[$i][1] & " - This user: " & $whoami & " - process user could *NOT* be retrieved." ConsoleWrite($ProcessName & @TAB & $aList[$i][1] & @TAB & "process user could *NOT* be retrieved" & @CRLF ) EndIf Next $aList[0][0]=UBound($aList)-1 ; Enable SeDebugPrivilege privilege by default ; _WinAPI_AdjustTokenPrivileges($hToken, $aAdjust, 0, $aAdjust) _WinAPI_CloseHandle($hToken) _ArrayDisplay($aList, $ProcessName & ' by user') EndIf EndIf Edited February 2, 2023 by rudi Earth is flat, pigs can fly, and Nuclear Power is SAFE! Link to comment Share on other sites More sharing options...
mistersquirrle Posted February 2, 2023 Share Posted February 2, 2023 (edited) I found a way to do what I think you're looking for with the code from 2009 by @spudw2k (modified a bit for my tastes) give this a shot and see if it works for you (just curious): expandcollapse popup#include <Array.au3> Local $iSession = _GetSessionByPid(@AutoItPID, @ComputerName) If @error Then ConsoleWrite('Error getting Session of pid: ' & @AutoItPID & ' \\ ' & @ComputerName & @CRLF) Exit EndIf ConsoleWrite('Session of this process: ' & $iSession & @CRLF) $arrProcesses = _GetProcessIds(@ComputerName, $iSession) _ArrayDisplay($arrProcesses) Func _GetProcessIds($strHost = @ComputerName, $iSession = -1) Local $oWMI = __WinMgmtsObj($strHost) If @error Then Return False Local $sSessionWhere = '' If $iSession >= 0 Then $sSessionWhere = ' WHERE SessionID = ' & $iSession EndIf $colItems = $oWMI.ExecQuery("SELECT * FROM Win32_Process" & $sSessionWhere) Local $iRows = 0 For $objItem In $colItems $iRows += 1 Next Local $arrResults[$iRows + 1][3] = [["Processname", "ProcessID", "SessionID"]] $iRows = 1 For $objItem In $colItems $arrResults[$iRows][0] = $objItem.Name $arrResults[$iRows][1] = $objItem.ProcessId $arrResults[$iRows][2] = $objItem.SessionId $iRows += 1 Next Return $arrResults EndFunc ;==>_GetProcessIds Func _GetSessionByPid($iPid, $strHost = @ComputerName) Local $oWMI = __WinMgmtsObj($strHost) If @error Then Return SetError(1, 0, False) EndIf If Not ($iPid > 0) Then Return SetError(2, 0, False) EndIf $colItems = $oWMI.ExecQuery("SELECT * FROM Win32_Process WHERE ProcessID = " & $iPid) For $objItem In $colItems If $objItem.SessionId >= 0 Then Return $objItem.SessionId EndIf Next EndFunc ;==>_GetSessionByPid Func __WinMgmtsObj($strHost = @ComputerName) Local Static $sPreviousHost = -1 Local Static $oWMI If Not Ping($strHost, 200) Then Return SetError(1, 0, False) EndIf If $sPreviousHost <> $strHost Then $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strHost & "\root\CIMV2") $sPreviousHost = $strHost EndIf If Not IsObj($oWMI) Then Return SetError(2, 0, False) EndIf Return $oWMI EndFunc ;==>__WinMgmtsObj Edited February 2, 2023 by mistersquirrle Updated code We ought not to misbehave, but we should look as though we could. Link to comment Share on other sites More sharing options...
rudi Posted February 3, 2023 Author Share Posted February 3, 2023 (edited) Your code is *NOT* doing what I need. To see what I mean these steps are sufficient: Start a CMD box as a different user as described in my last posting, verify it's running as a different user run your script, sort by process name run sysinternals PROCEXP.EXE, drag drop the crosshair to that CMD box to get the PID Looking up the result array of your script, you will notice, that that PID of the CMD box running as a different user is listed for "your session" <edit: grammar> Edited February 3, 2023 by rudi Earth is flat, pigs can fly, and Nuclear Power is SAFE! Link to comment Share on other sites More sharing options...
mistersquirrle Posted February 4, 2023 Share Posted February 4, 2023 If the test works for you, then great. However when I follow your testing steps to open a CMD window, it is STILL opened as a process under MY session, not a new session. Normally I only use 1 account, but I do have another set up on this computer. This computer is 'RAVEN', my main user is Raven, and the second user is Poe. When I run "runas /user:poe cmd.exe", it opens just fine, but when I used both Process Explorer and AutoIt to get the PID of the window, it returns a process that is under Raven's session (1), not Poe (because Poe is not logged in, Poe does not have a session). I tested this however by using a PID of the SYSTEM user, which is session 0, and that works fine: I then went ahead and actually signed into the Poe user, switched back to Raven, and now in Task Manager and/or ProcExp I can see that there are actually Pids under session 2, user Poe, and if I take one of those Pids and plug it into the script, or just say show me session 2: But even trying "runas /user:poe cmd.exe" AFTER Poe is signed in, it still creates a cmd.exe window under Raven's session (session 1), verified in Task Manager and ProcExp. The user name of the process does now show Poe in the User name column of Task Manager, but session is NOT Poes. So your test/script is not testing the session, but rather the user (as should be clear from _WinAPI_GetProcessUser, it has nothing to do with sessions). We ought not to misbehave, but we should look as though we could. Link to comment Share on other sites More sharing options...
rudi Posted February 6, 2023 Author Share Posted February 6, 2023 As mentioned above I wanted to distinguish the user account, a process is running with. You are right, for a terminal server, every user will have his/her own session. I'm not sure, if it is possible to start two different sessions using the same user account (e.g. one as console session), I don't think so, because both would need to access and lock files in %userprofile% dir (namely NTUSER.DAT). As replacing signature information is a user based thing for me the "check if there is a outlook.exe running for the currently loggedon user" seems to be the best approach. Earth is flat, pigs can fly, and Nuclear Power is SAFE! Link to comment Share on other sites More sharing options...
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