![Powershell 从“查询用户”获取值,而不是标题等](https://linux22.com/image/1361104/Powershell%20%E4%BB%8E%E2%80%9C%E6%9F%A5%E8%AF%A2%E7%94%A8%E6%88%B7%E2%80%9D%E8%8E%B7%E5%8F%96%E5%80%BC%EF%BC%8C%E8%80%8C%E4%B8%8D%E6%98%AF%E6%A0%87%E9%A2%98%E7%AD%89.png)
任务,从查询用户命令中获取 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..
提前致谢。
答案1
由于“查询用户”不是一个对象,除非你构造一个自定义 PSObject,否则你不能在 powershell 中将其用作对象,所以
$IDValue = query user | 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 ;
}
答案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."
}
}
答案3
这是用于“查询用户”/“quser”的 PowerShell 包装函数。它解析文本输出并为您提供实际的 PowerShell 对象,您可以查询您感兴趣的各个属性,例如会话 ID。
因此你可以做如下事情:
$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
}
答案4
如果你有 PowerShell 4.0+,你可以运行获取 RDUserSession在 ConnectionBroker 上(PowerShell 必须以管理员身份启动):
Get-RDUserSession | Select-Object UnifiedSessionID
使用Get-RDUserSession | Format-List *
查看您可以选择的所有属性
因此不需要自定义函数