我目前在PowerShell中有以下查询:
query user /server:$server
返回输出:
USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME
svc_chthost 2 Disc 1:05 8/16/2016 12:01 PM
myusername rdp-tcp 3 Active . 8/29/2016 11:29 AM
目前,我使用@(query user /server:$server).Count - 1
作为值来表示登录的用户数量(我知道这不是很好)。但是现在我想获取USERNAME
,ID
和LOGON TIME
等信息,以便在我的脚本的其他部分中使用。
我的问题是围绕一种更简单的方法来解析上面的信息,或者更好地解决我的问题:统计和收集与登录用户相关的信息。
我发现其他似乎更好的解决方案,但我确信必须有一种更简单的方法来完成这项任务:
$ComputerName | Foreach-object {
$Computer = $_
try
{
$processinfo = @(Get-WmiObject -class win32_process -ComputerName $Computer -EA "Stop")
if ($processinfo)
{
$processinfo | Foreach-Object {$_.GetOwner().User} |
Where-Object {$_ -ne "NETWORK SERVICE" -and $_ -ne "LOCAL SERVICE" -and $_ -ne "SYSTEM"} |
Sort-Object -Unique |
ForEach-Object { New-Object psobject -Property @{Computer=$Computer;LoggedOn=$_} } |
Select-Object Computer,LoggedOn
}#If
}
catch
{
}
答案 0 :(得分:2)
用于收集信息。
基于https://ss64.com/nt/query-user.html
$result = &quser
$result -replace '\s{2,}', ',' | ConvertFrom-Csv
答案 1 :(得分:1)
评论中有很多引用,并且仍然可以获得更多这个问题的答案,因为它应该有一个更简单的解决方案!
foreach ($s in $servers) #For Each Server
{
foreach($ServerLine in @(query user /server:$s) -split "\n") #Each Server Line
{
#USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME
$Parsed_Server = $ServerLine -split '\s+'
$Parsed_Server[1] #USERNAME
$Parsed_Server[2] #SESSIONNAME
$Parsed_Server[3] #ID
$Parsed_Server[4] #STATE
$Parsed_Server[5] #IDLE TIME
$Parsed_Server[6] #LOGON TIME
}
}
这个解决方案现在解决了这个问题,有点草率。
有关更多功能的更深入的解决方案,请查看原始问题的评论:)
答案 2 :(得分:0)
老问题,但似乎可行的解决方案:
(query user) -split "\n" -replace '\s\s+', ';' | convertfrom-csv -Delimiter ';'
与上面的答案一样,这会将输出分成几行,但是用分号替换了多个空格字符(\ s \ s +),然后使用分号将csv的输出转换为分隔符。
出现多个空格的原因是列标题中有空格(空闲时间,登录时间),因此只有一个空格时,它将试图将其解释为多列。从命令的输出来看,好像它们始终始终在项目之间保留至少2个空格,并且登录时间列在字段中也有空格。
答案 3 :(得分:0)
pip install somemodule
答案 4 :(得分:0)
我自己的专栏文章。我不确定ID列可以向左延伸多少。不确定结局有多宽。事实证明这很棘手。也许这样更好:Convert fixed width txt file to CSV / set-content or out-file -append?
# q.ps1
# USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME
# js1111 rdp-tcp#20 136 Active . 6/20/2020 4:26 PM
# jx111 175 Disc . 6/23/2020 1:26 PM
# sm1111 rdp-tcp#126 17 Active . 6/23/2020 1:13 PM
#
# di111111 rdp-tcp#64 189 Active 33 7/1/2020 9:50 AM
# kp111 rdp-tcp#45 253 Active 1:07 7/1/2020 9:43 AM
#
#0, 1-22, 23-40, 41-45, 46-53, 54-64, 65-80/82
$q = quser 2>$null | select -skip 1
$q | foreach {
$result = $_ -match '.(.{22})(.{18})(.{5})(.{8})(.{11})(.{16,18})'
[pscustomobject] @{
USERNAME = $matches[1].trim()
SESSIONNAME = $matches[2].trim()
ID = [int]$matches[3].trim()
STATE = $matches[4].trim()
IdleTime = $matches[5].trim()
LogonTime = [datetime]$matches[6].trim()
}
if (! $matches) {$_}
}
调用命令示例。如果您正在使用鳄梨调味酱,那就很好了。
$c = get-credential
icm comp1,comp2,comp3 q.ps1 -cr $c | ft
USERNAME SESSIONNAME ID STATE IdleTime LogonTime PSComputerName RunspaceId
-------- ----------- -- ----- -------- --------- -------------- ----------
js1 136 Disc . 6/20/2020 4:26:00 PM comp1 a8e670cd-4f31-4fd0-8cab-8aa11ee75a73
js2 137 Disc . 6/20/2020 4:26:00 PM comp2 a8e670cd-4f31-4fd0-8cab-8aa11ee75a74
js3 138 Disc . 6/20/2020 4:26:00 PM comp3 a8e670cd-4f31-4fd0-8cab-8aa11ee75a75
答案 5 :(得分:0)
已编辑:看起来有人已经创建了一个实际上运行良好的脚本:https://gallery.technet.microsoft.com/scriptcenter/Get-LoggedOnUser-Gathers-7cbe93ea
不能相信,这么多年以后,仍然没有原生的PowerShell。
我已经整理了Tyler Dickson所做的事情,并确保结果以PSCustomObject的形式返回
$Servers = @("10.x.x.x", "10.y.y.y")
$Result = @()
foreach ($Server in $Servers) {
$Lines = @(query user /server:$s) -split "\n"
foreach($Line in $Lines) #Each Server Line
{
if ($Line -match "USERNAME\s+SESSIONNAME\s+ID\s+STATE\s+IDLE TIME\s+LOGON TIME") {
continue # If is the header then skip to next item in array
}
$Parsed_Server = $Line -split '\s+'
$Result += [PSCustomObject]@{
SERVER = $Server
USERNAME = $Parsed_Server[1]
SESSIONNAME = $Parsed_Server[2]
ID = $Parsed_Server[3]
STATE = $Parsed_Server[4]
IDLE_TIME = $Parsed_Server[5]
LOGON_TIME = $Parsed_Server[6]
}
}
}
$Result | Format-Table
示例输出:
SERVER USERNAME SESSIONNAME ID STATE IDLE_TIME LOGON_TIME
------ -------- ----------- -- ----- --------- ----------
10.x.x.x user01 rdp-tcp#13 6 Active . 28/06/2020
10.x.x.x user02 rdp-tcp#35 11 Active 59 29/06/2020
10.y.y.y user03 rdp-tcp#38 12 Active . 29/06/2020
10.y.y.y user04 rdp-tcp#43 14 Active 5 29/06/2020
答案 6 :(得分:0)
$result = (&quser) -replace '\s{2,}', ',' | ConvertFrom-Csv | Select -ExpandProperty USERNAME
$loggedinuser = $result.Trim(">")
答案 7 :(得分:-1)
我进一步添加了上述代码以正确格式化并考虑了断开连接的用户
$HaSH = @()
foreach($ServerLine in @(query user) -split "\n") {
$Report = "" | Select-Object UserName, Session, ID, State, IdleTime, LogonTime
$Parsed_Server = $ServerLine -split '\s+'
if($Parsed_Server -like "USERNAME*") {
Continue
}
$Report.UserName = $Parsed_Server[1]
$Report.Session = $Parsed_Server[2]
$Report.ID = $Parsed_Server[3]
$Report.State = $Parsed_Server[4]
$Report.IdleTime = $Parsed_Server[5]
$Report.LogonTime = $Parsed_Server[6]+" " +$Parsed_Server[7]+" "+$Parsed_Server[8]
if($Parsed_Server[3] -eq "Disc") {
$Report.Session = "None"
$Report.ID = $Parsed_Server[2]
$Report.State = $Parsed_Server[3]
$Report.IdleTime = $Parsed_Server[4]
$Report.LogonTime = $Parsed_Server[5]+" " +$Parsed_Server[6]+" "+$Parsed_Server[7]
}
if($Parsed_Server -like ">*") {
$Parsed_Server=$Parsed_Server.Replace(">","")
$Report.UserName = $Parsed_Server[0]
$Report.Session = $Parsed_Server[1]
$Report.ID = $Parsed_Server[2]
$Report.State = $Parsed_Server[3]
$Report.IdleTime = $Parsed_Server[4]
$Report.LogonTime = $Parsed_Server[5]+" " +$Parsed_Server[6]+" "+$Parsed_Server[7]
}
$HaSH+=$Report
}