Public/RDS/Get-RDSActiveSessions.ps1
function Get-RDSActiveSessions { <# .SYNOPSIS Monitors and logs active Remote Desktop Services user sessions. .DESCRIPTION This function retrieves active RDS user sessions that haven't been idle for more than a specified threshold. It logs the session information to both a CSV log file and can optionally export to a separate CSV file. The function is designed to be used for monitoring user activity on RDS servers. .PARAMETER IdleThresholdMinutes The idle time threshold in minutes. Sessions idle longer than this will be excluded. Default is 60 minutes. .PARAMETER LogPath Path to the main log file. Default is "C:\Logs\rdsUserMonitor.csv". .PARAMETER ExportPath Path to export session data to a CSV file. If not specified, exports to ".\<hostname>-signIns.csv". .PARAMETER TranscriptPath Path to the transcript log file. Default is "C:\Logs\RdsMonitorTranscript.txt". .PARAMETER NoTranscript Switch to disable transcript logging. .EXAMPLE Get-RDSActiveSessions Monitors active RDS sessions using default settings (60-minute idle threshold). .EXAMPLE Get-RDSActiveSessions -IdleThresholdMinutes 30 Monitors active RDS sessions with a 30-minute idle threshold. .EXAMPLE Get-RDSActiveSessions -LogPath "D:\Logs\rds.csv" -ExportPath "D:\Reports\sessions.csv" Monitors active RDS sessions with custom log and export paths. .EXAMPLE Get-RDSActiveSessions -NoTranscript Monitors active RDS sessions without creating a transcript log. .NOTES Author: Michiel VH This function requires the RemoteDesktop PowerShell module. The function creates log directories if they don't exist. .LINK https://docs.microsoft.com/en-us/powershell/module/remotedesktop/get-rdusersession #> [CmdletBinding()] param( [Parameter(Mandatory = $false)] [int]$IdleThresholdMinutes = 60, [Parameter(Mandatory = $false)] [string]$LogPath = "C:\Logs\rdsUserMonitor.csv", [Parameter(Mandatory = $false)] [string]$ExportPath, [Parameter(Mandatory = $false)] [string]$TranscriptPath = "C:\Logs\RdsMonitorTranscript.txt", [Parameter(Mandatory = $false)] [switch]$NoTranscript ) # Import the Remote Desktop module if not already loaded if (-not (Get-Module -Name RemoteDesktop -ErrorAction SilentlyContinue)) { try { Import-Module RemoteDesktop -ErrorAction Stop } catch { Write-Error "Failed to import the RemoteDesktop module. Please ensure it is installed. Error: $_" return } } # Start transcript if not disabled if (-not $NoTranscript) { try { $transcriptDir = Split-Path -Path $TranscriptPath -Parent if (-not (Test-Path $transcriptDir)) { New-Item -ItemType Directory -Path $transcriptDir -Force | Out-Null } Start-Transcript -Path $TranscriptPath -Append -ErrorAction Stop } catch { Write-Warning "Failed to start transcript: $_" } } try { $hostname = $env:COMPUTERNAME # Set default export path if not provided if (-not $ExportPath) { $ExportPath = ".\$hostname-signIns.csv" } # Helper function for logging function Set-Log { param ( [string]$Message, [string]$Path = $LogPath ) $timestamp = Get-Date -Format "yyyy-MM-dd | HH:mm:ss" $logEntry = "$timestamp,$Message" try { $logDir = Split-Path -Path $Path -Parent if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force | Out-Null } Add-Content -Path $Path -Value $logEntry -ErrorAction Stop } catch { Write-Error "An error occurred while adding the log entry: $_" } } # Convert idle threshold to milliseconds $idleThreshold = $IdleThresholdMinutes * 60000 Write-Verbose "Getting RDS user sessions with idle threshold of $IdleThresholdMinutes minutes" # Get active sessions that haven't been idle for more than the threshold $activeSessions = Get-RDUserSession | Where-Object { $_.IdleTime -lt $idleThreshold } if ($activeSessions) { Write-Host "Found $($activeSessions.Count) active user session(s)" foreach ($session in $activeSessions) { $timestamp = Get-Date -Format "HH:mm:ss" $signInData = New-Object PSObject -Property @{ logTime = $timestamp userName = if($null -ne $session.UserName) { $session.UserName } else { "N/A" } createTime = if($null -ne $session.CreateTime) { $session.CreateTime } else { "N/A" } sessionState = if($null -ne $session.SessionState) { $session.SessionState } else { "N/A" } disconnectTime = if($null -ne $session.DisconnectTime) { $session.DisconnectTime } else { "N/A" } idleTimeMinutes = if($null -ne $session.IdleTime) { [math]::Round($session.IdleTime / 60000) } else { "N/A" } serverName = if($null -ne $session.ServerName) { $session.ServerName } else { "N/A" } } # Log to main log file Set-Log "$($signInData.userName),$($signInData.idleTimeMinutes),$($signInData.serverName),$($signInData.createTime),$($signInData.disconnectTime),$($signInData.sessionState)" # Export to CSV $signInData | Export-Csv -Path $ExportPath -NoTypeInformation -Append Write-Host "Collected log entry for $($signInData.userName)" -ForegroundColor Green } } else { $message = "No active user sessions found that haven't been idle for more than $IdleThresholdMinutes minutes" Write-Host $message -ForegroundColor Yellow Set-Log $message } } catch { Write-Error "An error occurred while processing RDS sessions: $_" } finally { # Stop transcript if it was started if (-not $NoTranscript) { try { Stop-Transcript -ErrorAction SilentlyContinue } catch { # Transcript might not have been started successfully } } } } |