PowerShell ASP: List Current Sessions of Machines on an Active Directory Domain



Requirements:

Overview

By combining several techniques, this article walks through creating a page that lists the current sessions for machines on an Active Directory domain. This article provides step by step instructions on how to create a simple PowerShell ASP page to list the session information for machines on an Active Directory domain. There are two main steps to accomplishing this.

  1. List the machines on the domain
  2. Get session information for each machine listed

To achieve these goals we will look to the world’s PowerShell enthusiasts who have already solved many of these problems and made the solutions freely available, then combine them and use them in a PowerShell ASP page to provide a simple and easy way of listing sessions of machines on the domain.

Over at the Hey, Scripting Guy! blog, ScriptingGuy1 has given us a way in this article to list all the machines on a domain using the classes in the .NET System.DirectoryServices namespace from PowerShell. This will help us achieve our first goal.

Shay Levy has created a freely available module called PSTerminalServices – A PowerShell Module for Terminal Services. This will aid us by allowing us to easily query each machine for session information.

Prerequisites and Setup

Before diving into the code in the next section (which is actually very simple), there are a few requirements worth noting.

  1. The machines in the domain must have the “AllowRemoteRPC” setting enabled. This is a value in the registry that can either be set manually or set by a custom group policy. This allows sessions to be queried remotely. To enable this manually open the registry editor and navigate to

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server

    Now Locate the AllowRemoteRPC value and change the value data from 0 to 1 to enable this.

  2. The PSTerminalServices module must be installed in a location where it is accessible from PowerShell ASP at runtime. Instead of installing to the user’s “Documents\WindowsPowerShell\Modules” folder the module will need to be installed to:
    c:\windows\system32\windowspowershell\v1.0\modules

    Note that you can simply copy the entire PSTerminalServices folder from the user’s “Documents\WindowsPowerShell\Modules” to the location above.

  3. PowerShell ASP must be running under an account that is a member of the domain. In this article we will assume PowerShell ASP is being used in a site hosted in IIS. Since by default the application pool identity used is not a member of a domain, the easiest approach here is to create a new application pool for this application. In IIS 7 and IIS 7.5 create a new application pool, then in the advanced settings for the application pool specify a new Identify value as a domain user account. For instance:

Lastly, modify the basic settings of the “PowerShellASP” application in IIS to use the new application pool.

The Code

The code for this operation is actually relatively simple. First we will obtain a list of machines on the domain, then we will get session information for each machine and display it.

<h2>Current session information</h2>

<div>
<table>
<tr><th>Server</th><th>SessionID</th><th>State</th><th>UserName</th><th>WindowStationName</th></tr>
<%
Import-Module PSTerminalServices

#List machines on a domain
$strCategory = "computer"

$objDomain = New-Object System.DirectoryServices.DirectoryEntry

$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.Filter = ("(objectCategory=$strCategory)")

$colProplist = "name"
foreach ($i in $colPropList){$null = $objSearcher.PropertiesToLoad.Add($i)}

$colResults = $objSearcher.FindAll()

#Iterate through the results and get session information for each machine
foreach ($objResult in $colResults)
{
	$objComputer = $objResult.Properties; 
	
	$sessionInfo = Get-TSSession -ComputerName $objComputer.name -ErrorAction SilentlyContinue -ErrorVariable myError

	if($sessionInfo)
	{
		foreach($tempInfo in $sessionInfo)
		{
		%>
		<tr><td><%= $tempInfo.Server.ServerName %></td><td><%= $tempInfo.SessionId %></td><td><%= $tempInfo.State %></td><td><%= $tempInfo.UserName %></td><td><%= $tempInfo.WindowStationName %></td></tr>
		<%
		}
	}
	else #an error occurred
	{
	%>
	<tr><td><% $objComputer.name; %><td colspan=4>Error: <%= $myError[0] %></td></tr>
	<%
	}	
} %>
</table>
</div>
</body>
</html>	

When accessing this page you will then see a neat list of session information for each machine such as this:

That is all there is to it. The easiest way to test this is to download the .ps1x file below and place this in the “www” folder of the PowerShell ASP Installation alongside the other demos.