Показать полную графическую версию : Установка через GPO определённой KB (943729). WSUS нет.
Доброго времени суток, коллеги.
Необходимо через GPO развернуть KB943729. WSUS в сети нет. В теории хотелось бы какой-нибудь скриптик, который бы запускался из GPO в startup-скрипте и проверял на наличие этого KB в системе. Если ОНО уже есть - ничего бы не делал дальше, а если его нет на каком-то компьютере - устанавливал бы эту KB'шку.
Или может кто подскажет какие-то другие варианты, как разворачивать в сети эту KB?
1. Проверьте как определяется это KB, будучи установленным.
Так:
wmic.exe QFE WHERE "HotFixID='File 1' AND ServicePackInEffect = 'KB943729'"
определяется?
2. Приведите имена файлов отсюда: Information about new Group Policy preferences in Windows Server 2008 (http://support.microsoft.com/?kbid=943729) в зависимости от Вашего перечня ОС и языков.
1. Определяется так:
http://clip2net.com/clip/m19972/thumb640/1341059363-clip-9kb.png (http://clip2net.com/s/24VT1)
2. Это немного не понял - извините. В сети используются Windows XP, Vista, Windows Server 2003. Все 32-bit, все Русские.
Разворачивать этот KB через GPO я уже научился: стартап-скриптом с ключём /quiet. Для каждой ОС будет (в теории) свой WMI фильтр. Сейчас такой фильтр есть пока только для Windows XP. Вот бы ещё проверочку сделать, чтобы при каждой загрузке не устанавливать :-)
На самом деле, наверное, было бы классно иметь возможность обойтись без WMI фильров - только одним скриптом для всех. Чтобы скрипт сам проверял наличие и в случае отсутствия - сам ставил бы нужную KB в соответствии с ОС, платформой, языком :-) Но это я губу раскатал уже :-)
возможность обойтись без WMI фильров - только одним скриптом для всех. Чтобы скрипт сам проверял наличие и в случае отсутствия - сам ставил бы нужную KB в соответствии с ОС, платформой, языком »
Ну, так, в общем-то, и планируется.
P.S. Зачем задаваться излишними платформами и языками, ежели:
В сети используются Windows XP, Vista, Windows Server 2003. Все 32-bit, все Русские. »
и только?
Incognitus, вот, с учётом вышеизложенного Вами, примерный шаблон:
Option Explicit
Dim objDictionary
Dim strComputer
Dim objSWbemLocator
Dim objSWbemServicesEx
Dim collSWbemObjectSet
Dim objSWbemObjectEx
Set objDictionary = WScript.CreateObject("Scripting.Dictionary")
With objDictionary
.Add "5.1.2600", "WindowsXP-KB943729-x86-RUS.exe"
.Add "5.2.3790", "WindowsServer2003-KB943729-x86-RUS.exe"
.Add "6.0.6000", "Windows6.0-KB943729-x86.msu"
.Add "6.0.6001", "Windows6.0-KB943729-x86.msu"
.Add "6.0.6002", "Windows6.0-KB943729-x86.msu"
End With
strComputer = "."
Set objSWbemLocator = WScript.CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServicesEx = objSWbemLocator.ConnectServer(strComputer, "root\cimv2")
Set collSWbemObjectSet = objSWbemServicesEx.ExecQuery( _
"SELECT * FROM Win32_QuickFixEngineering WHERE HotFixID='File 1' AND ServicePackInEffect = 'KB943729'")
If collSWbemObjectSet.Count = 0 Then
For Each objSWbemObjectEx In objSWbemServicesEx.InstancesOf("Win32_OperatingSystem")
With objSWbemServicesEx.Get("Win32_Process")
If .Create("""\\Server\Share$\" & objDictionary.Item(objSWbemObjectEx.Version) & _
""" /passive /norestart /log:""\\Server\Logs$\KB2647516_" & WScript.CreateObject("WScript.Network").ComputerName & ".log""") = 0 Then
Else
'Error
End If
End With
Exit For
Next
End If
Set collSWbemObjectSet = Nothing
Set objSWbemServicesEx = Nothing
Set objSWbemLocator = Nothing
objDictionary.RemoveAll
Set objDictionary = Nothing
WScript.Quit 0
У компьютеров домена должен быть доступ на чтение к ресурсу «\\Server\Share$» и на запись — к ресурсу «\\Server\Logs$». Корректные имена файлов обновления подставьте сами. Скрипт задавать для исполнения с параметром «//b»:
wscript.exe //b "\\server\gpo…\Script.vbs"
Спасибо огромное! Скрипт офигенный, правда его работоспособность я ещё не проверил. Сейчас этим займусь. Подскажите, пожалуйста, если я буду использовать этот скрипт как стартап - аргумент "//b" надо указывать?
http://clip2net.com/clip/m19972/thumb640/1341127056-clip-12kb.jpg (http://clip2net.com/s/2526H)
Ещё вопрос уже не относящийся к моей конкретной проблеме, но по Вашему скрипту: возможна его реализация с учётом платформы (x86, x64), языка (Rus, Eng), ОС (Windows XP, Vista, 7, Windows Server 2003, 2003 R2, 2008, 2008 R2 и т.д.)? "И т.д." - в том плане, что я с удовольствием подписался бы на обновления и актуализацию этого замечательного скрипта.
Ещё раз спасибо!
Что-то не захотел работать у меня скрипт. Для простоты отладки выполнял тестирование локально на новой Windows XP Eng 32-bit.
Код выглядит
Option Explicit
Dim objDictionary
Dim strComputer
Dim objSWbemLocator
Dim objSWbemServicesEx
Dim collSWbemObjectSet
Dim objSWbemObjectEx
Set objDictionary = WScript.CreateObject("Scripting.Dictionary")
With objDictionary
.Add "5.1.2600", "WindowsXP-KB943729-x86-ENU.exe"
.Add "5.2.3790", "WindowsServer2003-KB943729-x86-RUS.exe"
.Add "6.0.6000", "Windows6.0-KB943729-x86.msu"
.Add "6.0.6001", "Windows6.0-KB943729-x86.msu"
.Add "6.0.6002", "Windows6.0-KB943729-x86.msu"
End With
strComputer = "."
Set objSWbemLocator = WScript.CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServicesEx = objSWbemLocator.ConnectServer(strComputer, "root\cimv2")
Set collSWbemObjectSet = objSWbemServicesEx.ExecQuery( _
"SELECT * FROM Win32_QuickFixEngineering WHERE HotFixID='File 1' AND ServicePackInEffect = 'KB943729'")
If collSWbemObjectSet.Count = 0 Then
For Each objSWbemObjectEx In objSWbemServicesEx.InstancesOf("Win32_OperatingSystem")
With objSWbemServicesEx.Get("Win32_Process")
If .Create("""C:\KB\" & objDictionary.Item(objSWbemObjectEx.Version) & _
""" /passive /norestart /log:""C:\Logs" & WScript.CreateObject("WScript.Network").ComputerName & ".log""") = 0 Then
Else
'Error
End If
End With
Exit For
Next
End If
Set collSWbemObjectSet = Nothing
Set objSWbemServicesEx = Nothing
Set objSWbemLocator = Nothing
objDictionary.RemoveAll
Set objDictionary = Nothing
WScript.Quit 0
Расположение файлов на компьютере и отображение запуска и проверки работы скрипта выглядит так:
http://clip2net.com/clip/m19972/thumb640/1341139538-clip-52kb.png (http://clip2net.com/s/253z0)
При этом лог выполнения запуска KB'шки упал в корень C:\, а не C:\Logs, куда должен был бы по идее и выглядит
[LogsTESTCLIENTXP2.log]
0.156: ================================================================================
0.156: 2012/07/01 14:42:36.938 (local)
0.156: c:\0fa018c457c1f8431be21b0e09e8b2e2\update\update.exe (version 6.3.4.1)
0.156: Failed To Enable SE_BACKUP_PRIVILEGE
0.156: Setup encountered an error: You do not have permission to update Windows XP. Please contact your system administrator.
0.156: You do not have permission to update Windows XP. Please contact your system administrator.
0.156: Update.exe extended error code = 0xf004 0.156: Update.exe return code was masked to 0x643 for MSI custom action compliance.
http://clip2net.com/clip/m19972/thumb640/1341139984-clip-15kb.png (http://clip2net.com/s/253C9)
Все манипуляции выполнялись под локальным администратором.
Прошу Вашей помощи в восстановлении работоспособности скрипта!
если я буду использовать этот скрипт как стартап - аргумент "//b" надо указывать? »
Желательно. Дабы подавить любые сообщения, в том числе и об ошибках времени исполнения. Т.е., «Script name» [кстати, а говорили, что все машины — «RUS»?!]:
wscript.exe //b "Install GPP Extension.vbs"
возможна его реализация с учётом платформы (x86, x64), языка (Rus, Eng), ОС (Windows XP, Vista, 7, Windows Server 2003, 2003 R2, 2008, 2008 R2 и т.д.)? »
Реализация не представляет собой каких-то сложностей. Могу попробовать. Не в том дело. Было бы кому проверять — у меня в ниличии весьма ограниченный круг вариантов ОС, платформ и языков.
…этого замечательного скрипта. »
Не вижу в нём ничего замечательного. Лога нет, обработки ошибок нет, работоспособность ограничена малым перечнем платформ и языков.
[кстати, а говорили, что все машины — «RUS»?!]: »
Так и есть - все русские в рабочей среде. В моей тестовой среде - все английские. Но по идее, для данного скрипта это неважно, если правильно прописать соответствие в objDictionary - насколько я понимаю. В моём скрипте для тестовой среды я указал, что для "5.1.2600" надо брать "WindowsXP-KB943729-x86-ENU.exe", который как раз и лежит в папке C:\KB.
Желательно. Дабы подавить любые сообщения, в том числе и об ошибках времени исполнения. »
В окошке добавления скрипта для GPO (см. это окошко выше в топике) это значит что в поле "Script Parameters" надо прописать "//b" - верно?
Что-то не захотел работать у меня скрипт. »
Я посмотрю.
При этом лог выполнения запуска KB'шки упал в корень C:\, а не C:\Logs, куда должен был бы по идее »
Не должен. Вы пропустили завершающий слэш в:
… /log:""C:\Logs\" & WScript.CreateObject("WScript.Network").ComputerName & ".log""") = 0 …
Failed To Enable SE_BACKUP_PRIVILEGE
Учтём, попробуем запросить привилегию:
…
Set objSWbemLocator = WScript.CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServicesEx = objSWbemLocator.ConnectServer(strComputer, "root\cimv2")
objSWbemServicesEx.Security_.Privileges.AddAsString "SeBackupPrivilege", True
Set collSWbemObjectSet = objSWbemServicesEx.ExecQuery( _
"SELECT * FROM Win32_QuickFixEngineering WHERE HotFixID='File 1' AND ServicePackInEffect = 'KB943729'")
…
Так и есть - все русские в рабочей среде. В моей тестовой среде - все английские. »
Спасибо, ясно.
Но по идее, для данного скрипта это неважно, если правильно прописать соответствие в objDictionary - насколько я понимаю. В моём скрипте для тестовой среды я указал, что для "5.1.2600" надо брать "WindowsXP-KB943729-x86-ENU.exe", который как раз и лежит в папке C:\KB. »
Да. Вы совершенно правы.
В окошке добавления скрипта для GPO (см. это окошко выше в топике) это значит что в поле "Script Parameters" надо прописать "//b" - верно? »
Можно и так. Двойной слэш перед параметром указывает на то, что он не будет обрабатываться самим сценарием, а будет передан серверу сценариев («cscript.exe» или «wscript.exe»).
Отлично! Всё заработало в локальной машине! Теперь буду тестировать работу в связке с GPO.
KB'шка запросила ещё ряд привилегий. Я прописал их по аналогии. Сейчас скрипт выглядит Option Explicit
Dim objDictionary
Dim strComputer
Dim objSWbemLocator
Dim objSWbemServicesEx
Dim collSWbemObjectSet
Dim objSWbemObjectEx
Set objDictionary = WScript.CreateObject("Scripting.Dictionary")
With objDictionary
.Add "5.1.2600", "WindowsXP-KB943729-x86-ENU.exe"
.Add "5.2.3790", "WindowsServer2003-KB943729-x86-RUS.exe"
.Add "6.0.6000", "Windows6.0-KB943729-x86.msu"
.Add "6.0.6001", "Windows6.0-KB943729-x86.msu"
.Add "6.0.6002", "Windows6.0-KB943729-x86.msu"
End With
strComputer = "."
Set objSWbemLocator = WScript.CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServicesEx = objSWbemLocator.ConnectServer(strComputer, "root\cimv2")
objSWbemServicesEx.Security_.Privileges.AddAsString "SeBackupPrivilege", True
objSWbemServicesEx.Security_.Privileges.AddAsString "SeRestorePrivilege", True
objSWbemServicesEx.Security_.Privileges.AddAsString "SeShutdownPrivilege", True
objSWbemServicesEx.Security_.Privileges.AddAsString "SeSecurityPrivilege", True
objSWbemServicesEx.Security_.Privileges.AddAsString "SeTakeOwnershipPrivilege", True
Set collSWbemObjectSet = objSWbemServicesEx.ExecQuery( _
"SELECT * FROM Win32_QuickFixEngineering WHERE HotFixID='File 1' AND ServicePackInEffect = 'KB943729'")
If collSWbemObjectSet.Count = 0 Then
For Each objSWbemObjectEx In objSWbemServicesEx.InstancesOf("Win32_OperatingSystem")
With objSWbemServicesEx.Get("Win32_Process")
If .Create("""C:\KB\" & objDictionary.Item(objSWbemObjectEx.Version) & _
""" /quiet /norestart /log:""C:\Logs\" & WScript.CreateObject("WScript.Network").ComputerName & ".log""") = 0 Then
Else
'Error
End If
End With
Exit For
Next
End If
Set collSWbemObjectSet = Nothing
Set objSWbemServicesEx = Nothing
Set objSWbemLocator = Nothing
objDictionary.RemoveAll
Set objDictionary = Nothing
WScript.Quit 0
Ещё от себя Я изменил ключ /passive на /quiet - мне так больше подходит.
Спасибо Вам большущее за Вашу компетентность и оперативность! Если у Вас есть желание и время развить этот код для работы с учётом платформы и языка - с удовольствием буду Вашим тестером. Уверен, что этот код будет полезен многим нашим коллегам.
Решённой тему пока не отмечаю до окончательного тестирования.
Отлично! Всё заработало в локальной машине! Теперь буду тестировать работу в связке с GPO. »
Вот и славненько. Отпишитесь по результатам, пожалуйста.
KB'шка запросила ещё ряд привилегий.»
Действительно все перечисленные?
Ещё от себя Я изменил ключ /passive на /quiet - мне так больше подходит. »
Я стараюсь не скрывать от пользователя, что происходит процесс установки. Но сие действительно дело вкуса.
Если у Вас есть желание и время развить этот код для работы с учётом платформы и языка - с удовольствием буду Вашим тестером. »
С Вами приятно работать: Вы приводите исполняемый на Вашей стороне код, приводите полученные результаты, по потребности — скриншоты. Пишете грамотно, по-русски, по существу и к месту.
Обычно бывает с точностью до наоборот — «ничё неработает».
Отпишитесь по результатам, пожалуйста. » Обязательно ;-)
Действительно все перечисленные? » Да - всё что запросила KB'шка - прописал, ничего лишнего.
Я стараюсь не скрывать от пользователя, что происходит процесс установки. » Я предполагаю у себя запускать это starup-скриптом, т.е. на этом этапе никакого пользователя не предполагается. Отсюда использование /quiet ключа.
С Вами приятно работать: Вы приводите исполняемый на Вашей стороне код, приводите полученные результаты, по потребности — скриншоты. Пишете грамотно, по-русски, по существу и к месту. »
Спасибо :-) Просто я "спрашиватель" со стажем и прекрасно понимаю, что чем грамотнее буду задавать вопросы, тем быстрее найду на них ответы.
PIL123, посмотрите на этот код:
Option Explicit
Dim strHotFixID
Dim strServicePackInEffect
Dim strPath2HotFix
Dim strPath2Log
Dim objDictionary
Dim objFSO
Dim strComputer
Dim objSWbemLocator
Dim objSWbemServicesEx
Dim collSWbemObjectSet
Dim objSWbemObjectEx
Dim strPrivilege
Dim strOSVersion
Dim strHotFixFullPath
strHotFixID = "File 1"
strServicePackInEffect = "KB943729"
strPath2HotFix = "C:\KB"
strPath2Log = "C:\Logs"
Set objDictionary = WScript.CreateObject("Scripting.Dictionary")
With objDictionary
.Add "Windows XP x86 ENU", "WindowsXP-KB943729-x86-ENU.exe"
.Add "Windows XP x86 RUS", "WindowsXP-KB943729-x86-RUS.exe"
.Add "Windows XP x64 ENU", "WindowsXP64-KB943729-x86-ENU.exe"
.Add "Windows XP x64 RUS" , "WindowsXP64-KB943729-x86-RUS.exe"
.Add "Windows Server 2003 x86 ENU", "WindowsServer2003-KB943729-x86-ENU.exe"
.Add "Windows Server 2003 x86 RUS", "WindowsServer2003-KB943729-x86-RUS.exe"
.Add "Windows Server 2003 x64 ENU", "WindowsServer2003-KB943729-x64-ENU.exe"
.Add "Windows Server 2003 x64 RUS", "WindowsServer2003-KB943729-x64-RUS.exe"
.Add "Windows Vista x86 ENU", "Windows6.0-KB943729-x86-ENU.msu"
.Add "Windows Vista x86 RUS", "Windows6.0-KB943729-x86-RUS.msu"
.Add "Windows Vista x64 ENU", "Windows6.0-KB943729-x64-ENU.msu"
.Add "Windows Vista x64 RUS", "Windows6.0-KB943729-x64-RUS.msu"
.Add "Windows Server 2008 x86 ENU", "Windows6.0-KB943729-x86-ENU.msu"
.Add "Windows Server 2008 x86 RUS", "Windows6.0-KB943729-x86-RUS.msu"
.Add "Windows Server 2008 x64 ENU", "Windows6.0-KB943729-x64-ENU.msu"
.Add "Windows Server 2008 x64 RUS", "Windows6.0-KB943729-x64-RUS.msu"
.Add "Windows 7 x86 ENU", "Windows6.1-KB943729-x86-ENU.msu"
.Add "Windows 7 x86 RUS", "Windows6.1-KB943729-x86-RUS.msu"
.Add "Windows 7 x64 ENU", "Windows6.1-KB943729-x64-ENU.msu"
.Add "Windows 7 x64 RUS", "Windows6.1-KB943729-x64-RUS.msu"
.Add "Windows Server 2008 R2 x64 ENU", "Windows6.1-KB943729-x64-ENU.msu"
.Add "Windows Server 2008 R2 x64 RUS", "Windows6.1-KB943729-x64-RUS.msu"
End With
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
strComputer = "."
Set objSWbemLocator = WScript.CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServicesEx = objSWbemLocator.ConnectServer(strComputer, "root\cimv2")
For Each strPrivilege In Array("SeBackupPrivilege", "SeRestorePrivilege", "SeShutdownPrivilege", "SeSecurityPrivilege", "SeTakeOwnershipPrivilege")
objSWbemServicesEx.Security_.Privileges.AddAsString strPrivilege, True
Next
Set collSWbemObjectSet = objSWbemServicesEx.ExecQuery( _
"SELECT * FROM Win32_QuickFixEngineering WHERE HotFixID='" & strHotFixID & "' AND ServicePackInEffect = '" & strServicePackInEffect & "'")
If collSWbemObjectSet.Count = 0 Then
strOSVersion = GetStandardWindowsVersion(objSWbemServicesEx)
If objDictionary.Exists(strOSVersion) Then
strHotFixFullPath = objFSO.BuildPath(strPath2HotFix, objDictionary.Item(strOSVersion))
WScript.Echo """" & strHotFixFullPath & """" & _
" /passive /norestart /log:""" & strPath2Log & "\" & _
strHotFixID & "_" & strServicePackInEffect & " [" & _
WScript.CreateObject("WScript.Network").ComputerName & "].log"""
If objFSO.FileExists(strHotFixFullPath) Then
With objSWbemServicesEx.Get("Win32_Process")
If .Create("""" & strHotFixFullPath & """" & _
" /passive /norestart /log:""" & strPath2Log & "\" & _
strHotFixID & "_" & strServicePackInEffect & " [" & _
WScript.CreateObject("WScript.Network").ComputerName & "].log""") = 0 Then
' Success execute
Else
'Can't execute
End If
End With
Else
' File not found
End If
Else
' OS <--> HotFix link not found
End If
End If
Set collSWbemObjectSet = Nothing
Set objSWbemServicesEx = Nothing
Set objSWbemLocator = Nothing
objDictionary.RemoveAll
Set objDictionary = Nothing
WScript.Quit 0
'=============================================================================
'=============================================================================
Function GetStandardWindowsVersion(objSWbemServicesEx)
Dim objDictionary
Dim objSWbemObjectEx_Win32_OperatingSystem
Dim objSWbemObjectEx_Win32_ComputerSystem
Dim strOS
Set objDictionary = WScript.CreateObject("Scripting.Dictionary")
With objDictionary
.Add "32-bit", "x86"
.Add "64-bit", "x64"
.Add "X86-based PC", "x86"
.Add "X64-based PC", "x64"
End With
For Each objSWbemObjectEx_Win32_OperatingSystem In objSWbemServicesEx.InstancesOf("Win32_OperatingSystem")
With objSWbemObjectEx_Win32_OperatingSystem
Select Case .Version
'==========================================================================
Case "5.1.2600"
strOS = "Windows XP x86"
'==========================================================================
Case "5.2.3790"
Select Case .ProductType
Case 1
strOS = "Windows XP x64"
Case 2, 3
For Each objSWbemObjectEx_Win32_ComputerSystem In .InstancesOf("Win32_ComputerSystem")
strOS = "Windows Server 2003 " & objDictionary.Item(objSWbemObjectEx_Win32_OperatingSystem.SystemType)
Exit For
Next
End Select
'==========================================================================
Case "6.0.6000", "6.0.6001", "6.0.6002"
Select Case .ProductType
Case 1
strOS = "Windows Vista " & objDictionary.Item(.OSArchitecture)
Case 2, 3
strOS = "Windows Server 2008 " & objDictionary.Item(.OSArchitecture)
End Select
'==========================================================================
Case "6.1.7600", "6.1.7601"
Select Case objSWbemObjectEx.ProductType
Case 1
strOS = "Windows 7 " & objDictionary.Item(.OSArchitecture)
Case 2, 3
strOS = "Windows Server 2008 R2 " & objDictionary.Item(.OSArchitecture)
End Select
'==========================================================================
Case Else
' Other
End Select
Select Case .OSLanguage
Case 1033
strOS = strOS & " ENU"
Case 1049
strOS = strOS & " RUS"
Case Else
' Other
End Select
Exit For
End With
Next
objDictionary.RemoveAll
Set objDictionary = Nothing
WScript.Echo strOS
GetStandardWindowsVersion = strOS
End Function
'=============================================================================
Здесь мы в начале скрипта перечисляем (по-хорошему, надо сие перечисление выносить во внешний ini/xml-файл) файлы обновлений соответственно версий, платформ и языка ОС. Основной вопрос, как обычно — правильно ли сии составляющие определяются.
PIL123, посмотрите на этот код: »
ОК, отлично, спасибо! Обязательно посмотрю. Сейчас столкнулся немного с другой проблемой - не могу запустить через GPO стартап-скрип тот скрипт, который для AIDA64. На контроллере домена скрипт из GPO отработал нормально, а на тестовом клиенте (Windows XP) работать не хочет. Пока не знаю почему.
Попутно вот нашёл по этой теме: http://www.heidelbergit.dk/2008/03/how-to-install-gpp-cses-using-startup.html - зарубежный опыт.
А это: http://social.technet.microsoft.com/Forums/ru-RU/ws2008r2ru/thread/38a78315-8fac-4edb-a805-6958d02c63c1 - отечественный.
Iska, Ваш код отлично работает!!! Правда имел возможность потестить пока только на Windows XP x86 ENG. Позже постараюсь потестить на других ОС в более сложных условиях.
Я немного его адаптировал под себя и у меня он сейчас выглядит
Option Explicit
Dim strHotFixID
Dim strServicePackInEffect
Dim strPath2HotFix
Dim strPath2Log
Dim objDictionary
Dim objFSO
Dim strComputer
Dim objSWbemLocator
Dim objSWbemServicesEx
Dim collSWbemObjectSet
Dim objSWbemObjectEx
Dim strPrivilege
Dim strOSVersion
Dim strHotFixFullPath
strHotFixID = "File 1"
strServicePackInEffect = "KB943729"
strPath2HotFix = "\\TestDC.Company.Local\Distributives\KB943729"
strPath2Log = "\\TestDC.Company.Local\Distributives\KB943729\Logs"
Set objDictionary = WScript.CreateObject("Scripting.Dictionary")
With objDictionary
.Add "Windows XP x86 ENU", "WindowsXP-KB943729-x86-ENU.exe"
.Add "Windows XP x86 RUS", "WindowsXP-KB943729-x86-RUS.exe"
.Add "Windows XP x64 ENU", "WindowsXP-KB943729-x64-ENU-RUS.exe"
.Add "Windows XP x64 RUS", "WindowsXP-KB943729-x64-ENU-RUS.exe"
.Add "Windows Server 2003 x86 ENU", "WindowsServer2003-KB943729-x86-ENU.exe"
.Add "Windows Server 2003 x86 RUS", "WindowsServer2003-KB943729-x86-RUS.exe"
.Add "Windows Server 2003 x64 ENU", "WindowsServer2003-KB943729-x64-ENU.exe"
.Add "Windows Server 2003 x64 RUS", "WindowsServer2003-KB943729-x64-RUS.exe"
.Add "Windows Vista x86 ENU", "WindowsVista6.0-KB943729-x86-ENU.msu"
.Add "Windows Vista x86 RUS", "WindowsVista6.0-KB943729-x86-RUS.msu"
.Add "Windows Vista x64 ENU", "WindowsVista6.0-KB943729-x64-ENU.msu"
.Add "Windows Vista x64 RUS", "WindowsVista6.0-KB943729-x64-RUS.msu"
End With
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
strComputer = "."
Set objSWbemLocator = WScript.CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServicesEx = objSWbemLocator.ConnectServer(strComputer, "root\cimv2")
For Each strPrivilege In Array("SeBackupPrivilege", "SeRestorePrivilege", "SeShutdownPrivilege", "SeSecurityPrivilege", "SeTakeOwnershipPrivilege")
objSWbemServicesEx.Security_.Privileges.AddAsString strPrivilege, True
Next
Set collSWbemObjectSet = objSWbemServicesEx.ExecQuery( _
"SELECT * FROM Win32_QuickFixEngineering WHERE HotFixID='" & strHotFixID & "' AND ServicePackInEffect = '" & strServicePackInEffect & "'")
If collSWbemObjectSet.Count = 0 Then
strOSVersion = GetStandardWindowsVersion(objSWbemServicesEx)
If objDictionary.Exists(strOSVersion) Then
strHotFixFullPath = objFSO.BuildPath(strPath2HotFix, objDictionary.Item(strOSVersion))
WScript.Echo """" & strHotFixFullPath & """" & _
" /quiet /norestart /log:""" & strPath2Log & "\" & _
strHotFixID & "_" & strServicePackInEffect & " [" & _
WScript.CreateObject("WScript.Network").ComputerName & "].log"""
If objFSO.FileExists(strHotFixFullPath) Then
With objSWbemServicesEx.Get("Win32_Process")
If .Create("""" & strHotFixFullPath & """" & _
" /quiet /norestart /log:""" & strPath2Log & "\" & _
strHotFixID & "_" & strServicePackInEffect & " [" & _
WScript.CreateObject("WScript.Network").ComputerName & "].log""") = 0 Then
' Success execute
Else
'Can't execute
End If
End With
Else
' File not found
End If
Else
' OS <--> HotFix link not found
End If
End If
Set collSWbemObjectSet = Nothing
Set objSWbemServicesEx = Nothing
Set objSWbemLocator = Nothing
objDictionary.RemoveAll
Set objDictionary = Nothing
WScript.Quit 0
'=============================================================================
'=============================================================================
Function GetStandardWindowsVersion(objSWbemServicesEx)
Dim objDictionary
Dim objSWbemObjectEx_Win32_OperatingSystem
Dim objSWbemObjectEx_Win32_ComputerSystem
Dim strOS
Set objDictionary = WScript.CreateObject("Scripting.Dictionary")
With objDictionary
.Add "32-bit", "x86"
.Add "64-bit", "x64"
.Add "X86-based PC", "x86"
.Add "X64-based PC", "x64"
End With
For Each objSWbemObjectEx_Win32_OperatingSystem In objSWbemServicesEx.InstancesOf("Win32_OperatingSystem")
With objSWbemObjectEx_Win32_OperatingSystem
Select Case .Version
'==========================================================================
Case "5.1.2600"
strOS = "Windows XP x86"
'==========================================================================
Case "5.2.3790"
Select Case .ProductType
Case 1
strOS = "Windows XP x64"
Case 2, 3
For Each objSWbemObjectEx_Win32_ComputerSystem In .InstancesOf("Win32_ComputerSystem")
strOS = "Windows Server 2003 " & objDictionary.Item(objSWbemObjectEx_Win32_OperatingSystem.SystemType)
Exit For
Next
End Select
'==========================================================================
Case "6.0.6000", "6.0.6001", "6.0.6002"
Select Case .ProductType
Case 1
strOS = "Windows Vista " & objDictionary.Item(.OSArchitecture)
Case 2, 3
strOS = "Windows Server 2008 " & objDictionary.Item(.OSArchitecture)
End Select
'==========================================================================
Case "6.1.7600", "6.1.7601"
Select Case objSWbemObjectEx.ProductType
Case 1
strOS = "Windows 7 " & objDictionary.Item(.OSArchitecture)
Case 2, 3
strOS = "Windows Server 2008 R2 " & objDictionary.Item(.OSArchitecture)
End Select
'==========================================================================
Case Else
' Other
End Select
Select Case .OSLanguage
Case 1033
strOS = strOS & " ENU"
Case 1049
strOS = strOS & " RUS"
Case Else
' Other
End Select
Exit For
End With
Next
objDictionary.RemoveAll
Set objDictionary = Nothing
WScript.Echo strOS
GetStandardWindowsVersion = strOS
End Function
'=============================================================================
Эта, конкретная KB'шка не нужна для Windows 7, Windows Server 2008, Windows Server 2008 R2, поэтому из objDictionary я убрал упоминания о них для этого конкретного случая.
А вообще, судя по
strHotFixID = "File 1"
strServicePackInEffect = "KB943729"
у меня сложилось ощущение, что внутрь этого скрипта можно засунуть и другие KB'шки, т.е. Вы делали некий универсальный инструментарий для развёртывания KB - верно? Также косвенно об этом говорит имя файла логов, получившегося у меня: File 1_KB943729 [TESTCLIENT].log Было бы неплохо в таком случае, если бы Вы приложили бы к нему небольшое описание - инструкцию по эксплуатации - как его масштабировать для нескольких KB, как быть в случае, если KB'шки есть только для некоторых ОС (как в случае с KB943729).
Я не смог понять и разобраться для чего мне в коде для конкретной KB'шки, которой нет под Win 7, Win 2008, 2008R, вот эти строки.
Case 2, 3
strOS = "Windows Server 2008 " & objDictionary.Item(.OSArchitecture)
End Select
'==========================================================================
Case "6.1.7600", "6.1.7601"
Select Case objSWbemObjectEx.ProductType
Case 1
strOS = "Windows 7 " & objDictionary.Item(.OSArchitecture)
Case 2, 3
strOS = "Windows Server 2008 R2 " & objDictionary.Item(.OSArchitecture)
удалять их не стал, ибо "не понятно".
Верно ли я понимаю, что скрипт предполагает только одно место хранения для KB'шек?
strPath2HotFix = "\\TestDC.Company.Local\Distributives\KB943729"
Если это так, то это не очень универсально, ибо предполагает, что KB должны ВСЕ храниться в одном месте. Это не очень удобно. Нельзя ли для каждой KB указывать свой путь?
Если я вообще не правильно понял Ваш скрипт и несу ерунду, объясните, пожалуйста, как правильно в теории должно быть.
UPD:
Кстати, вот содержимое лога. Может из него удастся как-то что-то улучшить
[File 1_KB943729 [TESTCLIENT].log]
0.250: ================================================================================
0.250: 2012/07/02 21:29:05.140 (local)
0.250: c:\52fa1b1dbf5491ca582ac4\update\update.exe (version 6.3.4.1)
0.250: Hotfix started with following command line: /quiet /norestart /log:\\TestDC.Company.Local\Distributives\KB943729\Logs\File 1_KB943729 [TESTCLIENT].log
0.250: In Function GetBuildType, line 1170, RegQueryValueEx failed with error 0x2
0.266: C:\WINDOWS\system32\xmllite.dll is Present
0.266: Condition succeeded for section Test.PresentOp.Section in Line 1 of PreRequisite
0.266: DoInstallation: HpInitializeLibrary failed; status=0xe0000106, location=2749
0.266: Hotpatching Initialization Failed: Disabling Hotpatch functionality.
1.516: In Function TestVolatileFlag, line 12013, RegOpenKeyEx failed with error 0x2
1.516: In Function TestVolatileFlag, line 12045, RegOpenKeyEx failed with error 0x2
1.516: DoInstallation: CleanPFR failed: 0x2
1.516: In Function GetBuildType, line 1170, RegQueryValueEx failed with error 0x2
1.516: SetProductTypes: InfProductBuildType=BuildType.Sel
1.531: SetAltOsLoaderPath: No section uses DirId 65701; done.
1.594: DoInstallation: FetchSourceURL for c:\52fa1b1dbf5491ca582ac4\Update\update_wxp.inf failed
1.594: CreateUninstall = 1,Directory = C:\WINDOWS\$NtUninstallKB943729$
1.594: LoadFileQueues: UpdSpGetSourceFileLocation for halmacpi.dll failed: 0xe0000102
1.594: BuildCabinetManifest: update.url absent
1.594: Starting AnalyzeComponents
1.594: AnalyzePhaseZero used 0 ticks
1.594: No c:\windows\INF\updtblk.inf file.
1.594: OEM file scan used 0 ticks
1.594: AnalyzePhaseOne: used 0 ticks
1.594: AnalyzeComponents: Hotpatch analysis disabled; skipping.
1.594: AnalyzeComponents: Hotpatching is disabled.
1.625: AnalyzePhaseTwo used 15 ticks
1.625: AnalyzePhaseThree used 0 ticks
1.625: AnalyzePhaseFive used 0 ticks
1.625: AnalyzePhaseSix used 0 ticks
1.625: AnalyzeComponents used 31 ticks
1.625: Downloading 0 files
1.625: bPatchMode = FALSE
1.625: Inventory complete: ReturnStatus=0, 31 ticks
1.625: Num Ticks for invent : 31
1.625: Allocation size of drive C: is 4096 bytes, free space = 40797515776 bytes
1.641: AnalyzeDiskUsage: Skipping EstimateDiskUsageForUninstall.
1.641: Drive C: free 38907MB req: 8MB w/uninstall: NOT CALCULATED.
1.641: CabinetBuild complete
1.641: Num Ticks for Cabinet build : 16
1.641: DynamicStrings section not defined or empty.
1.641: Starting process: msiexec /x {376B771D-8C14-4AFF-874B-677C3423F8F8} /quiet
2.172: Return Code = 1605
2.172: Starting process: msiexec /x {5A01A639-CF6C-441D-9EF3-B59C4375FF87} /quiet
2.406: Return Code = 1605
2.406: Starting process: msiexec /x {337240B1-42C2-4384-AAFF-D347A6D2CC5E} /quiet
2.641: Return Code = 1605
2.641: Starting process: msiexec /x {362C838B-54FF-4197-847B-8927FF1742EE} /quiet
2.875: Return Code = 1605
2.875: Starting process: msiexec /x {E606D790-404B-46F7-8DE6-C1FAE06CAC67} /quiet
3.219: Return Code = 1605
3.219: Starting process: msiexec /x {4583EB96-6167-4B87-8F0E-A12A128B3EB0} /quiet
3.453: Return Code = 1605
3.453: Starting process: msiexec /x {200B6216-5FA0-4DAA-BC41-500CE1ADCF97} /quiet
3.688: Return Code = 1605
3.688: Starting process: msiexec /x {B01ED954-EB4F-401F-9CDE-98895FE6F367} /quiet
3.906: Return Code = 1605
3.906: Starting process: msiexec /x {2765750D-7888-4D77-AD27-A71EC00AFF53} /quiet
4.141: Return Code = 1605
4.141: Starting process: msiexec /x {D787C24E-809D-4C48-BF53-EC5C76689A13} /quiet
4.375: Return Code = 1605
4.391: FileInUse:: Detection disabled.
5.391: LoadFileQueues: UpdSpGetSourceFileLocation for halmacpi.dll failed: 0xe0000102
5.516: Num Ticks for Backup : 3875
5.578: Num Ticks for creating uninst inf : 62
5.578: Registering Uninstall Program for -> KB943729, KB943729 , 0x0
5.625: LoadFileQueues: UpdSpGetSourceFileLocation for halmacpi.dll failed: 0xe0000102
7.266: System Restore Point set.
7.297: Copied file: C:\WINDOWS\system32\spmsg.dll
9.000: PFE2: Not avoiding Per File Exceptions.
9.047: GetCatVersion: Failed to retrieve version information from C:\WINDOWS\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\KB943729.cat with error 0x57
9.328: Copied file: C:\WINDOWS\system32\gpprefcl.dll
9.485: Copied file: C:\WINDOWS\system32\WBEM\polprocl.mof
9.547: Copied file: C:\WINDOWS\system32\WBEM\polprocl.mfl
9.578: Copied file: C:\WINDOWS\system32\WBEM\POLBASE.MOF
9.610: Copied file: C:\WINDOWS\system32\WBEM\POLPRO.MOF
9.641: Copied file: C:\WINDOWS\system32\WBEM\POLPROC.MOF
9.656: Copied file: C:\WINDOWS\system32\WBEM\POLPROU.MOF
9.672: DoInstallation: Installing assemblies with source root path: c:\52fa1b1dbf5491ca582ac4\
9.672: Num Ticks for Copying files : 4094
9.969: Num Ticks for Reg update and deleting 0 size files : 297
9.969: Starting process: C:\WINDOWS\system32\wbem\mofcomp.exe C:\WINDOWS\system32\wbem\polprocl.mof
10.813: Return Code = 0
13.953: UpdateSpUpdSvcInf: Source [ProcessesToRunAfterReboot] section is empty; nothing to do.
13.985: RebootNecessary = 0,WizardInput = 1 , DontReboot = 1, ForceRestart = 0
Эта, конкретная KB'шка не нужна для Windows 7, Windows Server 2008, Windows Server 2008 R2, поэтому из objDictionary я убрал упоминания о них для этого конкретного случая. »
Можно и просто оставить пустые строки или закомментировать:
.Add "Windows 7 x86 ENU", ""
'.Add "Windows 7 x86 RUS", "Windows6.1-KB943729-x86-RUS.msu"
Названия файлов я, понятное дело, брал наобум. И версию 6.1 оставил просто для демонстрации.
Я всё-таки думаю, удобнее будет вынести сие во внешний файл.
А вообще, судя по
Код:
strHotFixID = "File 1"
strServicePackInEffect = "KB943729"
у меня сложилось ощущение, что внутрь этого скрипта можно засунуть и другие KB'шки, т.е. Вы делали некий универсальный инструментарий для развёртывания KB - верно? Также косвенно об этом говорит имя файла логов, получившегося у меня: File 1_KB943729 [TESTCLIENT].log »
В общем-то, да. Одного хотфикса. Значения:
strHotFixID
strServicePackInEffect
strPath2HotFix
strPath2Log
и планируемый «strPath2OSHotfixLinks» (путь ко внешнему файлу, содержащему то, что нынче присваивается в самом скрипте посредством «objDictionary») — должны будут передаваться аргументами скрипта. Либо и вовсе всё это держать в одном XML файле, путь к которому передавать аргументом.
Было бы неплохо в таком случае, если бы Вы приложили бы к нему небольшое описание - инструкцию по эксплуатации »
Можно будет попробовать.
как его масштабировать для нескольких KB »
Пока — никак. Только — несколько скриптов. Оттого я и хочу отделить мух от котлет код от данных, вынеся последние во внешний файл. Тогда скрипт будет один, а к нему — потребное число XML с данными на хотфикс (или даже один XML с несколькими хотфиксами). Попробую поработать над этим.
Сейчас мне важнее другое: правильно ли определяется версия/платформа/язык для разных ОС. А я, например, совершенно не представляю, как обстоят дела с MUI — как там правильно определять язык ОС, какие языкозависимые обновления вообще надо ставить под ним — RUS или ENU.
Сейчас мне важнее другое: правильно ли определяется версия/платформа/язык для разных ОС. А я, например, совершенно не представляю, как обстоят дела с MUI — как там правильно определять язык ОС, какие языкозависимые обновления вообще надо ставить под ним — RUS или ENU. »
Я потестирую и отпишусь Вам. Если завтра всё будет по плану и скрипт отработает - будут результаты по разным русским ОС.
Либо и вовсе всё это держать в одном XML файле »
XML-файл этот нужно будет руками составлять? Насколько это юзерфрендли? Я, например, имею очень скромные знания о формате XML и как подобный файл создавать самому в блокноте.
Сегодня запустил в рабочей среде скрипт. На Windows XP русской всё прошло хорошо без запинки, а вот на Windows Server 2003 R2 SP2 ставиться из скрипта не стало по каким-то причинам.
http://clip2net.com/clip/m19972/thumb640/1341430223-clip-132kb.jpg (http://clip2net.com/s/25GEg)
Причём руками тот KB, который соответствует в коде Windows Server 2003
.Add "Windows Server 2003 x86 RUS", "WindowsServer2003-KB943729-x86-RUS.exe"
поставился.
Запустить руками скрипт сразу не догадался. Если нужно - запущу.
Есть у Вас какие-нибудь идеи, как поправить код?
P.S. Картинка кликабельная.
Сегодня запустил в рабочей среде скрипт. На Windows XP русской всё прошло хорошо без запинки, а вот на Windows Server 2003 R2 SP2 ставиться из скрипта не стало по каким-то причинам. »
Ага. Есть такое дело. Сам понял, когда увидел у себя, что на 2003-м вылетает с ошибкой (я, правда, пускал не через GPO, а перебором). Я там в скрипте малость переборщил с упрощениями кода. Поправлю на днях.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.