Объявление: В ближайшее врема, возможность комментировать записи в блогах с учетной записью социальной сети ВКонтакте, будет удалена! В силу неприятия данной социально сети владельцем блога. Комментарии постараюсь сохранить.

Слава Україні! Ла-ла-ла-ла!...

Блог Морозов

Заметки, идеи, мысли...

SCCM OSD: Контроль версий

Автор: MadHead
MadHead
DevOps, Системный администратор, работающий как с Windows, так и UNIX системами.
Пользователей в сайте сейчас нет
Создано: Суббота, 28 Июль 2012 в Windows

Итак, возникла потребность развертывания ОС с помощью автономных образов (SCCM поддерживает как DVD, так и USB Drive). Первая же проблема -- контроль версий (как образа ОС, так и Task Sequence, возможно коллекции при сетевом развертывании), что используют администраторы. Поскольку данная группа людей по своей природе ленива, то получив однажды образ, не особенно будет следить за его актуальностью. А для того, чтоб оказывать влияние на таких людей нужно четко знать, что Василий Пупкин уже год не обновлял образ, из которого разворачивает ОС...

Есть задача, значит есть и решение! И вот моя реализация данного механизма...

Сначала расскажу об основном принципе работы, потом перейду к описанию реализации.

Каждый, кто хоть немного сталкивался с SCCM, знает - данная система очень плотно взаимодействует с WMI. WMI вещица очень мощная (хотя ее реализация в Windows XP оставляет желать лучшего): ее можно использовать как базу данных (именно эта функция нам и будет полезна), можно получать массу информации о системе и железе, можно редактировать реестр... Так вот, идея состоит в следующем: в каждом образе и Task Sequence хранится информация о версии, во время развертывания ОС мы эту информацию консолидируем и записываем в специальный класс WMI, затем (когда система уже работает в сети) мы эту информацию собираем в рамках инвентаризации (Hardware Inventory). Ну и последний штрих - отчет, где мы видим с какими версиями работают админы. Идея озвучена, самое время заняться поэтапной реализацией. Сразу оговорюсь, что описывать буду упрощенный вариант того, что реализовал - он легче для понимания, а нарастить функционал (понимая базовые принципы) будет тоже довольно легко.

Сохранение информации в OS Image, Task Sequence, Collection

Для сохранения данных о версии сборки образа ОС (OS Image) я выбрал обычный текстовый файл (пусть это будет c:\windows\sysimg.dat), следующего формата:
[SCCMOSD]
IMAGE=Windows XP SP3
VERSION=1207071230

(На самом деле первая строчка смысловой нагрузки не несет и написана просто для удобства)

Для сохранения данных о версии последовательности (Task Sequence) я использую переменные последовательности (Task Sequence Variable). В OS Deploy Task Sequence я включил 2 дополнительных шага (сразу после перезагрузки в основную ОС) "Set Task Sequence Variable", где в переменную myTSName я записываю имя последовательности, а в переменную myTSVer ее версию.

Для сохранения данных о коллекции (Collection) я использую переменные коллекции (Collection Variable). Переменные можно задать правым кликом по нужной коллекции и выбрать "Modify Collection Settings", затем на вкладке "Collection Variables" добавить нужные нам переменные: myCLName, myCLVer.

Собственно для задания версии я лично использую обратную запись даты и время в формате YYYYMMDDhhmm (например 201207071230, значит что модификация проведена 07.07.2012 12:30)

Запись информации в WMI

Итак, будем считать, что вся исходная информация готова (предыдущий шаг). Теперь нам требуется прочитать ее и добавить (опционально) фактическое время развертывания, затем записать эти данные в базу WMI. Для этого я использую скрипт (пакет), который запускаю в рамках последовательности, сразу после того, как установил переменные myTSName и myTSVer.

Dim objFSO
Dim objTextFile
Dim strTmp
Dim colParam

Dim dtDeploy  'Время развертывания
Dim strLabel  'Метка образа ОС
Dim intVersion  'Версия образа ОС
Dim strTSName  'Метка Task Sequence
Dim intTSVer  'Версия Task Sequence

Const modeRead = 1
Const formatUnicode = -1
Const strIMGData = "c:\windows\sysimg.dat"

'Установить время развертывания как текущее
dtDeploy = Now()
'Прочитать данные из образа ОС
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile(strIMGData, modeRead, True, formatUnicode)
While Not objTextFile.AtEndOfStream
  strTmp = objTextFile.ReadLine()
  colParam = Split(strTmp, "=")
  Select Case colParam(0)
    Case "IMAGE"
     strLabel = colParam(1)
    Case "VERSION"
     intVersion = colParam(1)
  End Select
Wend
objTextFile.Close

'Прочитать данные о переменных Task Sequence
Dim oTSEnv
Dim oVar

