Рецепты WMI: работа с реестром Windows

Примеры кода в статье приводятся на языке VBScript для административных сценариев Windows.

Класс StdRegProv

Класс StdRegProv служит для работы с системным реестром Windows и располагается в пространстве имён \\root\default.

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

const HKEY_CLASSES_ROOT = &H80000000
const HKEY_CURRENT_USER = &H80000001
const HKEY_LOCAL_MACHINE = &H80000002
const HKEY_USERS = &H80000003
const HKEY_CURRENT_CONFIG = &H80000005
const HKEY_DYN_DATA = &H80000006 ‘только для Windows 95 и Windows 98

Также соответствующими шестнадцатеричными значениями обозначаются права доступа на разделы или параметры реестра:

const KEY_QUERY_VALUE = &H1 ‘запрос значения
const KEY_SET_VALUE = &H2 ‘создание, удаление и установка значения
const KEY_CREATE_SUB_KEY = &H4 ‘создание подразделов
const KEY_ENUMERATE_SUB_KEYS = &H8 ‘перебор подразделов
const KEY_NOTIFY = &H10 ‘запрос уведомлений об изменении раздела и его подразделов
const KEY_CREATE_LINK = &H20 ‘создание связи
const DELETE = &H10000 ‘удаление раздела
const READ_CONTROL = &H20000 ‘комбинация STANDARD_RIGHTS_READ, KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS и KEY_NOTIFY
const WRITE_DAC = &H40000 ‘изменение DAC дескриптора безопасности
const WRITE_OWNER = &H80000 ‘изменение владельца дескриптора безопасности

Соответствующими целыми значениями обозначаются типы данных параметров реестра:

const REG_SZ = 1
const REG_EXPAND_SZ = 2
const REG_BINARY = 3
const REG_DWORD = 4
const REG_MULTI_SZ = 7

Методы класса:

Метод Описание
CheckAccess(hDefKey, sSubKeyName, lRequired, bGranted) Проверяет, имеет ли пользователь указанные разрешения. Возвращает целое число (код ошибки) или 0, если метод завершён успешно. Параметры:

  • hDefKey — ветвь реестра, в которой находится проверяемый раздел. По умолчанию — HKEY_LOCAL_MACHINE (&H80000002).
  • sSubKeyName — проверяемый раздел.
  • lRequired — право доступа, наличие которого проверяется. По умолчанию — KEY_QUERY_VALUE и KEY_SET_VALUE (3).
  • bGranted — если после выполнения метода этот параметр равен True, пользователь имеет указанное право.
CreateKey(hDefKey, sSubKeyName) Создаёт подраздел указанного раздела. Возвращает целое число (код ошибки) или 0, если метод завершён успешно. Параметры:

  • hDefKey — ветвь реестра, в которой будет находиться создаваемый раздел. По умолчанию — HKEY_LOCAL_MACHINE (&H80000002).
  • sSubKeyName — раздел, который будет создан. Метод создаст все разделы, указанные в пути, которые ещё не существуют.
DeleteKey(hDefKey, sSubKeyName) Удаляет подраздел указанного раздела. Возвращает целое число (код ошибки) или 0, если метод завершён успешно. Чтобы удалить раздел, необходимо сначала удалить все его подразделы. Параметры:

  • hDefKey — ветвь реестра, в которой находится удаляемый раздел. По умолчанию — HKEY_LOCAL_MACHINE (&H80000002).
  • sSubKeyName — раздел, который будет удалён.
DeleteValue(hDefKey, sSubKeyName, sValueName) Удаляет указанный параметр в определённом разделе. Возвращает целое число (код ошибки) или 0, если метод завершён успешно. Параметры:

  • hDefKey — ветвь реестра, в которой находится удаляемый параметр. По умолчанию — HKEY_LOCAL_MACHINE (&H80000002).
  • sSubKeyName — раздел, который содержит удаляемый параметр.
  • sValueName — имя параметра, который будет удалён. Укажите пустую строку, чтобы присвоить параметру по умолчанию значение «value not set» («значение не присвоено»).
