如何远程查询终端服务活动?

问题描述:

我想查询我们的服务器以查看断开连接/空闲会话。我知道我可以使用'query.exe',但我更愿意从代码中使用更容易的东西。如何远程查询终端服务活动?

WMI将是我的首选。

谢谢。

如果您使用的是.NET语言,则可以尝试Cassia。在C#中,代码将为:

using System; 
using Cassia; 

namespace CassiaSample 
{ 
    public static class Program 
    { 
     public static void Main(string[] args) 
     { 
      ITerminalServicesManager manager = new TerminalServicesManager(); 
      using (ITerminalServer server = manager.GetRemoteServer("server-name")) 
      { 
       server.Open(); 
       foreach (ITerminalServicesSession session in server.GetSessions()) 
       { 
        if ((session.ConnectionState == ConnectionState.Disconnected) 
         || 
         (session.ConnectionState == ConnectionState.Active) 
         && (session.IdleTime > TimeSpan.FromMinutes(1))) 
        { 
         Console.WriteLine("Session {0} (User {1})", session.SessionId, session.UserName); 
        } 
       } 
      } 
     } 
    } 
} 

编辑:更新了示例代码Cassia 2.0。

查找东西/生成WMI代码和查询,获取WMI Code Creator。它将生成测试存根(C#,VB.NET,VBScript)并让您测试查询以确保它们返回所需的信息。

终端服务的东西在Win32_Terminal *和Win32_TS *类(有几个,不知道哪一个是你需要的。)。

我也使用这个助手类(需要一点重构,多年没有碰过它)来获取管理对象和执行方法。

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Management; 

namespace MyWMI 
{ 
    public class WmiHelper 
    { 
     public static ManagementObjectCollection GetManagementObjectCollection(string ServerName, string WMIQuery) 
     { 
      //determine where the WMI root is that we will connect to. 
      string strNameSpace = "\\\\"; 

      ConnectionOptions connectionOptions = new ConnectionOptions(); 
      TimeSpan tsTimeout = new TimeSpan(0,0,5); 
      connectionOptions.Timeout = tsTimeout; 

      //if its not a local machine connection 
      if (ServerName.Trim().ToUpper() != Globals.HostName) 
      { 
       strNameSpace += ServerName; 
       connectionOptions.Username = Globals.WMIUserDomain + "\\" + Globals.WMIUserName; 
       connectionOptions.Password = Globals.WMIUserPass; 
      } 
      else 
      { //we are connecting to the local machine 
       strNameSpace += "."; 
      } 

      strNameSpace += "\\root\\cimv2"; 

      //create the scope and search 
      ManagementScope managementScope = new ManagementScope(strNameSpace, connectionOptions); 
      ObjectQuery objectQuery = new ObjectQuery(WMIQuery); 
      ManagementObjectSearcher searcher = new ManagementObjectSearcher(managementScope, objectQuery); 
      ManagementObjectCollection returnCollection; 
      try 
      { 
       returnCollection = searcher.Get(); 
      } 
      catch (ManagementException ex) 
      { 
       throw new SystemException("There was an error executing WMI Query. Source: " + ex.Source.ToString() + " Message: " + ex.Message); 
      } 

      //return the collection 
      return returnCollection; 

     } //eng GetManagementObjectCollection 

     public static bool InvokeWMIMethod(string ServerName, string WMIQueryToIsolateTheObject, string MethodName, object[] MethodParams) 
     { 

      //determine where the WMI root is that we will connect to. 
      string strNameSpace = "\\\\"; 

      ConnectionOptions connectionOptions = new ConnectionOptions(); 
      TimeSpan tsTimeout = new TimeSpan(0, 0, 5); 
      connectionOptions.Timeout = tsTimeout; 

      if (ServerName.Trim().ToUpper() != Globals.HostName) 
      { 
       strNameSpace += ServerName; 
       connectionOptions.Username = Globals.WMIUserDomain + "\\" + Globals.WMIUserName; 
       connectionOptions.Password = Globals.WMIUserPass; 
      } 
      else 
      { //we are connecting to the local machine 
       strNameSpace += "."; 
      } 

      strNameSpace += "\\root\\cimv2"; 

      ManagementScope managementScope = new ManagementScope(strNameSpace, connectionOptions); 
      ObjectQuery objectQuery = new ObjectQuery(WMIQueryToIsolateTheObject); 
      ManagementObjectSearcher searcher = new ManagementObjectSearcher(managementScope, objectQuery); 
      ManagementObjectCollection returnCollection = searcher.Get(); 

      if (returnCollection.Count != 1) 
      { 
       return false; 
      } 


      foreach (ManagementObject managementobject in returnCollection) 
      { 
       try 
       { 
        managementobject.InvokeMethod(MethodName, MethodParams); 
       } 
       catch 
       { 
        return false; 
       } 

      } //end foreach 
      return true; 
     } //end public static bool InvokeWMIMethod(string ServerName, string WMIQueryToGetTheObject, string MethodName, object[] MethodParams) 
    } 
} 

@First评论: 伊克......显然,这是首先想到的更为复杂。检查这篇文章(http://www.codeproject.com/KB/system/logonsessions.aspx),在标题为“”的内容中,内置WMI功能如何?“。如果使用XP,需要进行一些特殊处理,因为它具有不同的WMI提供程序类(将WMI代码创建程序更改为指向远程计算机 - 例如Win2K3服务器),无论哪种情况,都需要“加入”所有数据的会话类。

+0

哇,你提供了很多很棒的帮助和一些精彩的代码,但是我找不到我需要的课程。我只想看看三种可用的TS连接中哪一种正在使用,以及标准服务器的用户和他们的状态。 – 2009-02-09 13:18:36

+0

我在帖子中回复(评论不够大!) – StingyJack 2009-02-09 13:54:01