Не секрет, что служба Remote Desktop Connection Broker имеет встроенный механизм обнаружения нерабочих терминальных серверов. Параметры настраиваются через реестр в ветке самой службы (HKLM\SYSTEM\CurrentControlSet\services\Tssdis\Parameters).
Это не совсем удобно, тем более что сам механизм не всегда корректно отрабатывет, да и потом начинает он работать только в случае неудачного перенаправления сессии на неработающий терминальный сервер. Нам же необходимо немедленное реагирование. То есть если терминал перестал отвечать на эхо-запросы, то мы выполняем перезапуск службы.
Итак, пишем скрипт который будет делать следующее: поочередно посылать на каждый терминальный сервер два icmp-пакета Echo Request (ping), и в случае успеха записывать в файл-маркер Tssdis.log единицу, в противном случае ноль. Далее, пройдя все терминалы, происходит сравнение первоначальной структуры с получившейся путем банального подсчета и сравнения сумм. Если они отличаются, происходит перезапуск службы Tssdis с пометкой в файле-журнале Tssdis.restart.log. Во время запуска службы, механизм обнаружения не будет заносить в базу RD Connection Broker нерабочие терминальные серверы. Скрипт будет повторяться раз в минуту на самом сервере со службой Tssdis (в нашем примере количество терминалов-членов фермы равно двадцати пяти).
Import-Module ActiveDirectory
$log = "c:\users\public\Tssdis.log"
If (-not (Test-Path $log)) {Out-File $log}
$content1 = (Get-Content $log)
Clear-Content $log
$servers = Get-ADGroupMember "Terminal-Servers"
$servers | Sort -Property Name | foreach {
$ping = Test-Connection -ComputerName $_.Name -Count 2 -Quiet
If ($ping -eq $True) {"1" | Out-File $log -Append -Force -Confirm:$False}
Else {"0" | Out-File $log -Append -Force -Confirm:$False}}
$content2 = (Get-Content $log)
If ((Compare-Object $content1 $content2 | Measure).Count -gt 0) {
$currentdate = Get-Date
Restart-Service Tssdis -Force -Confirm:$False
$str = "Tssdis service has been restarted: " + $currentdate
$str | Out-File "c:\users\public\Tssdis.restart.log" -Append -Force -Confirm:$False}
Безусловно, скрипт не претендует на абсолютно законченное решение, но это наиболее надежный механизм, который мне удалось найти, особенно в наше время, в эпоху виртуализации. В теории, конечно, когда вы уверены, что нерабочий терминал будет отсутствовать долгое время, нужно еще удалить A-запись DNS фермы, указывающую на этот сервер. Это можно сделать, добавив следующую строку после или перед командой Restart-Service:
dnscmd dc /RecordDelete domain.local ts-farm A 10.0.0.120 /f
Данная команда удалит А-запись ts-farm, указывающую на IP: 10.0.0.120 с DNS-сервера dc домена domain.local.
Это не совсем удобно, тем более что сам механизм не всегда корректно отрабатывет, да и потом начинает он работать только в случае неудачного перенаправления сессии на неработающий терминальный сервер. Нам же необходимо немедленное реагирование. То есть если терминал перестал отвечать на эхо-запросы, то мы выполняем перезапуск службы.
Итак, пишем скрипт который будет делать следующее: поочередно посылать на каждый терминальный сервер два icmp-пакета Echo Request (ping), и в случае успеха записывать в файл-маркер Tssdis.log единицу, в противном случае ноль. Далее, пройдя все терминалы, происходит сравнение первоначальной структуры с получившейся путем банального подсчета и сравнения сумм. Если они отличаются, происходит перезапуск службы Tssdis с пометкой в файле-журнале Tssdis.restart.log. Во время запуска службы, механизм обнаружения не будет заносить в базу RD Connection Broker нерабочие терминальные серверы. Скрипт будет повторяться раз в минуту на самом сервере со службой Tssdis (в нашем примере количество терминалов-членов фермы равно двадцати пяти).
Import-Module ActiveDirectory
$log = "c:\users\public\Tssdis.log"
If (-not (Test-Path $log)) {Out-File $log}
$content1 = (Get-Content $log)
Clear-Content $log
$servers = Get-ADGroupMember "Terminal-Servers"
$servers | Sort -Property Name | foreach {
$ping = Test-Connection -ComputerName $_.Name -Count 2 -Quiet
If ($ping -eq $True) {"1" | Out-File $log -Append -Force -Confirm:$False}
Else {"0" | Out-File $log -Append -Force -Confirm:$False}}
$content2 = (Get-Content $log)
If ((Compare-Object $content1 $content2 | Measure).Count -gt 0) {
$currentdate = Get-Date
Restart-Service Tssdis -Force -Confirm:$False
$str = "Tssdis service has been restarted: " + $currentdate
$str | Out-File "c:\users\public\Tssdis.restart.log" -Append -Force -Confirm:$False}
Безусловно, скрипт не претендует на абсолютно законченное решение, но это наиболее надежный механизм, который мне удалось найти, особенно в наше время, в эпоху виртуализации. В теории, конечно, когда вы уверены, что нерабочий терминал будет отсутствовать долгое время, нужно еще удалить A-запись DNS фермы, указывающую на этот сервер. Это можно сделать, добавив следующую строку после или перед командой Restart-Service:
dnscmd dc /RecordDelete domain.local ts-farm A 10.0.0.120 /f
Данная команда удалит А-запись ts-farm, указывающую на IP: 10.0.0.120 с DNS-сервера dc домена domain.local.
Комментариев нет:
Отправить комментарий