EnumKey(hDefKey, sSubKeyName, sNames[]) Перечисляет подразделы указанного раздела. Возвращает целое число (код ошибки) или 0, если метод завершён успешно. Параметры:

  • hDefKey — ветвь реестра, в которой находится раздел. По умолчанию — HKEY_LOCAL_MACHINE (&H80000002).
  • sSubKeyName — раздел.
  • sNames — массив строк, содержащий подразделы (после выполнения метода).
EnumValues(hDefKey, sSubKeyName, sNames[], Types[]) Перечисляет параметры указанного раздела. Возвращает целое число (код ошибки) или 0, если метод завершён успешно. Параметры:

  • hDefKey — ветвь реестра, в которой находится раздел. По умолчанию — HKEY_LOCAL_MACHINE (&H80000002).
  • sSubKeyName — раздел.
  • sNames — массив строк, содержащий имена параметров (после выполнения метода). Точно корреспондирует с массивом Types.
  • Types — массив целочисленных значений типов данных параметров (после выполнения метода). Точно корреспондирует с массивом sNames.
GetBinaryValue(hDefKey, sSubKeyName, sValueName, Value[])
GetDWORDValue(hDefKey, sSubKeyName, sValueName, Value)
GetExpandedStringValue(hDefKey, sSubKeyName, sValueName, Value)
GetMultiStringValue(hDefKey, sSubKeyName, sValueName, Value[])
GetStringValue(hDefKey, sSubKeyName, sValueName, Value)
Возвращает значение для указанного параметра, тип данных которого — REG_BINARY, REG_DWORD, REG_EXPAND_SZ, REG_MULTI_SZ или REG_SZ соответственно (конкретный метод нужно выбирать по типу данных параметра). Возвращает целое число (код ошибки) или 0, если метод завершён успешно. Параметры:

  • hDefKey — ветвь реестра, в которой находится параметр. По умолчанию — HKEY_LOCAL_MACHINE (&H80000002).
  • sSubKeyName — раздел, в котором находится параметр.
  • sValueName — имя параметра, значение которого должно быть возвращено. Укажите пустую строку, чтобы получить значение параметра по умолчанию.
  • Value — значение параметра: массив байтов, значение DWORD, строка или массив строк (после выполнения метода).
SetBinaryValue(hDefKey, sSubKeyName, sValueName, Value[])
SetDWORDValue(hDefKey, sSubKeyName, sValueName, Value)
SetExpandedStringValue(hDefKey, sSubKeyName, sValueName, Value)
SetMultiStringValue(hDefKey, sSubKeyName, sValueName, Value)
SetStringValue(hDefKey, sSubKeyName, sValueName, Value)
Устанавливает значение для указанного параметра, тип данных которого — REG_BINARY, REG_DWORD, REG_EXPAND_SZ, REG_MULTI_SZ или REG_SZ соответственно (конкретный метод нужно выбирать по типу данных параметра). Возвращает целое число (код ошибки) или 0, если метод завершён успешно. Параметры:

  • hDefKey — ветвь реестра, в которой находится параметр. По умолчанию — HKEY_LOCAL_MACHINE (&H80000002).
  • sSubKeyName — раздел, в котором находится параметр.
  • sValueName — имя параметра, значение которого должно быть установлено. Укажите пустую строку, чтобы установить значение параметра по умолчанию. Если указанный параметр не существует, он будет создан.
  • Value — значение параметра: массив байтов, значение DWORD, строка или массив строк.

Примеры скриптов

Создание разделов и параметров:

On Error Resume Next
const HKEY_CURRENT_USER = &H80000001
'подключение к WMI
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
If Err.Number <> 0 Then
	WScript.Echo Err.Number & ": " & Err.Description
	WScript.Quit
End If
'Создание разделов
intRes = objReg.CreateKey(HKEY_CURRENT_USER, "MyKey\MySubKey")
If intRes <> 0 Then
	WScript.Echo intRes & ": не удалось создать разделы реестра"
	WScript.Quit
