Представим ситуацию, что на одном из пользовательских компьютеров или серверов был найден сервис, который относится к устаревшим приложению или является подозрительным с точки зрения безопасности. В этой статье будет рассмотрен пример поиска такого сервиса на всех компьютерах AD с Powershell.
Получение списка сервисов
Получить список всех сервисов, на локальном ПК, мы можем использовав следующую команду:
Get-Service
Что бы найти конкретный сервис мы можем указать точное или приблизительное имя:
# Точный поиск
Get-Service -Name 'WinRM'
# Поиск с использованием маски
Get-Service -Name '*Win*RM*'
Использование имение '*Win*RM*' ищет соответствия, где в начале и конце могут быть еще символы, а так же посередине. То есть строка 'Microsoft Windows RM v2' тоже бы подошла, так как в ней встречается и 'Win' и 'RM'.
Далее нам нужно выбрать способ для удаленного обращения к компьютерам. Мы можем использовать метод самого командлета Get-Service либо отдельную команду Invoke-Command. Обе команды, как минимум, будут нуждаться в запущенной службе WinRM, а пользователь должен обладать нужными правами (администратором).
В обеих командах мы можем перечислить несколько имен ПК сразу. В варианте с Get-Service имена компьютеров указываются после параметра -ComputerName. Отмечу, что использование IP адресов не самый лучший вариант для таких команд, так как будет использоваться NTLM, а не Kerberos (вариант с доменным именем):
Get-Service -ComputerName 'localhost','127.0.0.1' -Name '*Win*RM*'
Добавив для вывода свойство "MachineName" мы так же получим имена компьютеров:
$services = Get-Service -ComputerName 'localhost','127.0.0.1' -Name '*Win*RM*'
$services | Select-Object MachineName, Status, Name
Второй вариант использования - Invoke-Command. Плюс этой команды в том, что мы сразу можем использовать несколько команд на удаленном компьютере, а не по одной команде на каждом. Следующий пример аналогичен предыдущему:
Invoke-Command -ComputerName 'localhost','127.0.0.1' -ScriptBlock {Get-Service -Name '*Win*RM*'}
Если вы планируете использовать другого пользователя, то его можно объявить с командой Get-Credential и поместить в переменную:
$cred = Get-Credential
Такая переменная будет работать только с Invoke-Command:
Invoke-Command -ComputerName 'localhost', '127.0.0.1' -ScriptBlock {Get-Service -Name '*Win*RM*'} -Credential $cred
Как управлять службами в Powershell командлетами Service
Поиск сервисов на компьютерах AD
Список компьютеров мы можем получить выполнив команду Get-ADComputer. Эта команда будет доступна на сервере с AD или ПК с RSAT. Следующая команда вернет все ПК в Active Directory:
Get-ADComputer -Filter *
Что бы получить компьютеры из одной OU (организационной единицы) мы должны использовать определенный формат. Например мои компьютеры находятся в домене 'domain.local', а организационная единица называется Moscow:
Get-ADComputer -Filter * -SearchBase 'OU=Moscow,DC=domain,DC=local'
Что бы получить только имена компьютеров нужно обратиться к свойству Name:
(Get-ADComputer -Filter * -SearchBase 'OU=Moscow,DC=domain,DC=local').Name
Уточнить имя ПК можно добавив параметр Filter нужное свойство. Например мне нужны компьютеры с именами, где встречается цифра '5':
(Get-ADComputer -Filter {Name -like '*5*'} -SearchBase 'OU=Moscow,DC=domain,DC=local').Name
Теперь можно искать сервис на этих компьютерах:
$computers = (Get-ADComputer -Filter *).Name
Invoke-Command -ComputerName $computers -ScriptBlock {
Get-Service -Name '*Win*Rm*'
} -ErrorAction SilentlyContinue
Параметр '-ErrorAction SilentlyContinue' исключит ошибки связанные с выключенными компьютерами и не остановит выполнение скрипта. Это еще одно отличие от аналогичного способа с Get-Service, так как скрипт остановится при первой такой ошибке:
- Get-Service : Cannot open Service Control Manager on computer
Выгрузить такие данные можно, например, в CSV:
Get-Service -ComputerName $computers -Name '*Win*RM*' | Export-Csv -Path 'C:\services.csv' -NoTypeInformation
Получение списка компьютеров с Get-ADComputer в Powershell
...
Подписывайтесь на наш Telegram канал
Теги: #powershell #ad