Get-xRDS_Logs_Security.ps1

function Get-xRDS_Logs_Security {

<#
    .DESCRIPTION
    Collects Security Logs for RDS sessions 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 Security logs from $key" -ForegroundColor Cyan

                $ObjectsList += invoke-Command -cn $key -ArgumentList $BeforeDays -ScriptBlock {`
                  Get-EventLog -LogName Security -after ((Get-date -hour 0 -minute 0 -second 0).adddays(-($args[0])))| ?{(4624,4625,4778,4799) -contains $_.EventID -and ($_.Message -match 'logon type:\s+(10)\s') -OR $_.Message -match 'logon type:\s+(7)\s'}| %{
                (new-object -Type PSObject -Property @{
                EventID = $_.EventID
                TimeGenerated = $_.TimeGenerated
                ClientIP = if ($_.Message -eq ($_.Message -replace '(?smi).*Source Network Address:\s+([^\s]+)\s+.*','$1')){"-"} else {$_.Message -replace '(?smi).*Source Network Address:\s+([^\s]+)\s+.*','$1'};
                SID = $_.Message -replace '(?smi).*Security ID:\s+([^\s]+)\s+.*','$1'
                UserName = $_.Message -replace '(?smi).*[^Network Account Name:]Account Name:\s+([^\s]+)\s+.*','$1'
                Domain = $_.Message -replace '(?smi).*[^Network Account Domain:]Account Domain:\s+([^\s]+)\s+.*','$1'
                ReasonCode = if ($_.EventID -eq 4625) {if ($_.Message -eq ($_.Message -replace '(?smi).*Sub Status:\s+([^\s]+)\s+.*','$1')){""} else {$_.Message -replace '(?smi).*Sub Status:\s+([^\s]+)\s+.*','$1'}};
                LinkedLogonID = if ($_.Message -eq ($_.Message -replace '(?smi).*Linked Logon ID:\s+([^\s]+)\s+.*','$1')){""} else {$_.Message -replace '(?smi).*Linked Logon ID:\s+([^\s]+)\s+.*','$1'}
                LogonType = $_.Message -replace '(?smi).*Logon Type:\s+([^\s]+)\s+.*','$1'
                })
                } | sort TimeGenerated -Descending | Select TimeGenerated,EventID,Domain,Username,ClientIP `
                , @{N='EventType';E={
                switch ($_.EventID) {
                4624 {'LOGON SUCCESS'}
                4625 {'LOGON FAILED'}
                4778 {'SESSION RECONNECTED'}
                4799 {'SESSION DISCONNECTED'}
                default {$_.EventID}
                }
                }}`
                , @{N='Logon';E={
                switch ($_.LogonType) {
                2 {'Interactive - local logon'}
                3 {'Network connection to shared folder)'}
                4 {'Batch'}
                5 {'Service'}
                7 {'Unlock (after screensaver)'}
                8 {'NetworkCleartext'}
                9 {'NewCredentials (local impersonation process under existing connection)'}
                10 {'RDP'}
                11 {'CachedInteractive'}
                default {$_.LogonType}
                }
                }},LogonType `
                , @{N='Reason';E={
                switch ($_.ReasonCode) {
                "0XC000005E" {'There are currently no logon servers available to service the logon request.'}
                "0xC0000064" {'User logon with misspelled or bad user account'}
                "0xC000006A" {'User logon with misspelled or bad password'}
                "0XC000006D" {'This is either due to a bad username or authentication information'}
                "0XC000006E" {'Unknown user name or bad password.'}
                "0xC000006F" {'User logon outside authorized hours'}
                "0xC0000070" {'User logon from unauthorized workstation'}
                "0xC0000071" {'User logon with expired password'}
                "0xC0000072" {'User logon to account disabled by administrator'}
                "0XC00000DC" {'Indicates the Sam Server was in the wrong state to perform the desired operation.'}
                "0XC0000133" {'Clocks between DC and other computer too far out of sync'}
                "0XC000015B" {'The user has not been granted the requested logon type (aka logon right) at this machine'}
                "0XC000018C" {'The logon request failed because the trust relationship between the primary domain and the trusted domain failed.'}
                "0XC0000192" {'An attempt was made to logon, but the Netlogon service was not started.'}
                "0xC0000193" {'User logon with expired account'}
                "0XC0000224" {'User is required to change password at next logon'}
                "0XC0000225" {'Evidently a bug in Windows and not a risk'}
                "0xC0000234" {'User logon with account locked'}
                "0XC00002EE" {'Failure Reason: An Error occurred during Logon'}
                "0XC0000413" {'Logon Failure: The machine you are logging onto is protected by an authentication firewall. The specified account is not allowed to authenticate to the machine.'}
                "0x0" {'Status OK.'}
                default {$_}
                }
                }}`
                ,SID,LinkedLogonID}

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

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

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

}