Tag Archive for: Licensing

RDS License Audit Toolkit

<#
.SYNOPSIS
RDS License Audit Toolkit

.DESCRIPTION
This script performs a comprehensive audit of Remote Desktop Services (RDS) licensing,
including license server configuration, available licenses, and usage statistics.

.NOTES
File Name      : RDSLicenseAuditToolkit.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, administrator rights, and RDS management tools
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\RDSLicenseAuditToolkit.ps1
#>

# Global variables
$global:reportPath = "$env:USERPROFILE\Desktop\RDS_License_Audit_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html"
$global:licenseServer = $env:COMPUTERNAME  # Default to local machine

function Show-Menu {
    Clear-Host
    Write-Host "=== RDS License Audit Toolkit ===" -ForegroundColor Cyan
    Write-Host "Current License Server: $global:licenseServer"
    Write-Host "1. Set License Server"
    Write-Host "2. Check License Server Configuration"
    Write-Host "3. List Available Licenses"
    Write-Host "4. Analyze License Usage"
    Write-Host "5. Check RDS Server Configuration"
    Write-Host "6. Verify CAL Compliance"
    Write-Host "7. Review License Policies"
    Write-Host "8. Check License Server Health"
    Write-Host "9. Generate Comprehensive HTML Report"
    Write-Host "10. Exit"
}

function Set-LicenseServer {
    $server = Read-Host "Enter the RDS License Server name (or press Enter for localhost)"
    if ([string]::IsNullOrWhiteSpace($server)) {
        $global:licenseServer = $env:COMPUTERNAME
    } else {
        $global:licenseServer = $server
    }
    Write-Host "License server set to: $global:licenseServer" -ForegroundColor Green
}

function Check-LicenseServerConfiguration {
    Write-Host "`nChecking License Server Configuration..." -ForegroundColor Yellow
    try {
        $config = Invoke-Command -ComputerName $global:licenseServer -ScriptBlock {
            Import-Module RemoteDesktopServices
            $serverInfo = Get-RDLicenseConfiguration
            $serverStatus = Get-RDLicenseServerStatus
            return @{
                ServerInfo = $serverInfo
                ServerStatus = $serverStatus
            }
        }
        
        $result = [PSCustomObject]@{
            Mode = $config.ServerInfo.Mode
            LicensingType = $config.ServerInfo.LicensingType
            IsActivated = $config.ServerStatus.IsActivated
            LastIssuedLicenseDate = $config.ServerStatus.LastIssuedLicenseDate
            GracePeriodDays = $config.ServerStatus.GracePeriodDays
        }
        
        $result | Format-List
        return $result
    }
    catch {
        Write-Host "Error checking license server configuration: $_" -ForegroundColor Red
        return $null
    }
}

function List-AvailableLicenses {
    Write-Host "`nListing Available Licenses..." -ForegroundColor Yellow
    try {
        $licenses = Invoke-Command -ComputerName $global:licenseServer -ScriptBlock {
            Import-Module RemoteDesktopServices
            Get-RDLicense
        }
        
        $licenses | Format-Table -AutoSize
        return $licenses
    }
    catch {
        Write-Host "Error listing available licenses: $_" -ForegroundColor Red
        return $null
    }
}

function Analyze-LicenseUsage {
    Write-Host "`nAnalyzing License Usage..." -ForegroundColor Yellow
    try {
        $usage = Invoke-Command -ComputerName $global:licenseServer -ScriptBlock {
            Import-Module RemoteDesktopServices
            Get-RDLicenseUsage
        }
        
        $usage | Format-Table -AutoSize
        return $usage
    }
    catch {
        Write-Host "Error analyzing license usage: $_" -ForegroundColor Red
        return $null
    }
}

function Check-RDSServerConfiguration {
    Write-Host "`nChecking RDS Server Configuration..." -ForegroundColor Yellow
    try {
        $config = Invoke-Command -ComputerName $global:licenseServer -ScriptBlock {
            Import-Module RemoteDesktopServices
            $deployment = Get-RDDeploymentGatewayConfiguration
            $collection = Get-RDSessionCollection
            return @{
                Deployment = $deployment
                Collection = $collection
            }
        }
        
        $result = [PSCustomObject]@{
            GatewayMode = $config.Deployment.GatewayMode
            CollectionName = $config.Collection.CollectionName
            CollectionDescription = $config.Collection.CollectionDescription
        }
        
        $result | Format-List
        return $result
    }
    catch {
        Write-Host "Error checking RDS server configuration: $_" -ForegroundColor Red
        return $null
    }
}

function Verify-CALCompliance {
    Write-Host "`nVerifying CAL Compliance..." -ForegroundColor Yellow
    try {
        $compliance = Invoke-Command -ComputerName $global:licenseServer -ScriptBlock {
            Import-Module RemoteDesktopServices
            $licenses = Get-RDLicense
            $usage = Get-RDLicenseUsage
            
            $totalLicenses = ($licenses | Measure-Object -Property TotalLicenses -Sum).Sum
            $usedLicenses = ($usage | Measure-Object -Property IssuedLicenses -Sum).Sum
            
            return @{
                TotalLicenses = $totalLicenses
                UsedLicenses = $usedLicenses
                IsCompliant = $totalLicenses -ge $usedLicenses
            }
        }
        
        $result = [PSCustomObject]@{
            TotalLicenses = $compliance.TotalLicenses
            UsedLicenses = $compliance.UsedLicenses
            IsCompliant = $compliance.IsCompliant
            ComplianceStatus = if ($compliance.IsCompliant) { "Compliant" } else { "Non-Compliant" }
        }
        
        $result | Format-List
        return $result
    }
    catch {
        Write-Host "Error verifying CAL compliance: $_" -ForegroundColor Red
        return $null
    }
}

