Заметки · 27.03.2023

Проверка состояния службы

Помнится, уже был пост про удаление службы на хосте в домене (тык). Там я демонстрировал работу простого скрипта с обращением к удалённому компьютеру с помощью Get-WmiObject.

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

Требуется, чтобы код проверил доступность удалённого хоста, упомянутого в массиве $hosts, и — если он пингуется — вывел состояние службы, указанной в переменной $svcname (если она, конечно, есть).

Для начала я написал вот такую функцию:

function GetStatusService ($hostname, $servicename)
{
    $ping = Test-Connection -ComputerName $hostname -Quiet -Count 1
    if ($ping)
    {
        $status = Get-Service -ComputerName $hostname -Name $servicename -ErrorAction Ignore | select -ExpandProperty Status
        if ($status) { if ($status -eq "Running") { return $true } else { return $false } }
        else { $nfsvc="Service Not Found"; return $nfsvc }
    }
    else
    { $noping="Host Not Found"; return $noping }
}

GetStatusService проверяет доступность хоста, определяет статус службы и возвращает True (если служба запущена) или False (если служба в любом другом состоянии).

В случае, если служба отсутствует на хосте — функция вернёт Service Not Found. А Host Not Found вернётся, если командлет Test-Connection не смог получить ответ от хоста.

Обращение к функции:

GetStatusService -hostname "ИМЯ_ХОСТА" -servicename "ИМЯ СЛУЖБЫ"

Далее — добавил массив с именами хостов, переменную с названием службы и цикл для перебора массива. Итоговый код скрипта выглядит так:

$hosts = @("PC01", "PC02", "PC03", "PC04")
$svcname = "servicename"

function GetStatusService ($hostname, $servicename)
{
    $ping = Test-Connection -ComputerName $hostname -Quiet -Count 1
    if ($ping)
    {
        $status = Get-Service -ComputerName $hostname -Name $servicename -ErrorAction Ignore | select -ExpandProperty Status
        if ($status) { if ($status -eq "Running") { return $true } else { return $false } }
        else { $nfsvc="Service Not Found"; return $nfsvc }
    }
    else
    { $noping="Host Not Found"; return $noping }
}


foreach ($onehost in $hosts)
{
    $servicestatus = GetStatusService -hostname $onehost -servicename $svcname
    Write-Host "$onehost - $svcname - $servicestatus"
}

Всё, что в итоге требуется — это подставить свои названия хостов в массив $hosts и заменить название службы в переменной $svcname.

После отработки кода в консоль вернётся примерно такой ответ:

PC01 - servicename - Service Not Found
PC02 - servicename - False
PC03 - servicename - True
PC04 - servicename - Host Not Found

Теперь попробуем отобрать компьютеры из подразделения Active Directory и опросить их без использования каких-либо функций с использованием подручных командлетов прям из среды PowerShell ISE:

$ou = "OU=Unit,OU=PC,OU=Office,DC=org,DC=domain,DC=local"
$servicename = "DiagTrack" # <== Допустим такую службу ищем
$pclist = (Get-ADComputer -SearchBase $ou -filter * | where 'Enabled' -eq $True | Sort-Object -Property Name).Name
foreach($pc in $pclist)
{
    $ping = Test-Connection -ComputerName $pc -Count 1 -Quiet
    if ($ping)
    {
        $getservice = Get-Service -ComputerName $pc -Name $servicename -ErrorAction SilentlyContinue
        if ($getservice -eq $null)
        {
            Write-Host "$pc - Служба $servicename не найдена!" -ForegroundColor Yellow
        }
        else
        {
            $status = (Get-Service -ComputerName $pc -Name $servicename).Status
            Write-Host "$pc - Служба $servicename находится в состоянии $status" -ForegroundColor Green
        }
    }
    else
    {
        Write-Host "$pc недоступен!" -ForegroundColor Red
    }
}

В консоль непременно вернётся раскраска с данными.