Private/Kinds/SessionElevated.ps1

# The SessionElevated Kind: the Sessions of the machine, read with admin rights.
#
# The Session Kind runs in the Main Part, in the Session of the User, and Windows does not
# answer a User for the Session of another account: who is signed in to it, since when,
# and when it last had input stay unread. On a terminal server that is every colleague.
# This Kind reads the same with admin rights and judges nothing: the Session Check is
# handed its reading as $Observed['SessionElevated'] and fills in what it could not read
# itself.
#
# State only, as there (ADR-0006): the account, the state, the times, and a count and a
# sum of what the processes of each Session hold. No name of a program, and not how or
# from where a Session is connected: see ConvertTo-SessionEntry.
#
# Its one Finding says that the reading was taken, so that the Check is accounted for in
# the Report like any other.

$script:SessionElevatedNeedsAdmin = $true

function Get-SessionElevatedData {
    <#
    .SYNOPSIS
        Every Session of the machine and what its processes hold, as an administrator may
        read it. Decides nothing.
    .DESCRIPTION
        Read as the Session Kind reads them, by the same two functions, so that the two
        readings have one shape and one can fill in the other.
    #>

    [CmdletBinding()]
    [OutputType([psobject])]
    param([hashtable]$Parameters = @{})

    $own = $null
    try { $own = (Get-Process -Id $PID -ErrorAction Stop).SessionId } catch { }

    [pscustomobject]@{
        PSTypeName = 'Gutcheck.Data.SessionElevated'
        Sessions   = @(Get-SessionReading -OwnSessionId $own | ForEach-Object { ConvertTo-SessionEntry -Session $_ })
        Held       = @(Group-SessionProcess -Process (Get-SessionProcess))
        GatheredAt = Get-Date
    }
}

function ConvertTo-SessionElevatedFinding {
    <#
    .SYNOPSIS
        One Finding saying how many Sessions were read with admin rights. Pure.
    .DESCRIPTION
        No judgement: how long a disconnected Session may be idle and how much it may hold
        is the Session Check's to judge, with the limits of its Definition.
    #>

    [CmdletBinding()]
    [OutputType([psobject])]
    param([AllowNull()]$Data, [hashtable]$Parameters = @{})

    $sessions = @((Get-DataCollection $Data 'Sessions') | ForEach-Object { $_ })
    if (-not $sessions.Count) {
        return New-UnavailableFinding -Category User -Check (Get-Text 'Check.SessionElevated.Reading') `
            -Hint (Get-Text 'Hint.Session.Repeat')
    }

    $signedIn = @($sessions | Where-Object { "$(Get-DataProperty $_ 'Account')".Trim() }).Count
    New-Finding -Category User -Check (Get-Text 'Check.SessionElevated.Reading') -Severity OK `
        -Value ((Get-Text 'Value.SessionElevated.Reading') -f $sessions.Count, $signedIn)
}