End If
'Создание параметров
intRes = objReg.SetStringValue(HKEY_CURRENT_USER, "MyKey\MySubKey", "MyParam", "MyValue")
If intRes <> 0 Then
	WScript.Echo intRes & ": не удалось установить параметр ""HKEY_CURRENT_USER\MyKey\MySubKey\MyParam"""
	WScript.Quit
End If
intRes = objReg.SetStringValue(HKEY_CURRENT_USER, "MyKey", "", "MyDefaultValue")
If intRes <> 0 Then
	WScript.Echo intRes & ": не удалось установить параметр ""HKEY_CURRENT_USER\MyKey\(По умолчанию)"""
	WScript.Quit
End If
'Вывод сообщений
WScript.Echo "Созданы параметры:"
WScript.Echo "HKEY_CURRENT_USER\MyKey\MySubKey\MyParam (значение ""MyValue"")"
WScript.Echo "HKEY_CURRENT_USER\MyKey\(По умолчанию) (значение ""MyDefaultValue"")"

Проверка разрешений:

On Error Resume Next
const HKEY_CURRENT_USER = &H80000001
const KEY_CREATE_SUB_KEY = &H4
'подключение к WMI
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
If Err.Number <> 0 Then
	WScript.Echo Err.Number & ": " & Err.Description
	WScript.Quit
End If
'проверка прав на создание подразделов
intRes = objReg.CheckAccess(HKEY_CURRENT_USER, "MyKey\MySubKey", KEY_CREATE_SUB_KEY, bGranted)
If intRes <> 0 Then
	WScript.Echo intRes & ": не удалась проверка прав на создание подразделов ""HKEY_CURRENT_USER\MyKey\MySubKey"""
	WScript.Quit
End If
'вывод сообщений
If bGranted Then
	WScript.Echo "Право на создание подразделов в ""HKEY_CURRENT_USER\MyKey\MySubKey"" есть."
Else
	WScript.Echo "Права на создание подразделов в ""HKEY_CURRENT_USER\MyKey\MySubKey"" нет."
End If

Удаление разделов:

On Error Resume Next
const HKEY_CURRENT_USER = &H80000001
'подключение к WMI
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
If Err.Number <> 0 Then
	WScript.Echo Err.Number & ": " & Err.Description
	WScript.Quit
End If
'удаление разделов
intRes = objReg.DeleteKey(HKEY_CURRENT_USER, "MyKey\MySubKey")
If intRes <> 0 Then
	WScript.Echo intRes & ": не удалась удалить раздел ""HKEY_CURRENT_USER\MyKey\MySubKey"""
	WScript.Quit
End If
intRes = objReg.DeleteKey(HKEY_CURRENT_USER, "MyKey")
If intRes <> 0 Then
	WScript.Echo intRes & ": не удалась удалить раздел ""HKEY_CURRENT_USER\MyKey"""
	WScript.Quit
End If
'вывод сообщений
WScript.Echo "Раздел ""HKEY_CURRENT_USER\MyKey"" удалён."

Рекурсивный обход раздела и чтение значений:

On Error Resume Next
const HKEY_CURRENT_USER = &H80000001
'подключение к WMI
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
If Err.Number <> 0 Then
	WScript.Echo Err.Number & ": " & Err.Description
	WScript.Quit
