我正在PowerShell中使用query user
命令来过滤内容,以使在服务器上断开连接超过2天的用户。
这是我的结果:
USERNAME SESSIONNAME ID状态IDLE TIME登录时间
a_admin 2 Disc 20 + 16:56 19.08.2015
b_admin 3光盘。 2015年12月10日
c_admin 4光盘5 + 22:33 24.08.2015
d_admin 5 Disc 17:47 17.12.2015
e_admin 6光盘101 + 18:58 02.09.2015
f_admin 7光盘1 + 01:27 14.12.2015
问题是query user
不会以对象格式检索数据,因此我无法从这些数据中选择任何列,任何人都可以帮助我找到一种过滤此内容的方法吗?另外,我在空闲时间的内容上有问题。似乎很奇怪!
我试图将输出放入文本文件中,然后取回内容并进行一些过滤,但结果是相同的(带有空记录的USERNAME
)。
最佳答案
query user
产生字符串输出。您无法通过将其通过管道传递到Format-Table
来将其转换为对象。无论如何,Select-Object
不会与Format-Table
的输出一样。
使用正则表达式匹配将字符串输出转换为对象列表:
$server = 'servername'
$re = '(\w+)\s+?(\S*)\s+?(\d+)\s+Disc\s+(\S+)\s+(\d+\.\d+\.\d+)'
query user /server:$server | Where-Object { $_ -match $re } | ForEach-Object {
New-Object -Type PSCustomObject -Property @{
'Username' = $matches[1]
'SessionID' = $matches[3]
'IdleTime' = $matches[4]
'LogonTime' = $matches[5]
}
} | Select-Object Username, IdleTime
但是,这将为您提供所有内容作为字符串值。由于要过滤空闲时间,因此可能需要将值转换为适当的类型。使用更精细的正则表达式(带有命名组)将对此有所帮助。
$server = 'servername'
$re = '(?<username>\w+)\s+?' +
'(\S*)\s+?' +
'(?<session>\d+)\s+' +
'Disc\s+' +
'(?:(?:(?<days>\d+)\+)?(?<hours>\d+):)?(?<minutes>\d+)\s+' +
'(?<logon>\d+\.\d+\.\d+)'
query user /server:$server | Where-Object { $_ -match $re } | ForEach-Object {
New-Object -Type PSCustomObject -Property @{
'Username' = $matches['username']
'SessionID' = [int]$matches['session']
'IdleTime' = if ($matches['days']) {
New-TimeSpan -Days $matches['days'] -Hours $matches['hours'] -Minutes $matches['minutes']
} elseif ($matches['hours']) {
New-TimeSpan -Hours $matches['hours'] -Minutes $matches['minutes']
} else {
New-TimeSpan -Minutes $matches['minutes']
}
'LogonTime' = [DateTime]::ParseExact($matches['logon'], 'dd\.MM\.yyyy', [Globalization.CultureInfo]::InvariantCulture)
}
} | Where-Object {
$_.IdleTime.TotalDays -gt 2
} | Select-Object Username, IdleTime