среда, 9 апреля 2014 г.

VBScript: автоматизация поиска и установки обновлений Windows без участия пользователя

Нижеприведенный скрипт позволяет автоматизировать процесс установки обновлений Windows на только что проинсталлированную систему:

'''''''''''''''''''''''''''''''''''''     Auto Update VBScript for Windows      '''''''''''''''''''''''''''''''
'''
ON ERROR RESUME NEXT
''' Constants and variables
Attempt = 3                'Number of attempts to get updates
Const PauseTime = 15    'Number of minutes for pause between searching
Const HKEY_LOCAL_MACHINE = &H80000002
strUserName = "WinUpdate"
strFullName = "Windows Update Account"
strDescr = "Windows Update Account for AutoLogon"
strPassword = "1234567"
strGroupSID = "S-1-5-32-544"  'Well Known SID of the Administrators group
''' Detection OS and elevate privileges
SET colOS = GetObject("winmgmts:\root\cimv2").ExecQuery("Select * from Win32_OperatingSystem")
FOR EACH oOS IN colOS
    strOSLong = oOS.Version
NEXT
IF Left(strOSLong, 1) > "5" AND WScript.Arguments.length = 0 THEN
 SET oShellApp = CreateObject("Shell.Application")
 oShellApp.ShellExecute "cscript.exe", Chr(34) & WScript.ScriptFullName & Chr(34) & " uac", "//NoLogo //S", "runas", 1
 WScript.Quit
END IF
''' Copy script to Temp folder and restart them
SET WshNetwork = WScript.CreateObject("WScript.Network")
strComputer = WshNetwork.ComputerName
SET WshShell = WScript.CreateObject("WScript.Shell")
SET objFSO = CreateObject("Scripting.FileSystemObject")
IF NOT objFSO.FileExists(WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp\autoupdate.vbs") THEN 
 IF NOT objFSO.FolderExists(WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp") THEN 
  objFSO.CreateFolder(WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp")
 END IF
 objFSO.CopyFile Wscript.ScriptFullName, WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp\autoupdate.vbs", TRUE
 WshShell.Run "cscript //NoLogo //S " & WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp\autoupdate.vbs"
 WScript.Quit
ELSE
 IF Wscript.ScriptFullName <> WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp\autoupdate.vbs" THEN
  WshShell.Run "cscript //NoLogo //S " & WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp\autoupdate.vbs"
  WScript.Quit
 END IF
''' Preparing user for autologon
 WScript.Echo "Setup user....................................................................."
''' Check if local account already exists
 intExists = 0
 SET objSystem = GetObject("WinNT://" & strComputer)
 objSystem.Filter = Array("user")
 FOR EACH objUser IN objSystem
  IF objUser.Name = strUserName THEN
   intExists = 1
  END IF
 NEXT
'''  Finging correct title of admins group
 strGroupName = GetGroupName(strComputer, strGroupSID)
'''  Creating the user autoupdate
 IF intExists = 0 THEN
  SET objUser = objSystem.Create("user", strUserName)
  objUser.FullName = strFullName
  objUser.Description = strDescr
  objUser.SetPassword strPassword
  objUser.SetInfo
  SET objGroup = GetObject("WinNT://" & strComputer & "/" & strGroupName & ",group")
'''  Adding autoupdate to the admins group
  SET objUser = GetObject("WinNT://" & strComputer & "/" & strUserName & ",user")
  objGroup.Add(objUser.ADsPath)
 END IF
'''  Deleting the AutoLogonCount
 SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
 strValueName = "AutoLogonCount"
 oReg.DeleteValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName
'''  Setting forceAutoLogon to TRUE
 SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
 strValueName = "ForceAutoLogon"
 strValue = "1"
 oReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
''' Setting the default username to be the same as strUserName
 SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
 strValueName = "DefaultUserName"
 strValue = strUsername
 oReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
'''  Setting the default password to be same as strPassword
 SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
 strValueName = "DefaultPassword"
 strValue = strPassword
 oReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
'''  Setting AutoAdminLogon to TRUE
 SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
 strValueName = "AutoAdminLogon"
 strValue = "1"
 oReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
'''  Setting the default login domain to be the local machine
 SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
 strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
 strValueName = "DefaultDomainName"
 strValue = strComputer
 oReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
 '''  Setting AutoRun after reboot
 IF Left(strOSLong, 1) > "5" THEN
  WshShell.Run "%WINDIR%\system32\SCHTASKS.exe /Create /TN Autoupdater /TR ""cscript " & WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp\autoupdate.vbs //S //NoLogo"" /F /RL HIGHEST /IT /SC ONLOGON /RU " & strComputer & "\" & strUserName, 0
 ELSE
  SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
  strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
  strValueName = "autoupdate"
  strValue = "cscript //NoLogo //S " & WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp\autoupdate.vbs"
  oReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
 END IF
'''  Searching Updates
 WScript.Echo "Searching Updates:"
 DO
  Attempt = Attempt - 1
  WScript.Echo "Searching in progress...           (Number of remaining attempts is " & Attempt & ")"
  SET updateSession = createObject("Microsoft.Update.Session")
  SET updateSearcher = updateSession.CreateupdateSearcher()
  SET searchResult = updateSearcher.Search("IsHidden=0 and IsInstalled=0 and Type='Software'")
  IF searchResult.Updates.Count <> 0 OR Attempt = 0 THEN EXIT DO
  WScript.Echo "Waiting for " & PauseTime & " minutes before next searching..."
  WshShell.Run "%WINDIR%\system32\wuauclt.exe /detectnow", 0
  WScript.Sleep PauseTime*60000
 LOOP WHILE Attempt > 0
''' Downloading Updates
 IF Attempt > 0 THEN 'If there are updates for installing
  IF searchResult.Updates.Count <> 0 THEN
   WScript.Echo searchResult.Updates.Count & " updates are available."
  END IF
  flagDownload = 0
  FOR i = 0 To searchResult.Updates.Count-1
   SET update = searchResult.Updates.Item(i)
   IF update.IsDownloaded = FALSE THEN
    SET updatesToDownload = CreateObject("Microsoft.Update.UpdateColl")
    updatesToDownload.Add(update)
    IF updatesToDownload.Count = 1 AND flagDownload = 0 THEN
     WScript.Echo "Downloading Updates............................................................"
     flagDownload = 1
    END IF
    WScript.Echo "Downloading: " & update.Title
    SET downloader = updateSession.CreateUpdateDownloader() 
    downloader.Updates = updatesToDownload
    downloader.Download()
   END IF
  NEXT
''' Installing Updates
  WScript.Echo "Installing Updates............................................................."
  FOR i = 0 To searchResult.Updates.Count-1
   SET update = searchResult.Updates.Item(i)
   SET updatesToInstall = CreateObject("Microsoft.Update.UpdateColl")
   updatesToInstall.Add(update)  
   WScript.Echo "Installing: " & update.Title
   SET installer = updateSession.CreateUpdateInstaller()
   installer.Updates = updatesToInstall
   SET installationResult = installer.Install()
   IF ((installationResult.RebootRequired = TRUE) OR (Err.Number <> 0)) THEN
    WScript.Echo "Reboot after 3 seconds for complete installation of update!"
    WScript.Sleep 3000
    SET objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate,(Shutdown)}!\\" & strComputer & "\root\cimv2")
    SET colOperatingSystems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
    FOR EACH objOperatingSystem IN colOperatingSystems
     objOperatingSystem.Reboot()
    NEXT
   END IF
  NEXT
 ELSE 'If no more updates
  WScript.Echo "Cleaning script information..."
'''  Setting AutoAdminLogon to FALSE
  SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
  strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
  strValueName = "AutoAdminLogon"
  strValue = "0"
  oReg.SetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
'''  Deleting forceAutoLogon
  SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
  strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
  strValueName = "ForceAutoLogon"
  oReg.DeleteValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName
'''  Deleting AutoRun after reboot
  IF Left(strOSLong, 1) > "5" THEN
   WshShell.Run "%WINDIR%\system32\SCHTASKS.exe /Delete /TN Autoupdater /F", 0
  ELSE
   SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
   strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
   strValueName = "autoupdate"
   oReg.DeleteValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName
  END IF
'''  Deleting the default password to be same as strPassword
  SET oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
  strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
  strValueName = "DefaultPassword"
  oReg.DeleteValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName
'''  Deleting autoupdate user
  objSystem.Delete "user", strUserName
'''  Deleting temporary script file
  objFSO.DeleteFile(Wscript.ScriptFullName)
  SET fc = objFSO.GetFolder(WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp").Files
  IF 0 = fc.Count THEN
   objFSO.DeleteFolder(WshShell.ExpandEnvironmentStrings("%SystemDrive%") & "\Temp")
  END IF
 END IF
'''Finishing
 WScript.Echo "Complete, computer reboots after 5 seconds!"
 WScript.Sleep 5000
 SET objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate,(Shutdown)}!\\" & strComputer & "\root\cimv2")
 SET colOperatingSystems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
 FOR EACH objOperatingSystem IN colOperatingSystems
  objOperatingSystem.Reboot()
 NEXT
END IF
''''''''''''''''''Function for obtaining name of local Administrators group''''''''''''''''
FUNCTION GetGroupName(sComputer, sGroupSID)
 DIM oGroupAccounts, oGroupAccount
 SET oGroupAccounts = GetObject("winmgmts://" & sComputer & "/root/cimv2").ExecQuery("Select Name from Win32_Group" & " WHERE Domain = '" & sComputer & "' AND SID = '" & sGroupSID & "'")
 FOR EACH oGroupAccount IN oGroupAccounts
  GetGroupName = oGroupAccount.Name
 NEXT
END FUNCTION
''''''''''''''''''

Принцип работы следующий: Скрипт копирует себя в папку Temp и перезапускается с повышенными привилегиями в случае ОС Windows Vista и выше. Также, для автоматизации работы, создает пользователя WinUpdate и настраивает для него автоматический вход в систему, прописывается в автозапуск. Далее происходит поиск и установка обновлений, перезагрузка, и снова поиск и установка. Это длится до тех пор, пока скрипт не перестает находить новые обновления. Когда все попытки поиска исчерпаны, скрипт очищает все сделанные изменения в ОС и удаляется из папки Temp.
Управлять поиском можно с помощью переменной Attempt(количество предпринимаемых попыток поиска обновлений) и константы PauseTime(длина паузы между попытками поиска в минутах).
Скачать готовый vbs-файл можно по данной ссылке.

Комментариев нет:

Отправить комментарий