Поиск активных сессий и залогиненных пользователей с Powershell


16 января 2020


Как найти залогиненых пользователей и активные сессии с Powershell

Иногда может понадобится проверить какие в данный момент залогинены в системе, то есть являются активными. Такую информацию можно использовать для аудита, например для проверки какие учетные записи за какими компьютерами сидят или для последующей перезагрузки сервера, что бы не останавливать работу коллег. В примерах ниже рассмотрено как выполнять удаленные команды для получения активных пользователей и возврата включенных пользователей Active Directory.

 

Получение имени залогиненного пользователя

Я не могу вспомнить готовую команду Powershell, которая бы вернула логин пользователя, но такая возможность есть через WMI:

Get-WmiObject -Class Win32_ComputerSystem | Select-Object UserName

Есть еще вариант использовать CIM, который может работать немного быстрее:

Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object UserName

Залогиненные пользователи с Win32_ComputerSystem и Win32_ComputerSystem

Обе команды могут работать удаленно если добавить атрибут ComputerName:

Get-WmiObject -ComputerName 'localhost' -Class Win32_ComputerSystem | Select-Object UserName

Получение активных сеансов в Powershell удаленно

Если вы планируете выполнять эти команды удаленно, то может понадобится выполнить предварительные настройки в виде открытия портов и необходимых правах.

Получить только имя пользователя можно так:

$userinfo = Get-WmiObject -ComputerName 'localhost' -Class Win32_ComputerSystem
$user = $userinfo.UserName -split '\\'
$user[1]

Получение имени залогиненного пользователя в Powershell удаленно

Как вы знаете в Winodws есть так же параллельные сеансы сервисов. Если вам нужно вернуть имена этих аккаунтов нужно использовать класс "win32_LoggedOnUser":

Get-CimInstance -ComputerName 'localhost' -Class win32_LoggedOnUser | ft

Получение всех активных сеансов пользователей в Powershell

 

Получение списка компьютеров

Если у вас нет списка компьютеров к которым вы планируете подключиться и узнать активного пользователя - это можно сделать через AD. На примере ниже будут возвращены все компьютеры:

Get-ADComputer -Filter *

Получение списка компьютеров в Powershell

Операция по получению списка компьютеров может быть очень долгой, если у вас большой парк ПК в AD. Вы можете вернуть только компьютеры, которые не отключены в AD (Disable) следующим способом:

Get-ADComputer -Filter * | where Enabled -eq $True

Получение включенных компьютеров AD в Powershell

Можно использовать и фильтрацию. Так я верну компьютеры имена которые начинаются на "CL":

Get-ADComputer -Filter {Name -like 'CL*'} | where Enabled -eq $True

Фильтрация списка компьютеров в Powershell

Получить список имен мы можем так:

$pc = Get-ADComputer -Filter {Name -like 'CL*'} | where Enabled -eq $True
$pc.Name

Фильтрация списка компьютеров в Powershell

Если у вас список компьютеров не относится к AD или имеет другой формат - то просто преобразуйте его в массив:

# Текст с именами компьютеров
$pc = 'Computer1,Computer2,Computer3'
# Преобразование в массив
$pc_array = $pc -split ','
$pc_array

Split в Powershell 

 

Удаленное получение залогиненных пользователей

Выше уже рассматривался вариант получения имени пользователя удаленно используя WMI и CIM. Если обе команды, то всех  пользователей активных в данный момент мы можем получить так:

# Текст с именами компьютеров
$computers = (Get-AdComputer -Filter *).Name
# Удаленное получение пользователей
foreach ($computer in $computers){
    Get-CimInstance -ComputerName $computer -ClassName Win32_ComputerSystem | Select-Object UserName
}

Такой подход может привести к ошибкам так как мы не проверяем включены ли компьютеры:

Обход ошибок в Powershell

Мы можем просто не выводить ошибки с помощью "-ErrorAction SilentlyContinue" или заранее пинговать (что было бы правильнее с точки зрения времени выполнения). В примере ниже я так же разбиваю имя компьютера и логин в более удобный формат:

# Текст с именами компьютеров
$computers = (Get-AdComputer -Filter *).Name
# Удаленное получение имен учетных записей
foreach ($computer in $computers){
    $result = Get-CimInstance -ComputerName $computer -ClassName Win32_ComputerSystem -ErrorAction SilentlyContinue
    $computer_login = $result.UserName -split '\\'
    if ($computer_login){
        Write-Host 'ComputerName: ' $computer_login[0]
        Write-Host 'UserName: ' $computer_login[1]
       }
}

Обход ошибок в Powershell с ErrorAction

Если вы не хотите выполнять команды удаленно через WMI, то вы можете использовать PSRemoting. От так же требует предварительных настроек, которые описаны в статье "Удаленное управление через Powershell". Команда, которая использует PSRemoting, будет выглядеть примерно так же:

# Текст с именами компьютеров
$computers = (Get-AdComputer -Filter *).Name
# Удаленное получение имен учетных записей
foreach ($computer in $computers){
    $result = Invoke-Command -ComputerName $computer `
          -ScriptBlock {
              Get-WMIObject -ClassName Win32_ComputerSystem `
                            -ErrorAction SilentlyContinue
                       } `
          -ErrorAction SilentlyContinue
    $computer_login = $result.UserName -split '\\'
    if ($computer_login){
        Write-Host 'ComputerName: ' $computer_login[0]
        Write-Host 'UserName: ' $computer_login[1]
       }
}

Получение списка активных сеансов пользователей в Powershell

 

Получение включенных пользователей AD

Если вам нужно вернуть учетные записи, которые включены в AD выполните следующую команду:

Get-AdUser -Filter * | where 'Enabled' -eq $True

Фильтрация включенных пользователей в AD с Powershell

Для возврата только отключенных учетных записей используйте $False.

Такой подход работает и с объектами компьютеров в AD:

Get-AdComputer -Filter * | where 'Enabled' -eq $False

Для последующей выгрузки данных в Excel почитайте статью "Как в Powershell выгрузить из AD пользователей и группы CSV".

 

Whoami или WMI

Вы можете вспомнить команду, которая так же возвращает имя пользователя:

whoami

whoami в Powershell

Как можно увидеть она вернет ту же информацию, что и класс WMI. Ситуация меняется, когда эти команды используются удаленно:

# Пользователь вошедший в Windows и открывший Powershell
whoami
# Пользователь, который будет удаленно подключатся через Powershell
$new_psuser = Get-Credential 'admin'
# Способ с whoami
Invoke-Command -ComputerName 'localhost' `
               -Credential $new_psuser `
               -ScriptBlock {whoami}
# Способ с WMI
Invoke-Command -ComputerName 'localhost' `
               -Credential $new_psuser `
               -ScriptBlock {(Get-WmiObject -Class Win32_ComputerSystem).UserName}

Разница WMI и whoami в Powershell

Как видно, в случае с whoami у нас вернулось имя учетной записи выполнившей команду Powershell, а с WMI пользователь Windows. 

...

Теги: #powershell #wmi #ad


Популярные тэги
О блоге
Этот блог представляет собой конспекты выученного материала, преобретенного опыта и лучшие практики в системном администрировании и программировании.