1

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?

  • Is there a specific reason why the task has to be scheduled with an admin user? For the behavior you described you could just as well run it with User rights then each user just get his own outlook killed. Also if you have gpos you could maybe prevent the whole thing by denying specific users to run the exe to begin with instead of granting them 10 minutes all the time. I would expect many people to just reopen outlook again – Syberdoor Jan 30 '15 at 10:16
  • my intention was that so only one script has to run. Could run with system previleges. Userbased is not possible because some users use both - homeoffice and connecting from the other TS. Homeoffice should be allowed to use outlook and others not. If they open outlook again than the time limit is for example 3 minutes so they notice it is senseless to use outlook on the TS... – whowhywhere Jan 30 '15 at 10:27
  • yeah what I meant is run it with user privileges but still check for the clientname, but you are right multiple scripts would run at the same time then although I do not think it would cost a lot of performance. Unfortunately I found out my idea with the wmi query and the applocker gpo won't work either because win32_environment does not seem to include the clientname because it is volatile. So you would need some kind of logon script maybe – Syberdoor Jan 30 '15 at 10:50

3 Answers3

0

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

  • as I tried to tell you it is very hard to do with an admin user and I would highly advise against it (because the clientname is specific to each user). Also the idea to close is imo not as good as preventing open. If you insist on running this as admin I can try to give you a hint to a possible solution tomorrow. As a side note, you should not post additional questions as an answer but edit your question or use the comments on this site... – Syberdoor Feb 04 '15 at 16:02
  • hi, thanks for your help. preventing to open wpould be my fav too, but how to do, if the same user should be allowed to open these programs if he is logged on from another machine (home-PC) – whowhywhere Feb 05 '15 at 07:27
  • I posted my solution for an admin ran script but I will also post as second answer with a concept that could imo work for reliably preventing depending on how much you can say about the users behaviour – Syberdoor Feb 05 '15 at 08:12
0

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

Syberdoor
  • 2,521
  • 1
  • 11
  • 14
0

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.

Community
  • 1
  • 1
Syberdoor
  • 2,521
  • 1
  • 11
  • 14
  • thanks that sounds interesting. we do not kill sessions by timeout, users can "drive home" and use their session. I will have a try on your suggestions. – whowhywhere Feb 05 '15 at 11:52
  • keep me updated if you got any luck. I have one final idea it's just such a dirty hack that I wouldn't even post it, but if nothing else works you can tell me if you wanna try it – Syberdoor Feb 05 '15 at 12:33