1

Задача, получить идентификатор из команды запроса пользователя, я пытаюсь получить значение идентификатора из команды «запрос пользователя»,

Example:PS>  query user

 USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME

>administrator         rdp-tcp#0           3  Active          .  04/25/2013 08:43

Я пытаюсь использовать psexec и присоединиться к сеансу.

psexec \\\pc -i sessionid somecommand

Как мне получить идентификатор и только идентификатор из вышеприведенного запроса? это то, что я пробовал до сих пор, между прочим ...

PS>  query user |Select-Object $_.ID

USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME

>administrator         rdp-tcp#0           3  Active          .  04/25/2013 08:43

Я думаю, это легко, но, видимо, у меня пердит мозг, в идеале мне нравится это делать:

$IDValue = query user | Get_the_ID_somehow

psexec \\\pc -i $IDValue somecommand..

заранее спасибо.

7 ответов7

3

Поскольку "пользователь запроса" не является объектом, вы не можете использовать его в качестве объекта в powershell, если вы не создадите пользовательский объект PSObject, поэтому

$ IDValue = запрос пользователя | Select-Object ID
не будет работать.

Я бы использовал что-то вроде этого:

$users = query user ;
$IDs = @() ;

for ($i=1; $i -lt $users.Count;$i++) {
  # using regex to find the IDs
  $temp = [string]($users[$i] | Select-String -pattern "\s\d+\s").Matches ;
  $temp = $temp.Trim() ;
  $IDs += $temp ;
}
1

Вот функция оболочки PowerShell для «запрос пользователя» / «quser». Он анализирует текстовый вывод и выдает фактические объекты PowerShell, которые вы можете запросить для отдельных интересующих вас атрибутов, таких как идентификатор сеанса.

Таким образом, вы можете делать такие вещи, как:

$IDValue = Get-LoggedInUser -ComputerName server1 | where { $_.username -eq 'administrator' } | select-object -ExpandProperty id

Вот код функции:

function Get-LoggedInUser
{
<#
    .SYNOPSIS
        Shows all the users currently logged in

    .DESCRIPTION
        Shows the users currently logged into the specified computernames

    .PARAMETER ComputerName
        One or more computernames

    .EXAMPLE
        PS C:\> Get-LoggedInUser
        Shows the users logged into the local system

    .EXAMPLE
        PS C:\> Get-LoggedInUser -ComputerName server1,server2,server3
        Shows the users logged into server1, server2, and server3

    .EXAMPLE
        PS C:\> Get-LoggedInUser  | where idletime -gt "1.0:0" | ft
        Get the users who have been idle for more than 1 day.  Format the output
        as a table.

        Note the "1.0:0" string - it must be either a system.timespan datatype or
        a string that can by converted to system.timespan.  Examples:
            days.hours:minutes
            hours:minutes
#>

    [CmdletBinding()]
    param
    (
        [ValidateNotNullOrEmpty()]
        [String[]]$ComputerName = $env:COMPUTERNAME
    )

    $out = @()

    ForEach ($computer in $ComputerName)
    {
        try { if (-not (Test-Connection -ComputerName $computer -Quiet -Count 1 -ErrorAction Stop)) { Write-Warning "Can't connect to $computer"; continue } }
        catch { Write-Warning "Can't test connect to $computer"; continue }

        $quserOut = quser.exe /SERVER:$computer 2>&1
        if ($quserOut -match "No user exists")
        { Write-Warning "No users logged in to $computer";  continue }

        $users = $quserOut -replace '\s{2,}', ',' |
        ConvertFrom-CSV -Header 'username', 'sessionname', 'id', 'state', 'idleTime', 'logonTime' |
        Add-Member -MemberType NoteProperty -Name ComputerName -Value $computer -PassThru

        $users = $users[1..$users.count]

        for ($i = 0; $i -lt $users.count; $i++)
        {
            if ($users[$i].sessionname -match '^\d+$')
            {
                $users[$i].logonTime = $users[$i].idleTime
                $users[$i].idleTime = $users[$i].STATE
                $users[$i].STATE = $users[$i].ID
                $users[$i].ID = $users[$i].SESSIONNAME
                $users[$i].SESSIONNAME = $null
            }

            # cast the correct datatypes
            $users[$i].ID = [int]$users[$i].ID

            $idleString = $users[$i].idleTime
            if ($idleString -eq '.') { $users[$i].idleTime = 0 }

            # if it's just a number by itself, insert a '0:' in front of it. Otherwise [timespan] cast will interpret the value as days rather than minutes
            if ($idleString -match '^\d+$')
            { $users[$i].idleTime = "0:$($users[$i].idleTime)" }

            # if it has a '+', change the '+' to a colon and add ':0' to the end
            if ($idleString -match "\+")
            {
                $newIdleString = $idleString -replace "\+", ":"
                $newIdleString = $newIdleString + ':0'
                $users[$i].idleTime = $newIdleString
            }

            $users[$i].idleTime = [timespan]$users[$i].idleTime
            $users[$i].logonTime = [datetime]$users[$i].logonTime
        }
        $users = $users | Sort-Object -Property idleTime
        $out += $users
    }
    Write-Output $out
}
1

