Public/Get-ADRemoteDesktopLicenseReport.ps1

<#
.SYNOPSIS
Retrieves users with valid Remote Desktop Services (RDS) licenses from Active Directory.
 
.DESCRIPTION
The Get-ADRemoteDesktopLicenseReport function queries Active Directory for user accounts that have active RDS licenses. It searches under a specified distinguished name (SearchBase) and domain, filters for enabled accounts with non-expired `msTSExpireDate` attributes, and optionally exports the result to a CSV file.
 
The function uses the AD Web Services (adws) for domain discovery and can return results directly or save them for reporting purposes.
 
.PARAMETER SearchBase
Specifies the distinguished name (DN) of the Active Directory container to begin the search. For example: `DC=test,DC=domain,DC=LOCAL`.
 
.PARAMETER DomainName
Specifies the domain name to query, used for domain controller discovery. For example: `americas.ppdi.local`.
 
.PARAMETER ExportToCsv
If specified, exports the RDS-licensed user information to a CSV file located at `C:\temp\`.
 
.EXAMPLE
# Retrieve all users with valid RDS licenses from the Americas domain
Get-ADRemoteDesktopLicenseReport -SearchBase "DC=test,DC=domain,DC=LOCAL" -DomainName "test"
 
.EXAMPLE
# Retrieve and export to CSV all users with valid RDS licenses from the Labs domain
Get-ADRemoteDesktopLicenseReport -SearchBase "DC=LABS,DC=domain,DC=LOCAL" -DomainName "labs" -ExportToCsv $true
 
.EXAMPLE
# Aggregate licensed users from multiple domains
$domainDetails = @{
    Americas = "DC=test,DC=domain,DC=LOCAL"
    Labs = "DC=LABS,DC=domain,DC=LOCAL"
    Europe = "DC=labtest,DC=domain,DC=LOCAL"
}
$totalRDSLicenses = 0
foreach ($domain in $domainDetails.Keys) {
    $result = Get-ADRemoteDesktopLicenseReport -SearchBase $domainDetails[$domain] -DomainName $domain.ToLower()
    $totalRDSLicenses += $result.Count
}
 
.NOTES
Requires Active Directory module and proper domain privileges. Uses `msTSExpireDate` and `msTSManagingLS` attributes to determine licensing.
#>



function Get-ADRemoteDesktopLicenseReport {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, Position = 0)]
        [ValidateNotNull()]
        [ValidateNotNullOrEmpty()]
        [string]$SearchBase,

        [Parameter(Mandatory = $true, Position = 1)]
        [ValidateNotNull()]
        [ValidateNotNullOrEmpty()]
        [string]$DomainName,

        [Parameter()]
        [bool]$ExportToCsv = $false
    )
    
    try {
        # Retrieve AD users with valid RDS licenses
        $users = Get-ADUser -Filter {Enabled -eq $true} `
                            -SearchBase $SearchBase `
                            -SearchScope Subtree `
                            -Server (Get-ADDomainController -Discover -DomainName $DomainName -Service adws | Select-Object -ExpandProperty Name) `
                            -Properties Enabled, msTSManagingLS, msTSExpireDate |
                 Where-Object { $_.msTSExpireDate -gt (Get-Date) } |
                 Select-Object SamAccountName, msTSManagingLS, msTSExpireDate

        $count = $users.Count

        if ($ExportToCSV) {
            $outputPath = "C:\temp\RDLicenses_$($DomainName.Replace('.', '_'))_$(Get-Date -Format 'MMM-yyyy').csv"
            if (-not (Test-Path "C:\temp")) {
                New-Item -Path "C:\temp" -ItemType Directory | Out-Null
            }

            $users | Export-Csv -Path $outputPath -NoTypeInformation -Force
            Write-LogEntry -Message "Exported $count RD licensed users to: $outputPath"
            return $users
        } else {
            Write-LogEntry -Message "Total RD licensed users found: $count"
            return $users
        }
    }
    catch {
        Write-LogEntry -Message "Error while fetching RD license info: $_"
    }
}