我正在使用PowerShell中的query user
命令来过滤内容,以便让在服务器上断开连接超过2天的用户。
这是我的结果:
USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME a_admin 2 Disc 20+16:56 19.08.2015 b_admin 3 Disc . 10.12.2015 c_admin 4 Disc 5+22:33 24.08.2015 d_admin 5 Disc 17:47 17.12.2015 e_admin 6 Disc 101+18:58 02.09.2015 f_admin 7 Disc 1+01:27 14.12.2015
问题是query user
不能将数据检索为对象格式,因此我无法从这些数据中选择任何列,任何人都可以帮我找到过滤此内容的方法吗?另外,我在空闲时间的内容方面遇到了问题。这看起来很奇怪!?
我尝试将输出放在一个文本文件中然后获取内容并进行一些过滤,但结果是相同的(USERNAME
有空记录)。
答案 0 :(得分:6)
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