В ночь с 29 на 30 октября 2011 в России должен был быть переход на зимнее время, однако волевым решение президента переходы на летнее и зимнее время были отменены, и Россия остается на летнем времени. Значит многие IT специалисты столкнулись с задачей обновления всех систем и в частности, необходимо обновить все клиентские и все серверные операционные системы. Компания Microsoft выпустила очередное обновление для исправления временных зон, учитывающее последние изменения KB2570791. Это обновление необходимо установить на все Windows машины, «для гладкого» прохождения ночи с 29 на 30 октября, без возможных последствий из-за внесенных изменений.
В случае если в текущей инфраструктуре большое количество серверов и машин, то бегать ногами к каждой машине и устанавливать обновление KB2570791 займет массу времени и сил. Поэтому, те кто привык работать головой, а не ногами (руками), давно уже имеют равернутый Microsoft Windows Server Update Services (WSUS), а то и не один.
Однако, что делать с компьютерами, которые в силы каких либо причин, находятся в домене, но не зарегистрировались на WSUS, либо из-за все возможных причин давно к нему не обращались. Один из вариантов, опросить все доступные в сети компьютеры и проверить корректность установки данного обновления. В этом нам может помочь Powershell, Vbs, AutoIT и другие подобные инструменты.
Далее предлагается один из вариантов решения задачи поиска машин в доменной сети с неустановленным обновлением KB2570791.
В качестве исходных данных, требуется только список машин в домене, его легко получить из оснастки Active Directory Users and Computers (dsa.msc), используя Saved Query. В итоге полученный список серверов и компьютеров в домене экспортируется в csv-файл, и этот файл является источником информации о компьютерах в сети. Основная информация, которая нам необходима в этом файле, это имя машины (поле Name).
Далее этот файл обрабатывается следующим образом:
- Проверяется, пингуется и ли машина
- Если машина пингуется, то проверяется:
- Текущая настройка TimeZone
- IP адрес
- Версию ОС
- Текущий пользователь
- Установлено ли обновление KB2570791
- На основании данных п. 2 принимается решение о статусе обновления машины.
На выходе, получим следующую информацию:
- Список машин, которые не пингуются
- Список не обновленных машин
- Список обновленных машин
- Список машин, с настройками других временных зон
Чтобы реализовать выше описанное, потребуется:
- функция проверки отвечает ли хост на ping
- функция сбора информации о хосте
- Чтобы проверить пингуется ли удаленная машина, используется следующий набор команд:
$ping = New-Object System.Net.NetworkInformation.Ping $ping.Send($CompName)
Где $CompName – это имя машины
Полностью функция будет выглядеть следующим образом:
############################################################
##### Функция проверки доступности компьютера #####
############################################################
Function IsReply($CompName) {
$ping = New-Object System.Net.NetworkInformation.Ping
try
{
$Reply = $ping.Send($CompName)
}
catch
{
Write-host "Для машины " $CompName "не удалось выполнить ping"
}
return $Reply.status
}
- Чтобы собрать необходимую информацию для данной задачи о удаленной машине, понадобится несколько командлетов.
2.1 Для получения информации о удаленной машине будет использоваться функция Get-WmiObject, и классы WMI, так как это не накладывает дополнительных требований на удаленные машины.
Командлет Get-WmiObject отображает экземпляры классов WMI или сведения о доступных классах WMI. Параметр ComputerName всегда можно использовать для указания удаленного компьютера. При задании параметра List этот командлет извлекает сведения о классах WMI, доступных в заданном пространстве имен. При указании параметра Query командлет запускает инструкцию языка запросов WMI (WQL).
Командлет Get-WmiObject не использует инфраструктуру удаленного взаимодействия Windows PowerShell для выполнения удаленных операций. Параметр ComputerName командлета Get-WmiObject можно использовать, даже если компьютер не соответствует требованиям для удаленного взаимодействия Windows PowerShell и не настроен на удаленное взаимодействие в Windows PowerShell.
Для сбора информации о машине, будут использоваться следующие WMI-классы:
- Win32_TimeZone – для определения временной зоны
- Win32_NetworkAdapterConfiguration – для определения настроенных IP адресов
- Win32_OperatingSystem — для определения версии операционной системы и Service Pack
- Win32_ComputerSystem – для определения пользователя компьютера
Для получение полного списка доступных WMI-классов, можно использовать команду:
Get-WmiObject -List
При определении TimeZone, одно из самых наглядных параметров класса Win32_TimeZone, является свойство Caption. Его значение на обновленной машине выглядит следующим образом:
(UTC+04:00) Moscow, St. Petersburg, Volgograd
Однако как удалось заметить параметр Caption, на некоторых машинах имеет пустое значение, поэтому вместо него будет использоваться свойство BIAS. BIAS всегда имеет значение равное разнице между локальным временем и UTC.
2.2 Для получения информации о том, есть ли на удаленной машине обновление KB2570791, будет использоваться командлет Get-Hotfix.
Командлет Get-Hotfix возвращает исправления, примененные на локальном компьютере или на удаленных компьютерах с помощью компонентной модели CBS.
Но так как, получать полный список установленных обновлений, для решения данной задачи, нет необходимости, то полученные результаты отфильтруем по обновлению KB2570791:
Get-Hotfix -ComputerName $CompName | where-Object {($_.HotFixID -Like "*KB2570791*")}
Также в эту функцию будут включены операции, распределения полученной информации в соответствующие файлы. В итоге функция получения информации о компьютере будет выглядеть следующим образом:
############################################################
##### Функция получения информации о компьютере #####
############################################################
Function Get-Info ($CompName) {
# Получаем информация о текущих настройках TimeZone
$TZ = Get-WmiObject -Class "Win32_TimeZone" -namespace "root\\CIMV2" -computername $CompName -ErrorAction SilentlyContinue
# Получаем информацию о IP адресе
$IP = Get-WmiObject -Class "Win32_NetworkAdapterConfiguration" -namespace "root\\CIMV2" -computername $CompName -ErrorAction SilentlyContinue| Select-Object IPAddress |Where-Object { $_.IPAddress -ne $null }
# Получаем информацию о версии операционной системы
$OS = Get-WmiObject -Class "Win32_operatingSystem" -namespace "root\\CIMV2" -computername $CompName -ErrorAction SilentlyContinue
#Получаем информацию о пользователе на компьютере
$USER = Get-WmiObject -Class "Win32_ComputerSystem" -namespace "root\\CIMV2" -computername $CompName -ErrorAction SilentlyContinue
if ((!$TZ) -or (!$IP) -or (!$OS) -or (!$USER))
{
# Если ничего не удалось определить, то считаем что с компьютером не все в порядке
return "Failed"
}
else
{
# Проверяем: установлен ли Update KB2570791
$UpdateForTZ = Get-Hotfix -ComputerName $CompName | where-Object {($_.HotFixID -Like "*KB2570791*")}
#Полученная информация сохраняется для поиска возможных проблем
If ($UpdateForTZ.HotFixID -ne $null)
{
$IsHostFix = "There is update " + $UpdateForTZ.HotFixID
}
else
{
$IsHostFix = "There is not update KB2570791"
}
#Собирается вся информация в общую переменную
$FullInfo = $CompName + ";" + $User.UserName + ";" + $IP.IPAddress + ";" + $IsHostFix + ";" + $OS.Caption + $OS.OSArchitecture + " " + $OS.CSDVersion + ";" + $OS.Version + ";" + $TZ.Bias
#На основе собранной информации распределяются машины по разным файлам
#1. Машина доступна, но не обновлена
#2. Машина доступна и обновлена успешно
#3. Настройки часового пояса отличаются от искомых (+3 или +4)
#Проверяется параметр BIAS (Смещение от абсолютного времени)
if ($TZ.Bias -eq 180)
{
$FullInfo| Out-File -Append “D:\\powershell\\Log\\NotUpdated.txt”
}
elseif ($TZ.Bias -eq 240)
{
$FullInfo| Out-File -Append “D:\\powershell\\Log\\Updated.txt”
}
else
{
$FullInfo| Out-File -Append “D:\\powershell\\Log\\Other.txt”
}
#Возвращаем успех
return "Success"
}
}
Начало основное скрипта Powershell, в котором сначала подготавливаются файлы для результатов, затем считывается файл, со списком машин, а затем данные из этого файла запускаются в обработку.
############################################################
##### Начало скрипта #####
############################################################
#Если необходимо останавливать скрипт при возникновении ошибок в процессе выполнения
#(например при отладке), то следующую строку надо раскомментировать
#$ErrorActionPreference = "Stop"
# Обнуляем файлы, в которые записываем результаты и создаем шапку
#Файл для машин, на которых часовой пояс не изменился
("Name;User;IP_Address;Update;OS;OS_Version;Bias")| Out-File “D:\\powershell\\Log\\NotUpdated.txt”
#Файл для машин, на которых обновление прошло успешно
("Name;User;IP_Address;Update;OS;OS_Version;Bias")| Out-File “D:\\powershell\\Log\\Updated.txt”
#Файл для машин, на которых часовой пояс отличается и от старого и от нового
("Name;User;IP_Address;Update;OS;OS_Version;Bias")| Out-File “D:\\powershell\\Log\\Other.txt”
#Файл для машин, которые в настоящий момент недоступны
("Name;User;IP_Address;Update;OS;OS_Version;Bias")| Out-File “D:\\powershell\\Log\\NotAvailable.txt”
# Загружаем исходный список машин
$List= Import-Csv "D:\\powershell\\listcomp.csv" -delimiter ';'
#Обнуляем счетчик машин
$cnt=0
# Начинаем обработку каждой машины
foreach ( $arr in $List)
{
#Увеличиваем счетчик и выводим имя машины
$cnt=$cnt+1
Write-Host $cnt, $arr.name
# Проверяем доступен ли компьютер
$IsPing = IsReply($arr.name)
#Если доступен, то собираем информацию,
#Если не доступен, то записываем его в список недоступных машин
if ($IsPing –eq "Success")
{
# Собираем информацию
$Result = Get-Info($arr.name)
#Если сбор информации неуспешен, то записываем его в список недоступных машин
if ($Result –ne "Success")
{
$arr.name| Out-File -Append “D:\\powershell\\Log\\NotAvailable.txt”
}
}
else
{
$arr.name| Out-File -Append “D:\\powershell\\Log\\NotAvailable.txt”
}
}
############################################################
##### Конец скрипта #####
############################################################
После окончания работы скрипта и анализа полученных данных, файлы NotUpdated.txt и NotAvailable.txt можно обработать повторно. На основе файла NotUpdated.txt удобно проводить анализ причин отсутствия установленных обновлений.