В ночь с 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 удобно проводить анализ причин отсутствия установленных обновлений.