Set oTSEnv = CreateObject("Microsoft.SMS.TSEnvironment")
For Each oVar In oTSEnv.GetVariables
 Select Case oVar
  Case "myTSVer"
   intTSVer = oTSEnv(oVar)
  Case "myTSName"
   strTSName = oTSEnv(oVar)
 End Select
Next

'Записать данные в WMI
Const wbemCimtypeString = 8
Const wbemCimtypeUint32 = 19
Const wbemCimtypeDateTime = 101

Dim objWMIService
Dim objClass
Dim objData
Dim objInst

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2")
Set objClass = objWMIService.Get
objClass.Path_.Class = "SMSOSDStamp"
 objClass.Properties_.add "Image_Name", wbemCimtypeString
 objClass.Properties_("Image_Name").Qualifiers_.add "key", true
 objClass.Properties_.add "Image_Version", wbemCimtypeUint32
 objClass.Properties_.add "Deploy_Date", wbemCimtypeDateTime
 objClass.Properties_.add "OSD_TS_Name", wbemCimtypeString
 objClass.Properties_.add "OSD_TS_Version", wbemCimtypeUint32
objClass.Put_

Dim wbemDate
Set wbemDate = CreateObject("WbemScripting.SWbemDateTime")
Set objData = objWMIService.Get("SMSOSDStamp")
Set objInst = objData.SpawnInstance_
objInst.Image_Name = strLabel
objInst.Image_Version = intVersion
wbemDate.SetVarDate(CDate(dtDeploy))
objInst.Deploy_Date = wbemDate.Value
objInst.OSD_TS_Name = strTSName
objInst.OSD_TS_Version = intTSVer
objInst.Put_

Обратите внимание на обработку даты, при создании WMI класса! Дело в том, что формат даты для VBScript и WMI существенно отличаются. Если прямо присвоить, то ошибки не будет, но не будет и результата... мы просто не получим экземпляр класса.

Сбор информации

Собирать данные мы будем в рамках инвентаризации (Hardware Inventory), для этого нам надо добавить описание класса в SCCM (за описание классов, по которым собирается информация отвечает файл sms_def.mof). В конец файла добавляем следующую запись:

[ SMS_Report (TRUE),
SMS_Group_Name ("SMSOSDStamp"),
SMS_Class_ID ("CUSTOM|SMSOSDStamp|1.0") ]

class SMSOSDStamp : SMS_Class_Template
{
  [SMS_Report (TRUE), key ] string Image_Name;
  [SMS_Report (TRUE) ] uint32 Image_Version;
  [SMS_Report (TRUE) ] datetime Deploy_Date;
  [SMS_Report (TRUE) ] string OSD_TS_Name;
  [SMS_Report (TRUE) ] uint32 OSD_TS_Version;
};

Очет

Ну и последний штрих - получение информации в виде отчета. Вот мой вариант запроса (если быть честным то не мой, а напарника... я его просто слегка модифицировал):

SELECT TOP (100) PERCENT
  dbo.v_R_System.AD_Site_Name0,
  CASE WHEN (dbo.v_GS_SMSOSDStamp0.Image_Version0 IS NOT NULL) THEN 'OSD' ELSE 'No_OSD' END AS OSD,
  dbo.v_R_System.Name0,
dbo.v_R_System.User_Name0,
  dbo.v_GS_OPERATING_SYSTEM.InstallDate0,
  dbo.v_GS_OPERATING_SYSTEM.Caption0 AS OS_Type,
  dbo.v_GS_OPERATING_SYSTEM.CSDVersion0 AS SP_Version,
  dbo.v_GS_SMSOSDStamp0.Deploy_Date0,
  dbo.v_GS_SMSOSDStamp0.Image_Name0,
  dbo.v_GS_SMSOSDStamp0.Image_Version0,
  dbo.v_GS_SMSOSDStamp0.OSD_TS_Name0,
  dbo.v_GS_SMSOSDStamp0.OSD_TS_Version0
FROM dbo.v_GS_OPERATING_SYSTEM
  INNER JOIN dbo.v_R_System ON dbo.v_GS_OPERATING_SYSTEM.ResourceID = dbo.v_R_System.ResourceID
  LEFT OUTER JOIN dbo.v_GS_SMSOSDStamp0 ON dbo.v_R_System.ResourceID = dbo.v_GS_SMSOSDStamp0.ResourceID
WHERE (dbo.v_GS_OPERATING_SYSTEM.InstallDate0 > @variable)
ORDER BY dbo.v_GS_OPERATING_SYSTEM.InstallDate0 DESC, dbo.v_R_System.AD_Site_Name0, OSD

Заключение

Собственно все! Теперь мы можем контролировать какими версиями образов ОС и Task Sequence пользуются администраторы. Информацию мы будем получать достаточно оперативно, так как после установки агента SCCM, он в ближайшее время проводит инвентаризацию и отправляет ее на сервер.

Не достаточно прав для добавления комментариев (только зарегистрированные пользователи)

Tekstkontent