Private/Invoke-QwinstaQuery.ps1

#Requires -Version 5.1

function Invoke-QwinstaQuery {
    <#
        .SYNOPSIS
            Internal wrapper -- queries active sessions on a target computer via qwinsta.exe
 
        .DESCRIPTION
            Private function, not exported. Executes qwinsta.exe /server:<ServerName> and
            returns both the raw output lines and the process exit code encapsulated in a
            single PSCustomObject. This design allows the caller to be unit-tested without
            depending on the automatic variable $LASTEXITCODE, which is not reliably set
            when native commands are intercepted by Pester mocks.
 
        .PARAMETER ServerName
            The computer name to query. Passed as /server:<ServerName> to qwinsta.exe.
 
        .EXAMPLE
            Invoke-QwinstaQuery -ServerName 'SRV01'
 
            Returns [PSCustomObject]@{ Output = @('...'); ExitCode = 0 }.
 
        .EXAMPLE
            $qr = Invoke-QwinstaQuery -ServerName $ComputerName
            if ($qr.ExitCode -ne 0) { Write-Error "qwinsta failed with code $($qr.ExitCode)" }
            foreach ($line in ($qr.Output | Select-Object -Skip 1)) { # parse }
 
        .NOTES
            Author: Franck SALLET
            Version: 1.0.0
            Last Modified: 2026-03-11
            Requires: PowerShell 5.1+, qwinsta.exe (Remote Desktop Services tools)
            Permissions: None -- internal function, not exported
 
        .LINK
            https://github.com/k9fr4n/PSWinOps
 
        .LINK
            https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/query-session
    #>

    [CmdletBinding()]
    [OutputType([PSCustomObject])]
    param(
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$ServerName
    )

    process {
        $qwinstaPath = Join-Path -Path $env:SystemRoot -ChildPath 'System32\qwinsta.exe'
        $rawOutput = & $qwinstaPath "/server:$ServerName" 2>&1
        [PSCustomObject]@{
            Output   = $rawOutput
            ExitCode = $LASTEXITCODE
        }
    }
}