Powershell List Users who have RDS User Cal

powershellwindows-server-2012

I have a script to show users which haven't logged in recently which uses the Get -ADUser command with a filter on 'LastLoginTimeStamp'.

At the moment we disable accounts which haven't logged in for 90 days but I would like to take this a step further (as we are very limited on licenses) so that accounts without a license assigned are disabled after 30 days. If they already have a license assigned there isn't much point in disabling their account before that license expires.

As the Microsoft policy states 'any user with the ability to RDP must have a license' we are finding our self in the position where we have users that are not using RDP that we would like to disable and move to a group which doesn't permit RDP so we can free up a license for a new user.

I have came across multiple resources online which show how CSV reports can be produced but I can't find anything which shows how PowerShell can access this information. Is there a way or am I going to have to create a Powershell script to export a CSV license report and then another to compare the contents of that CSV to a list of users that haven't logged in within x days.

I am not looking for someone to write a script for me but to confirm if there is a way of doing this within Powershell.

Thanks,

Jack.

Best Answer

In most Remote Desktop/Terminal Server licensing situations I have worked with, this information is stored against the user object in Active Directory. So getting this info out is a matter of knowing either the right LDAP filter or properties to query.

I've got a JScript-based report that I run to pull this information out, using cscript.exe, but the principals should be the same in Powershell.

In older servers/domains (<=2003), this information was stored in a single property, terminalServer; and in newer ones (>2003), this is spread across three properties (that I know of), called msTSManagingLS, msTSLicenseVersion and msTSExpireDate. Obviously, with more information to go on, it is easier to pull this from newer domains (but, since you are working with Powershell, this is probably fine).

As such, assuming a version of Powershell and the AD module that supports scriptblock-style filters, the following (while slightly inefficient) should get you close:

Get-ADUser -Filter {(msTSManagingLS -like '*' -and msTSLicenseVersion -like '*') -or (terminalServer -like '*')} -Properties * | fl -Property Name,sAMAccountName,msTS*

If you are running on an older Powershell version, you may need to craft the filter in a more LDAP-friendly fashion. Maybe:

Get-ADUser -LDAPFilter '(|(&(msTSManagingLS=*)(msTSLicenseVersion=*))(terminalServer=*))' -Properties * | fl -Property Name,sAMAccountName,msTS*

Once you have the relevant AD objects in the pipeline, you can call regular Powershell on them (such as Where-Object { $_.msTSExpireDate -lt [DateTime]::Today.AddDays(-30) } | Disable-Account)

Note that you'll want to do a lot more work than I have done above to make sure you don't disable any reasonable accounts (especially as it might render you and/or other admins unable to access your own machines to resolve). At a minimum, I'd certainly look to limit this to users within a specific OU, e.g. by applying valid -SearchBase and -SearchScope parameters to your Get-ADUser call, or do more checking in your Where-Object filter (such as using Get-ADPrincipalGroupMembership to make sure they're not in the Domain Admins group).

Also note that this only works for Remote Desktop servers running the full-blown Remote Desktop Services with a Remote Desktop Licensing Server. You can't use this to check users who remote in using the two-connection Admin mode.