Windows TS: Terminate tasks of users with client name XYZ

869 Views Asked by At

I want to schedule a task on Windows Terminal Server 2008 and above which runs every 10 Minutes and terminates some processes like "outlook.exe", however this only should be done for users which connect from another TerminalServer (so they all have the same Client Name - the user shell use Outlook on their own machines - Outlook has to be installed because of users who connect from homeoffice).

The taskmanager shows username, processes and client name.

this little code works fine to list all logged on users

strComputer = "." Set objWMI = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\" _ & strComputer & "\root\cimv2")

Set colSessions = objWMI.ExecQuery _ ("Select * from Win32_LogonSession Where LogonType = 10")

If colSessions.Count = 0 Then Echo "No interactive users found" Else echo "RDP Sessions:" For Each objSession in colSessions Set colList = objWMI.ExecQuery("Associators of " _ & "{Win32_LogonSession.LogonId=" & objSession.LogonId & "} " _ & "Where AssocClass=Win32_LoggedOnUser Role=Dependent" ) For Each objItem in colList Echo "Username: " & objItem.Name & " FullName: " & objItem.FullName Next Next End If

A user could get his own Client Name shown like here

Set objShell = CreateObject( "WScript.Shell" ) ClientComp = objShell.ExpandEnvironmentStrings("%clientname%")

But I do not want every user to have an own vbs open permanently. A task should be scheduled with administrator previleges. There seems to be no way to realize this using vbs and WMI, has someone of you a hint please?

3

There are 3 best solutions below

3
On

Is there no way to realize? Perhaps with powershell or something else?

2
On

Instead of killing the task the more elegant solution would of course be preventing the start. This can be done via the DisallowRun key.

You would create a DWORD DisallowRun with value 1 under

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\

and a Subkey

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\DisallowRun\

After a reboot you can now create a REG_SZ under the new subkey with a good description and the value "outlook.exe".

Now the trick is of course to set this based on the clientname info. If you disconnect your sessions after some time of inactivity this is probably trivial. You just need a script put in the users run key or startup folder that sets or deletes this reg key.

If it is possible that the user opens his session locally, then drives home and continues the same session from there you would need a scheduled task again. Instead of after a certain time the best thing would be triggering it on an event. I think the unlock event (might need additional auditing enabled according to this so thread) should work. It would trigger a script that checks the clientname, changes the reg key accordingly and closes outlook if it was running and should not.

0
On

If you need to do this with an admin I would try the following:

The environment variables are all stored in the registry. We use that and iterate through the HKEY_USERS hive where we find all currently logged on users (plus service account plus users that are used with the "run as" command) We identify the services accounts (SID starting with something other than S-1-5-21) and for all the others we check if the key HKEY_USERS\\Volatile Environment has subkeys. Each of them may contain a CLIENTNAME. If you got that you can react on those keys mathcing them with the machinename etc. I know from expirience that the subkey can be 1, 2 or both however I can not think of a situation where two different CLIENTNAMEs are allowed but I might be wrong. A basic implementation of this principle would be the following script:

Const HKEY_USERS = &H80000003

strComputer = "."
Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv") 

' Grab a list of All User SIDs
objRegistry.EnumKey HKEY_USERS, "", arrSubKeys

' Loop Through all User SIDs skip the ones that are service users and their classes hives
For Each strSubKey In arrSubKeys
    If Left(strSubKey, 8) = "S-1-5-21" And Not Right(strSubKey, 8) = "_Classes" Then
        ' The volatile environment key can have subkeys
        ret = objRegistry.EnumKey(HKEY_USERS, strSubKey & "\Volatile Environment", arrVolatileEnvironmentSubKeys)
        If ret = 0 Then
            For Each strVolatileEnvironmentSubKey In arrVolatileEnvironmentSubKeys
                objRegistry.GetStringValue HKEY_USERS, strSubKey & "\Volatile Environment", "USERNAME", strUsername
                retClientname = objRegistry.GetStringValue(HKEY_USERS, strSubKey & "\Volatile Environment\" & strVolatileEnvironmentSubKey, "CLIENTNAME", strClientname)
                If retClientname = 0 And strClientname <> "" Then
                    WScript.Echo strUsername & " is logged on remotely from " & strClientname
                Else
                    WScript.Echo strUsername & " is not logged on remotely " & strClientname
                End If              
            Next    
        End If
    End If
Next

Instead of my prints you could put any sophisticated logic that fits your needs