End If
'рекурсивный обход ветви реестра
ReadKey "Software\ODBC"
'**************************************************************************************************
Function ReadKey(strKey)
	'Чтение параметров раздела
	intRes = objReg.EnumValues(HKEY_CURRENT_USER, strKey, sNames, Types)
	If intRes <> 0 Then
		WScript.Echo intRes & ": не удалась прочитать раздел ""HKEY_CURRENT_USER\" & strKey & """"
		WScript.Quit
	End If
	If IsArray(sNames) Then
		i = 0
		For Each Param In sNames
			If Types(i) = 1 Then
				intRes = objReg.GetStringValue(HKEY_CURRENT_USER, strKey, Param, Val)
			Elseif Types(i) = 2 Then
				intRes = objReg.GetExpandedStringValue(HKEY_CURRENT_USER, strKey, Param, Val)
			Elseif Types(i) = 3 Then
				intRes = objReg.GetBinaryValue(HKEY_CURRENT_USER, strKey, Param, Val)
			Elseif Types(i) = 4 Then
				intRes = objReg.GetDWORDValue(HKEY_CURRENT_USER, strKey, Param, Val)
			Elseif Types(i) = 7 Then
				intRes = objReg.GetMultiStringValue(HKEY_CURRENT_USER, strKey, Param, Val)
			End If
			If intRes <> 0 Then
				WScript.Echo intRes & ": не удалась прочитать значение параметра ""HKEY_CURRENT_USER\" & _
							 strKey & "\" & Param & """"
				WScript.Quit
			End If
			If Types(i) = 3 Then
				For j = 0 To UBound(Val)
					Val(j) = Right("00" & Hex(Val(j)), 2)
				Next
				Val = Join(Val)
			Elseif Types(i) = 7 Then
				Val = vbCrLf & Join(Val, vbCrLf)
			End If
			WScript.Echo "HKEY_CURRENT_USER\" & strKey & "\, параметр """ & Param & """ = " & Val
			i = i + 1
		Next
	End If
	'Обход подразделов
	intRes = objReg.EnumKey(HKEY_CURRENT_USER, strKey, sNames)
	If intRes <> 0 Then
		WScript.Echo intRes & ": не удалась прочитать подразделы ""HKEY_CURRENT_USER\" & strKey & """"
		WScript.Quit
	End If
	If IsArray(sNames) Then
		For Each strSubKey In sNames
			ReadKey strKey & "\" & strSubKey
		Next
	End If
End Function

Пример чтения заданного подраздела в HKEY_CURRENT_USER другого пользователя на удалённом компьютере:

On Error Resume Next
const HKEY_USERS = &H80000003
UserName = "SuperUser" 'имя пользователя Windows, HKEY_CURRENT_USER которого надо прочитать на другой машине
CompName = "SuperComputer" 'имя компьютера, на котором надо читать реестр
Key = "Software\1C\1Cv7\7.7\Titles" 'подраздел в HKEY_CURRENT_USER, который надо прочитать
'получение SID пользователя
Set objWMIService = GetObject("winmgmts:{ImpersonationLevel=Impersonate}!\\.\root\cimv2")
If Err.Number <> 0 Then
	WScript.Echo Err.Number & ": " & Err.Description
	WScript.Quit
End If
Set colItems = objWMIService.ExecQuery("Select * from Win32_UserAccount WHERE Name = """ & UserName & """")
For Each objItem in colItems
	strSID = Trim(objItem.SID)
	Exit For
Next
'собственно чтение реестра
Set oReg = GetObject("winmgmts:{ImpersonationLevel=Impersonate}!\\" & CompName & "\root\default:StdRegProv")
If Err.Number <> 0 Then
	WScript.Echo Err.Number & ": " & Err.Description
	WScript.Quit
End If
strKeyPath = strSID & "\" & Key
intRes = oReg.EnumValues(HKEY_USERS, strKeyPath, arrValues)
If intRes <> 0 Then
	WScript.Echo intRes & ": не удалась прочитать раздел ""HKEY_USERS\" & strKeyPath & """"
	WScript.Quit
End If
For i = LBound(arrValues) To UBound(arrValues)
	intRes = oReg.GetStringValue(HKEY_USERS, strKeyPath, arrValues(i), Val)
	If intRes <> 0 Then
		WScript.Echo intRes & ": не удалась прочитать значение параметра ""HKEY_USERS\" & _
					 strKeyPath & "\" & arrValues(i) & """"
		WScript.Quit
	End If
	WScript.Echo Val
Next

Источник: http://www.script-coding.info

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

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