function Review-LicensePolicies {
    Write-Host "`nReviewing License Policies..." -ForegroundColor Yellow
    try {
        $policies = Invoke-Command -ComputerName $global:licenseServer -ScriptBlock {
            Import-Module RemoteDesktopServices
            Get-RDLicenseConfiguration
        }
        
        $result = [PSCustomObject]@{
            Mode = $policies.Mode
            LicensingType = $policies.LicensingType
            PolicyExpirationDays = $policies.PolicyExpirationDays
            PolicyOverrideAllowed = $policies.PolicyOverrideAllowed
        }
        
        $result | Format-List
        return $result
    }
    catch {
        Write-Host "Error reviewing license policies: $_" -ForegroundColor Red
        return $null
    }
}

function Check-LicenseServerHealth {
    Write-Host "`nChecking License Server Health..." -ForegroundColor Yellow
    try {
        $health = Invoke-Command -ComputerName $global:licenseServer -ScriptBlock {
            Import-Module RemoteDesktopServices
            $status = Get-RDLicenseServerStatus
            $service = Get-Service -Name TermServLicensing
            
            return @{
                Status = $status
                ServiceStatus = $service.Status
            }
        }
        
        $result = [PSCustomObject]@{
            IsActivated = $health.Status.IsActivated
            LastIssuedLicenseDate = $health.Status.LastIssuedLicenseDate
            GracePeriodDays = $health.Status.GracePeriodDays
            ServiceStatus = $health.ServiceStatus
        }
        
        $result | Format-List
        return $result
    }
    catch {
        Write-Host "Error checking license server health: $_" -ForegroundColor Red
        return $null
    }
}

function Generate-HTMLReport {
    param([hashtable]$AllResults)

    Write-Host "`nGenerating Comprehensive HTML Report..." -ForegroundColor Yellow
    $reportContent = @"
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>RDS License Audit Report</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; }
        h1, h2, h3 { color: #0078D4; }
        table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
        .warning { color: orange; }
        .critical { color: red; }
        .success { color: green; }
    </style>
</head>
<body>
    <h1>RDS License Audit Report</h1>
    <p>Generated on: $(Get-Date)</p>
    <p>License Server: $global:licenseServer</p>

    <h2>License Server Configuration</h2>
    $($AllResults.ServerConfig | ConvertTo-Html -Fragment)

    <h2>Available Licenses</h2>
    $($AllResults.AvailableLicenses | ConvertTo-Html -Fragment)

    <h2>License Usage</h2>
    $($AllResults.LicenseUsage | ConvertTo-Html -Fragment)

    <h2>RDS Server Configuration</h2>
    $($AllResults.RDSConfig | ConvertTo-Html -Fragment)

    <h2>CAL Compliance</h2>
    $($AllResults.CALCompliance | ConvertTo-Html -Fragment)

    <h2>License Policies</h2>
    $($AllResults.LicensePolicies | ConvertTo-Html -Fragment)

    <h2>License Server Health</h2>
    $($AllResults.ServerHealth | ConvertTo-Html -Fragment)
</body>
</html>
"@

    $reportContent | Out-File -FilePath $global:reportPath
    Write-Host "Report generated and saved to: $global:reportPath" -ForegroundColor Green
}

# Main program loop
$allResults = @{}

do {
    Show-Menu
    $choice = Read-Host "`nEnter your choice (1-10)"

    switch ($choice) {
        "1" { Set-LicenseServer }
        "2" { $allResults.ServerConfig = Check-LicenseServerConfiguration }
        "3" { $allResults.AvailableLicenses = List-AvailableLicenses }
        "4" { $allResults.LicenseUsage = Analyze-LicenseUsage }
        "5" { $allResults.RDSConfig = Check-RDSServerConfiguration }
        "6" { $allResults.CALCompliance = Verify-CALCompliance }
        "7" { $allResults.LicensePolicies = Review-LicensePolicies }
        "8" { $allResults.ServerHealth = Check-LicenseServerHealth }
        "9" { Generate-HTMLReport -AllResults $allResults }
        "10" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

    if ($choice -ne "10") {
        Read-Host "`nPress Enter to continue..."
    }
} while ($choice -ne "10")

This RDS License Audit Toolkit includes:

  1. A menu-driven interface for easy navigation.
  2. Functions to analyze various aspects of RDS licensing:
    • License Server Configuration Check
    • Available Licenses Listing
    • License Usage Analysis
    • RDS Server Configuration Check
    • CAL Compliance Verification
    • License Policies Review
    • License Server Health Check
  3. Option to set a target license server (local or remote)
  4. HTML report generation for easy sharing and viewing of results

Key features:

  • Comprehensive RDS license server configuration analysis
  • Detailed listing of available licenses and their types
  • Analysis of current license usage
  • Verification of Client Access License (CAL) compliance
  • Review of RDS deployment and collection configurations
  • Examination of license policies and server health

This tool is particularly useful for:

  • RDS administrators managing license servers
  • IT professionals auditing RDS environments
  • System administrators troubleshooting RDS licensing issues
  • Anyone needing to quickly gather comprehensive information about RDS licensing configuration and usage

To use this script effectively:

  1. Run PowerShell as an administrator
  2. Ensure you have the Remote Desktop Services PowerShell module installed
  3. Have the necessary permissions to query RDS license information (local admin rights on the license server or appropriate delegated permissions)
  4. Review the generated HTML report for a comprehensive overview of the RDS licensing status and configuration

This script provides a thorough analysis of RDS licensing, helping to identify potential issues, compliance concerns, or areas that need attention. It’s designed to give administrators a quick but comprehensive view of their RDS licensing health and configuration.