Лучший отвечающий
Как добраться до реестра машины, не входящей в домен?

Вопрос
-
Есть домен 2008 в лесу 2008. И есть несколько компьютеров (Windows XP, Windows7), не входящих в домен. Нужно на этих компьютерах получить/поменять одно из значений в реестре. Работать буду с машины, которая входит в домен. Имя и пароль пользователя с административными правами на недоменных машинах знаю. Сам вхожу в группу "Администраторы домена". Для достижения цели написал вот такой скрипт:
Computers = Array("192.168.5.10") strPassword = "xxxxxx" For Each strComputer In Computers Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator") Set objSWbemServices = objSWbemLocator.ConnectServer(strComputer, "root\cimv2", "COMP\user", strPassword) Set ShellObj = WScript.CreateObject("WScript.Shell") Set FSO = WScript.CreateObject("Scripting.FilesystemObject") Set NetObj = WScript.CreateObject("WScript.Network") WinDir = FSO.GetSpecialFolder(0) SysDir = FSO.GetSpecialFolder(1) On Error Resume Next RegistryKeyPath="HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\" RegKeyValue = ShellObj.RegRead(RegistryKeyPath & "WUServer") WScript.Echo RegKeyValue Next
Запускаю скрипт... получаю Access denied. При этом, я уверен, что на машине с адресом 192.168.5.10 (которая носит имя COMP) есть пользователь user с паролем xxxxxx.
Если вместо данных машины COMP подставляю адрес, имя машины, имя пользователя DOMAIN\user и пароль этого юзера - всё работает. Скрипт возвращает значение переменной WUServer...
Что я делаю не так?
Сергей Панченко
- Изменено Daemon-GTC 11 мая 2012 г. 10:29
11 мая 2012 г. 9:02
Ответы
-
Вы желаете работать с реестром удалённой станции, а метод RegRead объекта WScript.Shell "умеет" работать только с локальным реестром.
Пример работающего сценария:
Const HKLM = &H80000002 Computers = Array("192.168.5.10") strPassword = "xxxx" RegKeyPath = "SOFTWARE\Policies\Microsoft\Windows\Installer" strValueName = "EnableAdminTSRemote" For Each strComputer In Computers strUser = strComputer & "\Администратор" Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator") Set objSWbemServices = objSWbemLocator.ConnectServer(strComputer, "root\default:StdRegProv", strUser, strPassword) Set objReg = objSWbemServices.Get("StdRegProv") objReg.GetDWORDValue HKLM, RegKeyPath, strValueName, RegKeyValue WScript.Echo strComputer & " = " & RegKeyValue Next WScript.Quit 0
Примечание.
В примере выполняется чтение значения типа DWORD. Для чтения значения другого типа используйте соответствующий метод класса StdRegProv.- Изменено DmitriiV 11 мая 2012 г. 11:01
- Помечено в качестве ответа Daemon-GTC 12 мая 2012 г. 9:19
11 мая 2012 г. 10:54 -
В итоге, всё получилось.
Во-первых, нужно было использовать методы класса StdRegProv: SetDWORDValue, GetDWORDValue, DeleteDWORDValue (и аналоги для String, Multistring и т.д.).
Во-вторых, ключик HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\ForceGuest должен быть в 1.
В-третьих, служба удалённого реестра на целевой машине должна быть запущена.
Привожу рабочий скрипт, прописывающий некоторые параметры WSUS на удалённой машине:
Const HKLM = &H80000002 Const WSUSPATH1 = "SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\" Const WSUSPATH2 = "SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\" Computers = Array("COMP1", "COMP2") strPassword = "xxxxxx" For Each strComputer In Computers strUser = strComputer & "\user" Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator") Set objSWbemServices = objSWbemLocator.ConnectServer(strComputer, "\root\default", strUser, strPassword) Set objReg = objSWbemServices.Get("StdRegProv") 'Удаляем ненужные значения call objReg.DeleteValue(HKLM, WSUSPATH1, "SUSClientID") call objReg.DeleteValue(HKLM, WSUSPATH1, "PingID") call objReg.DeleteValue(HKLM, WSUSPATH1, "AccountDomainSID") 'Добавляем/изменяем нужные call objReg.SetStringValue(HKLM, WSUSPATH2, "TargetGroup", "Машины вне домена") call objReg.SetDWORDValue (HKLM, WSUSPATH2, "TargetGroupEnabled", 1) call objReg.SetDWORDValue(HKLM, WSUSPATH2 & "AU\", "AUOptions", 4) call objReg.SetDWORDValue(HKLM, WSUSPATH2 & "AU\", "ScheduledInstallDay", 0) call objReg.SetDWORDValue(HKLM, WSUSPATH2 & "AU\", "ScheduledInstallTime", 11) call objReg.SetDWORDValue(HKLM, WSUSPATH2 & "AU\", "NoAutoRebootWithLoggedOnUsers", 1) call objReg.SetDWORDValue(HKLM, WSUSPATH2 & "AU\", "NoAutoUpdate", 0) call objReg.SetDWORDValue(HKLM, WSUSPATH2 & "AU\", "UseWUServer", 1)
'Для отладки выводим установленное значение
' call objReg.GetStringValue(HKLM, WSUSPATH2, "TargetGroup", RegKeyValue)
' WScript.Echo RegKeyValue Next
Сергей Панченко
- Помечено в качестве ответа Daemon-GTC 12 мая 2012 г. 9:19
- Изменено Daemon-GTC 12 мая 2012 г. 9:20
12 мая 2012 г. 7:53
Все ответы
-
Вы желаете работать с реестром удалённой станции, а метод RegRead объекта WScript.Shell "умеет" работать только с локальным реестром.
Пример работающего сценария:
Const HKLM = &H80000002 Computers = Array("192.168.5.10") strPassword = "xxxx" RegKeyPath = "SOFTWARE\Policies\Microsoft\Windows\Installer" strValueName = "EnableAdminTSRemote" For Each strComputer In Computers strUser = strComputer & "\Администратор" Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator") Set objSWbemServices = objSWbemLocator.ConnectServer(strComputer, "root\default:StdRegProv", strUser, strPassword) Set objReg = objSWbemServices.Get("StdRegProv") objReg.GetDWORDValue HKLM, RegKeyPath, strValueName, RegKeyValue WScript.Echo strComputer & " = " & RegKeyValue Next WScript.Quit 0
Примечание.
В примере выполняется чтение значения типа DWORD. Для чтения значения другого типа используйте соответствующий метод класса StdRegProv.- Изменено DmitriiV 11 мая 2012 г. 11:01
- Помечено в качестве ответа Daemon-GTC 12 мая 2012 г. 9:19
11 мая 2012 г. 10:54 -
В общем, ошибку понял. На недоменной машине было выставлено HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\ForceGuest = 1.
Исправил в 0, скрипт стал читать значения риджистри. Теперь хочу поменять. Модифицировал скрипт так:
Computers = Array("192.168.5.10") strPassword = "хххххх" For Each strComputer In Computers Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator") Set objSWbemServices = objSWbemLocator.ConnectServer(strComputer, "\root\cim2", "COMP\user", strPassword) Set ShellObj = WScript.CreateObject("WScript.Shell") Set FSO = WScript.CreateObject("Scripting.FilesystemObject") Set NetObj = WScript.CreateObject("WScript.Network") WinDir = FSO.GetSpecialFolder(0) SysDir = FSO.GetSpecialFolder(1) 'Читаем имеющееся значение ключа RegistryKeyPath="HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\" RegKeyValue = ShellObj.RegRead(RegistryKeyPath & "WUServer") WScript.Echo RegKeyValue 'Прочитали успешно, получили значение. ' Удаляем старую регистрацию на WSUS RegistryKeyPath1="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\" call ShellObj.RegDelete(RegistryKeyPath1 & "SUSClientID") 'А вот тут получаем облом: "Ошибка при удалении" 80070005. Next
И что я опять неверно сделал?
Сергей Панченко
11 мая 2012 г. 11:11 -
1. Код ошибки свидетельствует об отказе в доступе к объекту. Наиболее вероятная причина - недостаточный уровень полномочий для выполнения операции (например, на Win 7 действие может быть заблокировано средствами UAC, т.к. для правки реестра обычно требуются повышенные привилегии).
2. Скажите, с реестром какой станции Вы пытаетесь экспериментировать: локальной или удалённой?
- Изменено DmitriiV 12 мая 2012 г. 5:49
12 мая 2012 г. 5:19 -
В итоге, всё получилось.
Во-первых, нужно было использовать методы класса StdRegProv: SetDWORDValue, GetDWORDValue, DeleteDWORDValue (и аналоги для String, Multistring и т.д.).
Во-вторых, ключик HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\ForceGuest должен быть в 1.
В-третьих, служба удалённого реестра на целевой машине должна быть запущена.
Привожу рабочий скрипт, прописывающий некоторые параметры WSUS на удалённой машине:
Const HKLM = &H80000002 Const WSUSPATH1 = "SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\" Const WSUSPATH2 = "SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\" Computers = Array("COMP1", "COMP2") strPassword = "xxxxxx" For Each strComputer In Computers strUser = strComputer & "\user" Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator") Set objSWbemServices = objSWbemLocator.ConnectServer(strComputer, "\root\default", strUser, strPassword) Set objReg = objSWbemServices.Get("StdRegProv") 'Удаляем ненужные значения call objReg.DeleteValue(HKLM, WSUSPATH1, "SUSClientID") call objReg.DeleteValue(HKLM, WSUSPATH1, "PingID") call objReg.DeleteValue(HKLM, WSUSPATH1, "AccountDomainSID") 'Добавляем/изменяем нужные call objReg.SetStringValue(HKLM, WSUSPATH2, "TargetGroup", "Машины вне домена") call objReg.SetDWORDValue (HKLM, WSUSPATH2, "TargetGroupEnabled", 1) call objReg.SetDWORDValue(HKLM, WSUSPATH2 & "AU\", "AUOptions", 4) call objReg.SetDWORDValue(HKLM, WSUSPATH2 & "AU\", "ScheduledInstallDay", 0) call objReg.SetDWORDValue(HKLM, WSUSPATH2 & "AU\", "ScheduledInstallTime", 11) call objReg.SetDWORDValue(HKLM, WSUSPATH2 & "AU\", "NoAutoRebootWithLoggedOnUsers", 1) call objReg.SetDWORDValue(HKLM, WSUSPATH2 & "AU\", "NoAutoUpdate", 0) call objReg.SetDWORDValue(HKLM, WSUSPATH2 & "AU\", "UseWUServer", 1)
'Для отладки выводим установленное значение
' call objReg.GetStringValue(HKLM, WSUSPATH2, "TargetGroup", RegKeyValue)
' WScript.Echo RegKeyValue Next
Сергей Панченко
- Помечено в качестве ответа Daemon-GTC 12 мая 2012 г. 9:19
- Изменено Daemon-GTC 12 мая 2012 г. 9:20
12 мая 2012 г. 7:53 -
Daemon-GTC, только сейчас заметил ошибку, допущенную в собственном примере:
Set objSWbemServices = objSWbemLocator.ConnectServer(strComputer, "root\default:StdRegProv", strUser, strPassword)
Имя класса после имени WMI-пространства здесь указывать не нужно.
Должно быть так:
Set objSWbemServices = objSWbemLocator.ConnectServer(strComputer, "root\default", strUser, strPassword)- Изменено DmitriiV 12 мая 2012 г. 9:05
12 мая 2012 г. 9:03 -
Имя класса после имени WMI-пространства здесь указывать не нужно.
Сергей Панченко
- Изменено Daemon-GTC 12 мая 2012 г. 9:20
12 мая 2012 г. 9:19 -
В данном случае - ничего (как это явствует из опыта). Видимо, обработчик запроса игнорирует всё, что следует за разделителем (:), стоящим после имени WMI-пространства (DEFAULT).
Однако, вообще говоря, результаты обращения к объектам по пути ROOT\DEFAULT и по пути ROOT\DEFAULT:STDREGPROV будут разными.
В первом случае будет получена ссылка на объект типа SWbemServicesEx, а во втором - на объект SWbemObjectEx. Эти объекты имеют разное функциональное назначение, а следовательно, разные наборы методов и свойств.14 мая 2012 г. 11:05