Click here to Skip to main content
15,897,371 members
Articles / Programming Languages / C#

Retrieve a List of Network Computers and the Full Names of Connected Users

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
24 Jul 2012CPOL3 min read 29.1K   1.8K   11   1
When you're in an environment that has multiple virtual machines and you would like to quickly know which machines have extra connection available or if the machine is free.

Image 1

Introduction

When you're in an environment that has multiple virtual machines with each machine having RDP account connection limitation (e.g., only x maximum concurrent terminal service users) or will be too slow for more than one user, and you would like to quickly know which machines have extra connection available or if a machine is free, it is a waste of time to connect to each one.

On average, an RDP connection attempt takes 30 seconds and, on top of that, checking if another user(s) is connected will take around 3 minutes. Using Terminal Services Manager can cut this time down but still you'll have to spend 10 to 15 seconds checking each known machine...but what if you want to scan including the newly added machines that you're not aware of?

What if you want to have a bird's eye-view of the network domain and its current users and also be able to print (print screen for now) this view? What if you need the Full Name of each connected user (disconnected/timed-out users are not displayed) instead of their usually unintelligible login names?

What if you want to know if a user is unreasonably using a lot of machines?

Background

Note that this solution is not limitless as it can only scan virtual machines that are exposed to the current machine's network domain where you will run this tool. I know some guys especially network administrators can have a better explanation about this so let's leave it to them.

Also note that this project took 1.5 hours to create on a staggered basis covering three days (I have a day job and a personal life like everyone else) so for a moment please brush aside the "this project needs refactoring!" thought running in your mind. Consider this as a very quick 1-hour project if done continuously Big Grin

Using the Code

My approach is to briefly give you an explanation of the source code and how it is mainly structured. Feel free to look at the project source code for the rest of the functionalities not mentioned here.

  1. Note the following references:
    C#
    using System.Windows.Forms;
    using ListNetworkComputers;
    using System.Security.Principal;
    using Cassia;
    using System.DirectoryServices;

    We reference the ListNetworkComputers project only (quickest approach) just to get access to the NetworkBrowser class. The ListNetworkComputers project was created by Sacha Barber with the link at the end of this post.

    The Cassia .Net library is "for accessing the native Windows Terminal Services API (now the Remote Desktop Services API)" and is from Google Code with link at the end of this post.

  2. The main functionality is presented below, which is where I integrated all the pre-existing functionalities for my purpose:
    C#
    //create a new NetworkBrowser object, and get the
    //list of network computers it found, and add each
    //entry to the combo box on this form
    try
    {
       NetworkBrowser nb = new NetworkBrowser(); //We reuse Sacha Barber's project
       ArrayList al = nb.getNetworkComputers(); //Will contain all the network computers/VMs
       ITerminalServicesManager manager = new TerminalServicesManager();
       for (int x = 0; x < al.Count; x++)
       {
           ...
           panel1.Controls.Add(lblComputer); //Add the computer on the form
           try
           {
               using (ITerminalServer server = manager.GetRemoteServer(al[x] as string))
               {
                   server.Open();
                   int locationCounter = 0;
                   //Get the connected user(s)
                   foreach (ITerminalServicesSession session in server.GetSessions())
                   {
                       NTAccount account = session.UserAccount;
                       if (account != null)
                       {
                           Label lblUser = new Label();
                           string filter = string.Format("(&(ObjectClass={0})(sAMAccountName={1}))",
                                                    "person", session.UserName);
                                                    //Format string for Active Directory purposes
                           DirectoryEntry adRoot = new DirectoryEntry("LDAP://" + session.DomainName,
                                                    null, null, AuthenticationTypes.Secure);
                           DirectorySearcher searcher = new DirectorySearcher(adRoot);
                           searcher.SearchScope = SearchScope.Subtree;
                           searcher.ReferralChasing = ReferralChasingOption.All;
                           searcher.PropertiesToLoad.AddRange(new string[] { "fullname" });
                                                  //Give me the Full Name of the user
                           searcher.Filter = filter;
    
    
                           SearchResult result = searcher.FindOne();
                           DirectoryEntry directoryEntry = result.GetDirectoryEntry();
    
    
                           //not sure if this check is necessary but let it pass
                           if (directoryEntry != null)
                           {
                               lblUser.Text = directoryEntry.Properties["displayName"][0].ToString(); //Got the Full Name
                           }
                           else
                           {
                               lblUser.Text = account.Value; //Just give me the Account Name
                           }
                           ...
                       }
                   } 
               } 
           }
           ...
       }
    }
    ...

Points of Interest

Please do note that I am in no way attempting plagiarism or claiming something that is not mine. The list below are the exact sources/references of the source codes as applicable...what I only did is to create a (very quick) structure of functionality that will merge all of the useful parts of these codes for my intended purpose. There are tons of improvements (modularity, interactivity, efficiency, late-binding, etc. etc.) to be done here so feel free to improvise. Please refer to the following links to get details on the specific libraries and classes that I used.

Licenses: The third-party components/libraries/codes used in this project may have respective copyrights/licenses of their own. Refer to the third-party sites and observe their copyrights/licenses. Codes that I have created in this project are under CPOL License.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead Datacom Systems (Wellington) Ltd.
New Zealand New Zealand
Ritchie Grijaldo is a Microsoft Certified Professional Developer for Enterprise, Web, and Windows Applications. More than 10 years of experience in migrating, designing, and developing n-tier applications. Designed and developed a WCF service impervious to hacking exploits, is robust, scalable, extensible, architecturally secure, a high-performing and efficient solution for validating and converting PDF documents into the standard PDF/A archiving format. Senior Developer for ASP.Net 3.5 custom workflow application hosted within a SharePoint 2010 site. Delivered solutions using Windows Azure.

Technical Skills:
- C# 5.0/6.0, C#.Net Best Practices, .Net Design Patterns, WCF
- SharePoint Development, XSLT, ASP.Net, SQL Database Design
- JQuery, AJAX, KnockoutJS, HTML5, ECMAScript 6, CSS3
- MVC, MVVM, MVP
- SQL Scripting, PowerShell Scripting
- ETL, SOA, TDD, SDLC Concepts
- Secure Software Design, High Performance Computing (Multithreading, Multiprocessing, C#.Net Code Performance Optimizations), Application Analysis & Detailed Design
- Old Projects: J2EE, SNMP, CIMD2, PHP, ColdFusion, Classic ASP, Oracle Identity & Access Management, Microsoft Azure Development

Comments and Discussions

 
QuestionAccess Denied Pin
Member 835641230-Jul-12 23:21
Member 835641230-Jul-12 23:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.