Windows TS:终止客户端名称为 XYZ 的用户的任务



>我想在 Windows Terminal Server 2008 及更高版本上安排一个任务,该任务每 10 分钟运行一次并终止一些进程,如"outlook.exe",但是这只应该为从另一个终端服务器连接的用户完成(因此他们都具有相同的客户端名称 - 用户外壳在他们自己的机器上使用 Outlook - 由于用户从家庭办公室连接,必须安装 Outlook)。

任务管理器显示用户名、进程和客户端名称。

这个小代码可以很好地列出所有登录的用户

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

Set colSessions = objWMI.ExecQuery _ ("从Win32_LogonSession中选择 *,其中 LogonType = 10")

如果 colSessions.Count = 0,则回显"未找到交互式用户" 否则回显"RDP Sessions:"对于 colSession 中的每个对象会话 Set colList = objWMI.ExecQuery("Associators of " _ & "{Win32_LogonSession.LogonId=" & objSession.LogonId & "} " _ &"Where AssocClass=Win32_LoggedOnUser Role=Dependent" ) 对于列列表中的每个对象项 Echo "Username: " & objItem.Name & " FullName: " & objItem.FullName 下一页 下一页 尾页 如果

用户可以像下面这样显示自己的客户端名称

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

但我不希望每个用户都永久打开自己的 vbs。应使用管理员先前的任务来计划任务。似乎没有办法使用 vbs 和 WMI 实现这一点,请问你们中的某个人有提示吗?

没有办法实现吗?也许使用电源外壳或其他东西?

如果您需要与管理员一起执行此操作,我会尝试以下方法:

环境变量都存储在注册表中。我们使用它并循环访问HKEY_USERS配置单元,在其中查找所有当前登录的用户(加上服务帐户以及与"运行方式"命令一起使用的用户)我们标识服务帐户(SID 以 S-1-5-21 以外的内容开头),对于所有其他帐户,我们检查键HKEY_USERS\\易失性环境是否具有子项。它们中的每一个都可能包含一个客户端名称。如果你得到了,你可以对这些键做出反应,用机器名称等对它们进行数学运算。我知道子项可以是 1、2 或两者兼而有之,但是我想不出允许两个不同的 CLIENTNAME 的情况,但我可能是错的。此原则的基本实现是以下脚本:

Const HKEY_USERS = &H80000003
strComputer = "."
Set objRegistry = GetObject("winmgmts:\" & strComputer & "rootdefault: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

代替我的打印,您可以放置任何适合您需求的复杂逻辑

与其杀死任务,更优雅的解决方案当然是阻止启动。这可以通过DisallowRun键完成。

您将创建一个 DWORD DisallowRun,其值为 1 下

HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionPoliciesExplorer

和一个子项

HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionPoliciesExplorerDisallowRun

重新启动后,您现在可以在新子项下创建一个具有良好描述和值"outlook.exe"的REG_SZ。

现在的诀窍当然是根据客户端名称信息进行设置。如果您在一段时间不活动后断开会话,这可能是微不足道的。您只需要在用户运行密钥或启动文件夹中放置一个脚本来设置或删除此 reg 密钥。

如果用户可能在本地打开他的会话,然后开车回家并从那里继续相同的会话,您将需要再次计划任务。而不是在一段时间后,最好的办法是在事件中触发它。我认为解锁事件(可能需要根据此线程启用其他审核)应该可以工作。它将触发一个脚本,该脚本检查客户端名称,相应地更改 reg 键并关闭 outlook(如果它正在运行并且不应该运行)。

最新更新