Понадобилось проверить текущее время на всех контроллерах домена. Решил соорудить скрипт., использующий дополнительные командлеты для 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
.
[System.Object[]] не содержит метод с именем “op_Subtraction”
Судя по гуглу это из-за того, что powershell не ждет выполнения команды в контексте FOREACH, а долбит запросы асинхронно.
Можно попробовать вставить “Start-Sleep”.
P.S. Хотя у меня отработало как часы с рабочей станции.
Странно, не совсем понятно куда добавить, вот что у меня получилось в итоге:
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
никуда вставлять не надо 🙁
Мой косяк – не проверил эту версию скрипта перед публикацией.
Правильный вариант строки с ForEach:
$array=0..($dc.count-1) | %{
На сайте скрипт исправил, спасибо, что заметили.
Отлично ! Работает :). Спасибо !
Глупый вопрос, но откуда берётся рассинхронизации времени на КД? Они ведь сами синхронизируются с PDC.
для гео-распределенных доменов имеет смысл добавить что-то вроде
$obj | Add-Member -type noteproperty -name TimeZone -Value ((gwmi win32_TimeZone -ComputerName $dc[$i].Name).caption)
2Ринат: В принципе, имеет. Хоть время и так показательно, но в часовых поясах еще есть настройка по переводу часов.
2navion: Должны сами синхронизироваться. Топология синхронизации NTP иногда дает сбой и контроллеры начинают синхронизироваться кто во что горазд. Видел распределенную систему на ~10DC, раскиданную по РФ, с рассинхронизацией в пару минут.
Естественно, лучше подобные косяки лечить через ту же w32tm.
P.S. Рабочие станции тоже должны синхронизировать время с любого контроллера домена (в идеале). Но иногда встречаются косяки из-за неправильных значений параметра Type в HKLM\System\CurrentControlSet\Services\W32Time\Parameters.
по поводу списка контроллеров домена без доп командлетов:
$domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$domain.DomainControllers
Спасибо, Саша.