RDS Toolkit – Remote Desktop Services Management Script

<#
.SYNOPSIS
RDS Toolkit - Comprehensive Remote Desktop Services Management Script

.DESCRIPTION
This script provides a set of tools for managing and monitoring Remote Desktop Services environments.
It includes functions for session management, user monitoring, performance analysis, and reporting.

.NOTES
File Name      : RDSToolkit.ps1
Author         : [Your Name]
Prerequisite   : PowerShell V5.1 or later, admin rights on the RDS server
Version        : 1.0
Date           : [Current Date]

.EXAMPLE
.\RDSToolkit.ps1
#>

# Import required modules
Import-Module RemoteDesktop

# Global variables
$global:logFile = "$env:USERPROFILE\Desktop\RDS_Toolkit_Log_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"

function Write-Log {
    param (
        [string]$Message
    )
    
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $logEntry = "$timestamp - $Message"
    Add-Content -Path $global:logFile -Value $logEntry
    Write-Host $logEntry
}

function Show-Menu {
    Clear-Host
    Write-Host "=== RDS Toolkit ===" -ForegroundColor Cyan
    Write-Host "1. List Active Sessions"
    Write-Host "2. Disconnect User"
    Write-Host "3. Log Off User"
    Write-Host "4. Send Message to Users"
    Write-Host "5. Monitor Disconnected Sessions"
    Write-Host "6. View RDS Server Performance"
    Write-Host "7. Generate RDS Usage Report"
    Write-Host "8. Manage RDS Collections"
    Write-Host "9. Exit"
}

function Get-ActiveSessions {
    $sessions = quser | Where-Object { $_ -match 'Active' }
    $activeSessions = @()
    foreach ($session in $sessions) {
        $sessionInfo = $session -split '\s+'
        $activeSessions += [PSCustomObject]@{
            Username = $sessionInfo[1]
            SessionID = $sessionInfo[2]
            State = $sessionInfo[3]
            IdleTime = $sessionInfo[4]
            LogonTime = $sessionInfo[5..($sessionInfo.Length-1)] -join ' '
        }
    }
    return $activeSessions
}

function Disconnect-RDSUser {
    $username = Read-Host "Enter username to disconnect"
    $sessions = quser | Where-Object { $_ -match $username }
    if ($sessions) {
        $sessionId = ($sessions -split '\s+')[2]
        tsdiscon $sessionId
        Write-Log "Disconnected user: $username (Session ID: $sessionId)"
    } else {
        Write-Host "User not found or not connected." -ForegroundColor Yellow
    }
}

function LogOff-RDSUser {
    $username = Read-Host "Enter username to log off"
    $sessions = quser | Where-Object { $_ -match $username }
    if ($sessions) {
        $sessionId = ($sessions -split '\s+')[2]
        logoff $sessionId
        Write-Log "Logged off user: $username (Session ID: $sessionId)"
    } else {
        Write-Host "User not found or not connected." -ForegroundColor Yellow
    }
}

function Send-MessageToUsers {
    $message = Read-Host "Enter message to send"
    $users = Get-ActiveSessions
    foreach ($user in $users) {
        msg $user.Username $message
    }
    Write-Log "Sent message to all active users: $message"
}

function Monitor-DisconnectedSessions {
    $duration = Read-Host "Enter monitoring duration in minutes (0 for continuous)"
    $startTime = Get-Date
    Write-Host "Monitoring disconnected sessions. Press Ctrl+C to stop." -ForegroundColor Yellow
    
    try {
        while ($true) {
            $disconnectedSessions = quser | Where-Object { $_ -match 'Disc' }
            foreach ($session in $disconnectedSessions) {
                $sessionInfo = $session -split '\s+'
                Write-Host "Disconnected: $($sessionInfo[1]) (Session ID: $($sessionInfo[2]))" -ForegroundColor Red
                Write-Log "Disconnected session detected: $($sessionInfo[1]) (Session ID: $($sessionInfo[2]))"
            }
            
            if ($duration -ne "0" -and ((Get-Date) - $startTime).TotalMinutes -ge $duration) {
                break
            }
            
            Start-Sleep -Seconds 30
        }
    }
    catch {
        Write-Host "Monitoring stopped." -ForegroundColor Yellow
    }
}

function View-RDSServerPerformance {
    $duration = Read-Host "Enter monitoring duration in minutes"
    $interval = Read-Host "Enter sampling interval in seconds"
    $startTime = Get-Date
    $endTime = $startTime.AddMinutes($duration)
    
    Write-Host "Monitoring RDS server performance. This may take $duration minutes." -ForegroundColor Yellow
    
    $performanceData = @()
    
    while ((Get-Date) -lt $endTime) {
        $cpu = (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples.CookedValue
        $memory = (Get-Counter '\Memory\% Committed Bytes In Use').CounterSamples.CookedValue
        $disk = (Get-Counter '\PhysicalDisk(_Total)\% Disk Time').CounterSamples.CookedValue
        $network = (Get-Counter '\Network Interface(*)\Bytes Total/sec').CounterSamples.CookedValue | Measure-Object -Sum | Select-Object -ExpandProperty Sum
        
        $performanceData += [PSCustomObject]@{
            Timestamp = Get-Date
            CPU = [math]::Round($cpu, 2)
            Memory = [math]::Round($memory, 2)
            Disk = [math]::Round($disk, 2)
            Network = [math]::Round($network / 1MB, 2)  # Convert to MB/s
        }
        
        Start-Sleep -Seconds $interval
    }
    
    $performanceData | Format-Table -AutoSize
    $performanceData | Export-Csv -Path "$env:USERPROFILE\Desktop\RDS_Performance_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv" -NoTypeInformation
    Write-Host "Performance data exported to desktop." -ForegroundColor Green
}

function Generate-RDSUsageReport {
    $days = Read-Host "Enter number of days for the report"
    $startDate = (Get-Date).AddDays(-$days)
    $events = Get-WinEvent -FilterHashtable @{
        LogName = 'Microsoft-Windows-TerminalServices-LocalSessionManager/Operational'
        ID = 21, 23, 24, 25  # Logon, Logoff, Disconnect, Reconnect
        StartTime = $startDate
    }
    
    $report = @()
    foreach ($event in $events) {
        $report += [PSCustomObject]@{
            Timestamp = $event.TimeCreated
            Username = $event.Properties[0].Value
            EventType = switch ($event.Id) {
                21 { "Logon" }
                23 { "Logoff" }
                24 { "Disconnect" }
                25 { "Reconnect" }
            }
        }
    }
    
    $report | Format-Table -AutoSize
    $report | Export-Csv -Path "$env:USERPROFILE\Desktop\RDS_Usage_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv" -NoTypeInformation
    Write-Host "Usage report exported to desktop." -ForegroundColor Green
}

function Manage-RDSCollections {
    Write-Host "RDS Collections Management" -ForegroundColor Cyan
    Write-Host "1. List Collections"
    Write-Host "2. Create New Collection"
    Write-Host "3. Add Server to Collection"
    Write-Host "4. Remove Server from Collection"
    Write-Host "5. Back to Main Menu"
    
    $choice = Read-Host "Enter your choice"
    
    switch ($choice) {
        "1" {
            Get-RDSessionCollection | Format-Table -AutoSize
        }
        "2" {
            $name = Read-Host "Enter new collection name"
            $sessionHost = Read-Host "Enter session host server name"
            New-RDSessionCollection -CollectionName $name -SessionHost $sessionHost
            Write-Log "Created new RDS collection: $name"
        }
        "3" {
            $collection = Read-Host "Enter collection name"
            $server = Read-Host "Enter server to add"
            Add-RDSessionHost -CollectionName $collection -SessionHost $server
            Write-Log "Added server $server to collection $collection"
        }
        "4" {
            $collection = Read-Host "Enter collection name"
            $server = Read-Host "Enter server to remove"
            Remove-RDSessionHost -CollectionName $collection -SessionHost $server
            Write-Log "Removed server $server from collection $collection"
        }
        "5" {
            return
        }
        default {
            Write-Host "Invalid choice. Please try again." -ForegroundColor Red
        }
    }
    
    Pause
    Manage-RDSCollections
}

# Main program loop
do {
    Show-Menu
    $choice = Read-Host "`nEnter your choice (1-9)"

    switch ($choice) {
        "1" { Get-ActiveSessions | Format-Table -AutoSize }
        "2" { Disconnect-RDSUser }
        "3" { LogOff-RDSUser }
        "4" { Send-MessageToUsers }
        "5" { Monitor-DisconnectedSessions }
        "6" { View-RDSServerPerformance }
        "7" { Generate-RDSUsageReport }
        "8" { Manage-RDSCollections }
        "9" { Write-Host "Exiting program..." -ForegroundColor Yellow; break }
        default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red }
    }

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

This RDS Toolkit script provides a comprehensive set of tools for managing and monitoring Remote Desktop Services environments. Here’s a breakdown of its features:

  1. List Active Sessions: Displays all currently active RDS sessions.
  2. Disconnect User: Allows you to disconnect a specific user.
  3. Log Off User: Allows you to log off a specific user.
  4. Send Message to Users: Sends a broadcast message to all active users.
  5. Monitor Disconnected Sessions: Continuously monitors and reports on disconnected sessions.
  6. View RDS Server Performance: Monitors and reports on server performance metrics (CPU, Memory, Disk, Network).
  7. Generate RDS Usage Report: Creates a report of RDS usage over a specified number of days.
  8. Manage RDS Collections: Provides options to list, create, and modify RDS collections.

To use this script:

  1. Save it as RDSToolkit.ps1.
  2. Open PowerShell as an administrator on the RDS server.
  3. Navigate to the directory containing the script.
  4. Run the script:

.\RDSToolkit.ps1

Notes:

  • This script requires administrative privileges on the RDS server.
  • Some functions may require additional modules or permissions depending on your RDS setup.
  • The script creates log files and exports reports to the desktop by default. You may want to modify these paths for production use.
  • Always test the script in a non-production environment before using it in production.

This toolkit provides a solid foundation for managing RDS environments and can be further customized based on specific organizational needs or more complex RDS setups.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *