Powershell Ative o usuário logado no computador local

2

Estou tentando fazer com que os usuários conectados no momento tenham sessões ativas.

No gerenciador de tarefas, a lista é clara de que há duas sessões de usuário e uma está ativa.

Eu quero consultar o mesmo via Powershell. Eu tentei alguns dos comandos disponíveis Get-WmiObject Win32_LoggedOnUser | Select Antecedent -Unique que lista muito mais usuários do que eu posso ver [o domínio entrou no computador]

Eu estou procurando a consulta que pode dar resultados exatamente como o Gerenciador de Tarefas.

    
por Reddy 08.03.2017 / 16:44

3 respostas

2

O problema com Get-WmiObject Win32_LoggedOnUser | Select Antecedent -Unique é que ele mostra todas as sessões, mesmo aquelas que foram fechadas desde a última vez em que o computador foi reinicializado. A maneira mais fácil de pesquisar sessões infelizmente está usando o antigo executável query.exe.

Você pode converter a saída de query.exe em objetos usando um pouco de regex:

$Computer = $env:COMPUTERNAME
$Users = query user /server:$Computer 2>&1

$Users = $Users | ForEach-Object {
    (($_.trim() -replace ">" -replace "(?m)^([A-Za-z0-9]{3,})\s+(\d{1,2}\s+\w+)", '$1  none  $2' -replace "\s{2,}", "," -replace "none", $null))
} | ConvertFrom-Csv

foreach ($User in $Users)
{
    [PSCustomObject]@{
        ComputerName = $Computer
        Username = $User.USERNAME
        SessionState = $User.STATE.Replace("Disc", "Disconnected")
        SessionType = $($User.SESSIONNAME -Replace '#', '' -Replace "[0-9]+", "")
    } 
}

O que lhe dará uma saída assim:

ComputerName Username SessionState SessionType
------------ -------- ------------ -----------
BSMITH-LT    bobsm    Active       console    

Levando mais longe para uma função:

function Convert-QueryToObjects
{
    [CmdletBinding()]
    [Alias('QueryToObject')]
    [OutputType([PSCustomObject])]
    param
    (
        [Parameter(Mandatory = $false,
                   ValueFromPipeline = $true,
                   ValueFromPipelineByPropertyName = $true,
                   Position = 0)]
        [Alias('ComputerName', 'Computer')]
        [string]
        $Name = $env:COMPUTERNAME
    )

    Process
    {
        Write-Verbose "Running query.exe against $Name."
        $Users = query user /server:$Name 2>&1

        if ($Users -like "*No User exists*")
        {
            # Handle no user's found returned from query.
            # Returned: 'No User exists for *'
            Write-Error "There were no users found on $Name : $Users"
            Write-Verbose "There were no users found on $Name."
        }
        elseif ($Users -like "*Error*")
        {
            # Handle errored returned by query.
            # Returned: 'Error ...<message>...'
            Write-Error "There was an error running query against $Name : $Users"
            Write-Verbose "There was an error running query against $Name."
        }
        elseif ($Users -eq $null -and $ErrorActionPreference -eq 'SilentlyContinue')
        {
            # Handdle null output called by -ErrorAction.
            Write-Verbose "Error action has supressed output from query.exe. Results were null."
        }
        else
        {
            Write-Verbose "Users found on $Name. Converting output from text."

            # Conversion logic. Handles the fact that the sessionname column may be populated or not.
            $Users = $Users | ForEach-Object {
                (($_.trim() -replace ">" -replace "(?m)^([A-Za-z0-9]{3,})\s+(\d{1,2}\s+\w+)", '$1  none  $2' -replace "\s{2,}", "," -replace "none", $null))
            } | ConvertFrom-Csv

            Write-Verbose "Generating output for $($Users.Count) users connected to $Name."

            # Output objects.
            foreach ($User in $Users)
            {
                Write-Verbose $User
                if ($VerbosePreference -eq 'Continue')
                {
                    # Add '| Out-Host' if -Verbose is tripped.
                    [PSCustomObject]@{
                        ComputerName = $Name
                        Username = $User.USERNAME
                        SessionState = $User.STATE.Replace("Disc", "Disconnected")
                        SessionType = $($User.SESSIONNAME -Replace '#', '' -Replace "[0-9]+", "")
                    } | Out-Host
                }
                else
                {
                    # Standard output.
                    [PSCustomObject]@{
                        ComputerName = $Name
                        Username = $User.USERNAME
                        SessionState = $User.STATE.Replace("Disc", "Disconnected")
                        SessionType = $($User.SESSIONNAME -Replace '#', '' -Replace "[0-9]+", "")
                    }
                }
            }
        }
    }
}

e agora você pode fazer coisas como: Get-ADComputer -Filter {Name -like "SERVER*"} | Convert-QueryToObjects | ? {$_.SessionState -eq 'Active'}

    
por 10.03.2017 / 15:12
1

Veja como eu faço isso. Não funciona para sessões de rdp.

$out = query session | where {$_ -match 'console'}
$array = $out -split('\s+')
$consoleuser = $array[1]

Ou:

$consoleuser = query session | select-string console | foreach { -split $_ } | 
  select -index 1
    
por 15.03.2017 / 20:26
-1

isso pode ser feito com:

get-wmiobject -Class Win32_Computersystem | select Username

considera

    
por 08.03.2017 / 16:50