Опрос времени на контроллерах домена

Понадобилось проверить текущее время на всех контроллерах домена. Решил соорудить скрипт., использующий дополнительные командлеты для Active Directory от MS. Буду признателен, если в комментариях подскажут, как сделать список контроллеров домена без дополнительных командлетов.

UPD: Изменил скрипт по совету Васильева Александра. Теперь он не требует командлетов под AD.

Вот что из этого получилось:

$dc=Get-ADObject -LDAPFilter "(objectclass=computer)" -searchbase "ou=domain controllers,dc=holding,dc=com" | sort name

$dc = ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).domaincontrollers | sort name
$i=0
$array=0..($dc.count-1) | %{
$obj = New-Object psobject
$obj | Add-Member -type noteproperty -name Name -Value $dc[$i].Name
$temp=(gwmi Win32_LocalTime -computer $dc[$i].Name)
$obj | Add-Member -type noteproperty -name Hour -Value $temp.hour
$obj | Add-Member -type noteproperty -name Minute -Value $temp.minute
$obj
$i=$i+1
}
$array | out-file c:\tmp\dc_time.txt

Результатом работы скрипта становится таблица, содержащая в строке имя контроллера и его текущее время. В результате работы скрипта нашлось два контроллера с неправильным часовым поясом и один контроллер, выключенный в прошлом году.

P.S. Напоминаю, что рассинхронизацию времени на контроллерах домена можно посмотреть с помощью команды w32tm /monitor

Правда, если контроллеров много, лучше перенаправлять ее вывод в файл, например так — w32tm /monitor >> dc_time.txt.

Опрос времени на контроллерах домена: 10 комментариев

  1. Судя по гуглу это из-за того, что powershell не ждет выполнения команды в контексте FOREACH, а долбит запросы асинхронно.
    Можно попробовать вставить «Start-Sleep».
    P.S. Хотя у меня отработало как часы с рабочей станции.

  2. Странно, не совсем понятно куда добавить, вот что у меня получилось в итоге:

    Import-Module ActiveDirectory
    $dc=Get-ADObject -LDAPFilter «(objectclass=computer)» -searchbase «ou=domain controllers,dc=d,dc=r, dc=local» | sort name
    $i=0
    $array=0..$dc.count-1 | %{
    $obj = New-Object psobject
    $obj | Add-Member -type noteproperty -name Name -Value $dc[$i].Name
    $temp=(gwmi Win32_LocalTime -computer $dc[$i].Name)
    $obj | Add-Member -type noteproperty -name Hour -Value $temp.hour
    $obj | Add-Member -type noteproperty -name Minute -Value $temp.minute
    $obj
    $i=$i+1
    }
    $array | out-file c:\temp\dc_time.txt

  3. никуда вставлять не надо 🙁
    Мой косяк — не проверил эту версию скрипта перед публикацией.
    Правильный вариант строки с ForEach:
    $array=0..($dc.count-1) | %{
    На сайте скрипт исправил, спасибо, что заметили.

  4. Глупый вопрос, но откуда берётся рассинхронизации времени на КД? Они ведь сами синхронизируются с PDC.

  5. для гео-распределенных доменов имеет смысл добавить что-то вроде
    $obj | Add-Member -type noteproperty -name TimeZone -Value ((gwmi win32_TimeZone -ComputerName $dc[$i].Name).caption)

  6. 2Ринат: В принципе, имеет. Хоть время и так показательно, но в часовых поясах еще есть настройка по переводу часов.
    2navion: Должны сами синхронизироваться. Топология синхронизации NTP иногда дает сбой и контроллеры начинают синхронизироваться кто во что горазд. Видел распределенную систему на ~10DC, раскиданную по РФ, с рассинхронизацией в пару минут.
    Естественно, лучше подобные косяки лечить через ту же w32tm.
    P.S. Рабочие станции тоже должны синхронизировать время с любого контроллера домена (в идеале). Но иногда встречаются косяки из-за неправильных значений параметра Type в HKLM\System\CurrentControlSet\Services\W32Time\Parameters.

  7. по поводу списка контроллеров домена без доп командлетов:
    $domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
    $domain.DomainControllers

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *