Powershell รับค่าจาก 'ผู้ใช้แบบสอบถาม' ไม่ใช่ส่วนหัว ฯลฯ


1

ภารกิจรับ ID จากคำสั่งผู้ใช้แบบสอบถามฉันพยายามรับค่า ID จากคำสั่ง 'ผู้ใช้แบบสอบถาม'

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

ฉันจะไปเกี่ยวกับการรับ ID และ ID จากแบบสอบถามด้านบนได้อย่างไร นี่คือสิ่งที่ฉันได้ลองไปแล้วเหนือสิ่งอื่นใด ...

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..

ขอบคุณล่วงหน้า.


คุณ migtt ดูคำถามที่เกี่ยวข้องบ้างที่นี่ serverfault.com/questions/347723/…
Zoredache

มีประโยชน์ แต่ฉันยังไม่สามารถรับ ID จากผลลัพธ์ได้
user219872

@Zoredache ฉันคิดว่าฉันควรใช้ 'ผู้ใช้แบบสอบถาม' แล้วฉันจะมีหนึ่งบรรทัดในการแยกวิเคราะห์
user219872

สิ่งนี้สามารถใช้งานได้ $ s = ผู้ใช้คิวรี $ id = $ s [1] .Substring (39,5)
user219872

คำตอบ:


3

เนื่องจาก "ผู้ใช้แบบสอบถาม" ไม่ใช่วัตถุที่คุณไม่สามารถใช้เป็นวัตถุใน PowerShell เว้นแต่ว่าคุณจะสร้าง PSObject ที่กำหนดเองดังนั้น

$ IDValue = ผู้ใช้แบบสอบถาม | รหัสวัตถุที่เลือก
จะไม่ทำงาน

ฉันจะใช้สิ่งนี้:

$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 ;
}

2

วันนี้ฉันต้องการสิ่งเดียวกันดังนั้นนี่คือวิธีแก้ไข:

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."
    }

}

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
}

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
แม้ว่าสิ่งนี้อาจตอบคำถามได้ แต่มันจะเป็นคำตอบที่ดีกว่าถ้าคุณสามารถให้คำอธิบายได้ว่าทำไมถึงเป็นเช่นนั้น
DavidPostill

0

หากคุณมี PowerShell 4.0+ คุณสามารถเรียกใช้Get-RDUserSessionบน ConnectionBroker (ต้องเริ่ม PowerShell ในฐานะผู้ดูแลระบบ):

Get-RDUserSession | Select-Object UnifiedSessionID

ใช้Get-RDUserSession | Format-List *เพื่อดูคุณสมบัติทั้งหมดที่คุณสามารถเลือกได้

ดังนั้นไม่จำเป็นต้องใช้ฟังก์ชั่นที่กำหนดเอง


-1

ฉันเชื่อว่าคุณกำลังมองหา $IDValue = query user | Select-Object ID


ผู้ใช้แบบสอบถามเซสชันการสืบค้น qwinsta.exe จะไม่ส่งคืนวัตถุ PowerShell เพียงแสดงผลลัพธ์ของคอนโซล คุณจะต้องแยกวิเคราะห์
sonjz

-1

ฟังก์ชันGet-LoggedInUserควรใช้ParseExact()เพื่อแก้ไขข้อผิดพลาด: "ไม่รู้จักสายอักขระเป็น DateTime ที่ถูกต้อง"

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

สิ่งนี้ดูเหมือนจะถูกส่งมาโดยไม่ได้ตั้งใจเป็นคำตอบสำหรับคำถามนี้ โปรดพิจารณาแก้ไขคำถามของคุณเพื่อให้ตอบคำถามของผู้เขียนโดยตรง
Ramhound
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.