Мне нужно было то же самое сегодня, так что вот как я это решил:

function Get-TSSessions {
    param(
        $ComputerName = "localhost"
    )

    query user /server:$ComputerName |
    #Parse output
    ForEach-Object {
        # trim spaces at beginning and end
        $_ = $_.trim() 
        # insert , at specific places for ConvertFrom-CSV command
        $_ = $_.insert(22,",").insert(42,",").insert(47,",").insert(56,",").insert(68,",")
        # Remove every space two or more spaces
        $_ = $_ -replace "\s\s+",""
        # for debug purposes, comment out above row and uncomment row below
        #$_ = $_ -replace "\s","_"

        # output to pipe
        $_

    } |
    #Convert to objects
    ConvertFrom-Csv
}

Если вы сейчас запустите Get-TSSessions, он возвращает массив объектов для каждого пользователя, который понимает Powershell.

Вот пример, который показывает, какие отключенные пользователи работают с chrome.exe:

foreach ($user in GET-TSSessions)
{

    if($user.state -ne "Active")
    {   #User is not active
        $user
        tasklist /FI '"USERNAME eq '$user.USERNAME'"' /FI "IMAGENAME eq chrome.exe"
    }
    else
    {
        "User "+$user.USERNAME+" is currently active."
    }

}
0

если у вас PowerShell 4.0+, вы можете запустить Get-RDUserSession на ConnectionBroker (PowerShell должен быть запущен от имени администратора):

Get-RDUserSession | Select-Object UnifiedSessionID

использовать Get-RDUserSession | Format-List * чтобы увидеть все свойства, которые вы можете выбрать

Так что нет необходимости в пользовательской функции

0
$userlock = Read-Host "Enter user"
$serverlock = Read-Host "Enter server"
$quserlock = quser /server $serverlock | Select-String -CaseSensitive $userlock
$quserlock
$quserlock1 = ($quserlock -split ' +') | Select-String -NotMatch "rdp-tcp"
$quserlock2 = ($quserlock1 -split ' +') | Select-String -NotMatch $userlock
$quserlock3 = $quserlock2[1]
$quserlock3
logoff $quserlock3.Line /server $serverlock
quser /server $serverlock
-1

Функция Get-LoggedInUser должна использовать ParseExact() для исправления ошибки: «Строка не была распознана как допустимый DateTime».

$users[$i].logonTime = [datetime]::ParseExact($users[$i].logonTime, "dd/MM/yyyy HH:mm", $null)
-1

Я считаю, что вы ищете $IDValue = query user | Select-Object ID

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .