Get-xRDS_Logs_LocalSessionManager.ps1

function Get-xRDS_Logs_LocalSessionManager {

<#
    .DESCRIPTION
    Collects LocalSessionManager Logs from RDS Session Hosts.
  
    .PARAMETER Broker
    -ConnectionBroker - FQDN of RDS ConnectionBroker.
 
    .PARAMETER Broker
    -Computer - FQDN of RDS computer. (No required if you use connection brokers FQDN).
 
    .PARAMETER BeforeDays
    -BeforeDays - By default, logs are collected from current days midnight. If you use this value logs are calculated since before number of days.
 
    .PARAMETER Credential
    -Credential [Optional] - Query RDS Connection Broker resources under provided credentials, the same credentials will be used to query RDS session hosts.
 
    .PARAMETER UI
    -UI [Optional] - Displays records in GridView for output selection.
 
    .PARAMETER WINRMPort
    -WINRMPort [Optional] - WINRM Port to test for host connectivity validation. Default port is 5985.
 
    .EXAMPLE
    # Invokes RDS user's session logoff:
    Get-xRDS_SessionHostList -ConnectionBroker ardscbl01.adatum.labnet
#>



    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)][string]$ConnectionBroker,
        [String]$Computer = "localhost",
        [switch]$UI,
        [Int]$BeforeDays = 0,
        [Int]$WinRMPort = 5985,    
        [PSCredential]$Credential
    )      
   
    $ObjectsList=@()

    if($ConnectionBroker) {$Collection = Get-xRDS_CollectionsList -ConnectionBroker $ConnectionBroker -Credential $Credential} 
    else {$Collection = @{ $Computer = "Computer"}}

    Try {  

    #List session host maintenance mode

             foreach ($key in $Collection.Keys) 
                {

                $TempObject=@()
                $connection = $null;

                #Test host WInRM access
                $connection =  Invoke-xRDS_TestPort -hostname $key -port $WinRMPort
                
                if ($connection.open) {
                write-host "Collecting RDS LocalSessionManager logs from $key" -ForegroundColor Cyan

                $ObjectsList += invoke-Command -cn $key -ArgumentList $BeforeDays -ScriptBlock {`
                Get-WinEvent -logname "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational" | where {($_.Id -eq "21" -OR $_.Id -eq "23" -OR $_.Id -eq "24" -OR $_.Id -eq "25" -OR $_.Id -eq "39" -OR $_.Id -eq "40" -AND $_.timecreated -gt ((Get-date -hour 0 -minute 0 -second 0).adddays(-($args[0]))))} | %{
                (new-object -Type PSObject -Property @{
                EventID = $_.ID
                TimeGenerated = $_.TimeCreated 


                Message = $_.Message -replace '(?smi):(.*?[^\\]):\s+([^\s]+)\s+.*','$1'

                UserName = if ($_.Message -eq ($_.Message -replace '(?smi).*User:\s+([^\s]+)\s+.*','$1')){""} else {$_.Message -replace '(?smi).*User:\s+([^\s]+)\s+.*','$1'}

                ReasonCode = if ($_.ID -eq 40) {if ($_.Message -eq ($_.Message -replace '(?smi).*reason code\s+([^\s]+).*','$1')){""} else {$_.Message -replace '(?smi).*reason code\s+([^\s]+).*','$1'}}
                else {""}

                ClientIP = if ($_.ID -eq 21) {if ($_.Message -eq ($_.Message -replace '(?smi).*Source Network Address:\s+([^\s]+).*','$1')){""} else {$_.Message -replace '(?smi).*Source Network Address:\s+([^\s]+).*','$1'}}
                ElseIf ($_.ID -eq 24) {if ($_.Message -eq ($_.Message -replace '(?smi).*Source Network Address:\s+([^\s]+).*','$1')){""} else {$_.Message -replace '(?smi).*Source Network Address:\s+([^\s]+).*','$1'}}
                ElseIf ($_.ID -eq 25) {if ($_.Message -eq ($_.Message -replace '(?smi).*Source Network Address:\s+([^\s]+).*','$1')){""} else {$_.Message -replace '(?smi).*Source Network Address:\s+([^\s]+).*','$1'}}
                else {""}

                SessionID = if ($_.ID -eq 40) {$_.Message -replace '(?smi)Session\s+([^\s]+)\s+.*','$1'}
                ElseIf ($_.ID -eq 23) {$_.Message -replace '(?smi).*Session ID:\s+([^\s]+).*','$1'}
                else {if ($_.Message -eq ($_.Message -replace '(?smi).*Session ID:\s+([^\s]+)\s+.*','$1')){$_.Message -replace '(?smi)Session\s+([^\s]+)\s+.*','$1'} else {$_.Message -replace '(?smi).*Session ID:\s+([^\s]+)\s+.*','$1'}}

                })
                } | sort TimeGenerated -Descending | Select TimeGenerated,EventID,SessionID,UserName,ClientIP `
                , @{N='Action';E={
                switch ($_.EventID) {
                21 {'LOGON'}
                23 {'LOGOFF'}
                24 {'DISCONNECT'}
                25 {'RECONNECTION'}
                40 {'DISCONNECT'}
                default {$_}
                }
                }},ReasonCode `
                , @{N='Reason';E={
                switch ($_.ReasonCode) {
                1 {'The disconnection was initiated by an administrative tool on the server in another session.'}
                2 {'The disconnection was due to a forced logoff initiated by an administrative tool on the server in another session.'}
                3 {'The idle session limit timer on the server has elapsed.'}
                4 {'The active session limit timer on the server has elapsed.'}
                5 {'Another user connected to the server, forcing the disconnection of the current connection.'}
                6 {'The server ran out of available memory resources.'}
                7 {'The server denied the connection.'}
                9 {'The user cannot connect to the server due to insufficient access privileges.'}
                10 {'The server does not accept saved user credentials and requires that the user enter their credentials for each connection.'}
                11 {'The disconnection was initiated by the user disconnecting his or her session on the server or by an administrative tool on the server.'}
                12 {'The disconnection was initiated by the user logging off his or her session on the server.'}
                default {$_}
                }
                }},Message}

                }
                
                else {write-host "Cannot access WinRM port for $key" -ForegroundColor Red}
                   
                } 

             #Output
             If($UI) {$ObjectsList | Out-GridView -PassThru -Title "RDS LocalSessionManager Log Details"}
             ELSE {$ObjectsList } 

    } Catch {Write-host $_.Exception.message }   

}