Powershell Get Active вошел в систему пользователя на локальном компьютере

10154
Reddy

Я пытаюсь получить в настоящее время вошли пользователей, которые имеют активный сеанс.

В диспетчере задач список предельно ясен: есть два пользовательских сеанса и один активный.

Я хочу запросить то же самое через Powershell. Я попробовал несколько доступных команд, в Get-WmiObject Win32_LoggedOnUser | Select Antecedent -Uniqueкоторых перечислено гораздо больше пользователей, чем я могу видеть [компьютер, присоединенный к домену]

Я ищу запрос, который может дать результаты точно так же, как диспетчер задач. enter image description here

2
Как насчет `запроса пользователя`? duenni 7 лет назад 0
@duenni кажется правильным. в любом случае разобрать и получить `Активные пользователи`. Похоже, это вывод строки Reddy 7 лет назад 0
Может быть, это может помочь вам http://superuser.com/q/587737/378809 duenni 7 лет назад 0
AFAIK, через PowerShell нет собственного пути, я искал его в прошлом. См. [Powershell получает значение от «пользователь запроса», а не от заголовков и т. Д.] (Http://superuser.com/questions/587737/powershell-get-a-value-from-query-user-and-not-the- заголовки и т.д.-? noredirect = 1 & LQ = 1) Ƭᴇcʜιᴇ007 7 лет назад 0
@MagicallyDelicous, на самом деле я пытаюсь выполнить некоторые сценарии на удаленном компьютере с помощью удаленного PowerShell. Если нет активного пользователя, я пытаюсь перезагрузить компьютер. Reddy 7 лет назад 0
Reddy - Готовься, когда придет время для спагетти, и напомни мне, чтобы я взял мой мачете, чтобы я мог порубить, порубить, порубить ... психику ... Какой статус на этом? Вы тоже читали мои комментарии? Pimp Juice IT 7 лет назад 0
@MagicallyDelicous Я сделал это по-другому http://stackoverflow.com/questions/42711592/getting-the-logged-in-user-in-powershell Это работает на всех машинах и не зависит от языка и дает правильные результаты Reddy 7 лет назад 0
О, так вы использовали некоторый код C # в PS с `Add-Type` ... это было мое второе предположение ... ** НЕ ** !! Pimp Juice IT 7 лет назад 0

3 ответа на вопрос

2
omniomi

Проблема в Get-WmiObject Win32_LoggedOnUser | Select Antecedent -Uniqueтом, что он показывает все сеансы, даже те, которые были закрыты с момента последней перезагрузки компьютера. К сожалению, самый простой способ опроса сеансов - использовать старый исполняемый файл query.exe.

Вы можете преобразовать выходные данные query.exe в объекты, используя немного регулярных выражений:

$Computer = $env:COMPUTERNAME $Users = query user /server:$Computer 2>&1  $Users = $Users | ForEach-Object { (($_.trim() -replace ">" -replace "(?m)^([A-Za-z0-9])\s+(\d\s+\w+)", '$1 none $2' -replace "\s", "," -replace "none", $null)) } | ConvertFrom-Csv  foreach ($User in $Users) { [PSCustomObject]@{ ComputerName = $Computer Username = $User.USERNAME SessionState = $User.STATE.Replace("Disc", "Disconnected") SessionType = $($User.SESSIONNAME -Replace '#', '' -Replace "[0-9]+", "") }  } 

Который даст вам вывод, как это:

ComputerName Username SessionState SessionType ------------ -------- ------------ ----------- BSMITH-LT bobsm Active console  

Возьмем это намного дальше к функции:

function Convert-QueryToObjects { [CmdletBinding()] [Alias('QueryToObject')] [OutputType([PSCustomObject])] param ( [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)] [Alias('ComputerName', 'Computer')] [string] $Name = $env:COMPUTERNAME )  Process { Write-Verbose "Running query.exe against $Name." $Users = query user /server:$Name 2>&1  if ($Users -like "*No User exists*") { # Handle no user's found returned from query. # Returned: 'No User exists for *' Write-Error "There were no users found on $Name : $Users" Write-Verbose "There were no users found on $Name." } elseif ($Users -like "*Error*") { # Handle errored returned by query. # Returned: 'Error ...<message>...' Write-Error "There was an error running query against $Name : $Users" Write-Verbose "There was an error running query against $Name." } elseif ($Users -eq $null -and $ErrorActionPreference -eq 'SilentlyContinue') { # Handdle null output called by -ErrorAction. Write-Verbose "Error action has supressed output from query.exe. Results were null." } else { Write-Verbose "Users found on $Name. Converting output from text."  # Conversion logic. Handles the fact that the sessionname column may be populated or not. $Users = $Users | ForEach-Object { (($_.trim() -replace ">" -replace "(?m)^([A-Za-z0-9])\s+(\d\s+\w+)", '$1 none $2' -replace "\s", "," -replace "none", $null)) } | ConvertFrom-Csv  Write-Verbose "Generating output for $($Users.Count) users connected to $Name."  # Output objects. foreach ($User in $Users) { Write-Verbose $User if ($VerbosePreference -eq 'Continue') { # Add '| Out-Host' if -Verbose is tripped. [PSCustomObject]@{ ComputerName = $Name Username = $User.USERNAME SessionState = $User.STATE.Replace("Disc", "Disconnected") SessionType = $($User.SESSIONNAME -Replace '#', '' -Replace "[0-9]+", "") } | Out-Host } else { # Standard output. [PSCustomObject]@{ ComputerName = $Name Username = $User.USERNAME SessionState = $User.STATE.Replace("Disc", "Disconnected") SessionType = $($User.SESSIONNAME -Replace '#', '' -Replace "[0-9]+", "") } } } } } } 

и теперь вы можете делать такие вещи, как: Get-ADComputer -Filter | Convert-QueryToObjects | ? {$_.SessionState -eq 'Active'}

единственная проблема. `Quser` возвращает вывод на местном языке. Это будет проблемой, если вы захотите работать на удаленных машинах, у которых может быть другой язык Reddy 7 лет назад 0
Вы можете изменить функцию для работы с разными языками, но, к сожалению, нет реальных альтернативных способов получения необходимой информации. Единственный жизнеспособный чистый метод PowerShell - это проверка запуска процессов explorer.exe на удаленной машине, но это не делает различий между активными и отключенными сеансами. Тем не менее, сейчас самое время подумать о стандартизации языка установки ваших серверов и о том, чтобы пользователи использовали Set-WinUILanguageOverride для своих личных нужд языка пользовательского интерфейса. omniomi 7 лет назад 0
1
js2010

Вот как я это делаю. Это не работает для сеансов RDP, хотя.

$out = query session | where {$_ -match 'console'} $array = $out -split('\s+') $consoleuser = $array[1] 

Или же:

$consoleuser = query session | select-string console | foreach { -split $_ } |  select -index 1 
-1
s0mm3r

это можно сделать с помощью:

get-wmiobject -Class Win32_Computersystem | выберите имя пользователя

С уважением

Это дает мне пустой результат, когда я выполняю на удаленной машине из RDP :( Reddy 7 лет назад 0
запрос wmi получает только локальную подписку для пользователей, чтобы получить сеансы rdp, попробуйте "qwinsta". Вот скрипт, который я получил с помощью одного поиска в Google https://gallery.technet.microsoft.com/scriptcenter/PowerShell-script-to-Find -d2ba4252 s0mm3r 7 лет назад 1