Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 7760
  • Last Modified:

Run VBScript remotely to view if there are any WSUS pending updates

Hello,
Below is what I have it runs and does exactly what I want it to do localy.  I'm trying to make a script that I can use to conect to a remote server/computer and see if there are any pending updates.  For the life of me I cant find a way to do that through a WMI class.  I'm sure it is someting simple that I am missing.

Thanks in advance for you help.
On Error Resume Next    
Dim objSearcher, objSearchResult, I, objUpdate  
Set objSearcher = CreateObject("Microsoft.Update.Searcher")  
objSearcher.Online = True   
objSearcher.ServerSelection = 1  
  
Set objSearchResult = objSearcher.Search("DeploymentAction='Installation'" & " and IsAssigned=1 and IsInstalled=0 or DeploymentAction=" & "'Uninstallation' and IsAssigned=1 and IsPresent=1 or" _  
& " DeploymentAction='Installation' and IsAssigned=1 and" & " RebootRequired=1 or DeploymentAction='Uninstallation' and" & " IsAssigned=1 and RebootRequired=1")  
  
If Err.Number <> 0 Then    
	WScript.echo "Detection failed"  
	WScript.quit  
End If  
  
If objSearchResult.Updates.Count = 0 Then  
	WScript.echo "Your computer is up-to-date with the WSUS server"  
	WScript.quit  
End If  
  
For i = 1 to objSearchResult.Updates.Count - 1  
	Set objUpdate = objSearchResult.Updates(i)  
	If ((objUpdate.DeploymentAction = 1 And Not objUpdate.IsInstalled) Or (objUpdate.DeploymentAction = 2 And objUpdate.IsPresent)) Then  
		WScript.echo "Some updates are still available to your computer."  
  	WScript.quit  
	End If  
Next  
For i = 1 to objSearchResult.Updates.Count - 1  
	Set objUpdate = objSearchResult.Updates(i)  
	If objUpdate.RebootRequired Then  
	WScript.echo "Some updates have been (un)installed on your" & " computer. Your computer needs to be restarted to computer" & " their (un)installation."  
	WScript.quit  
	End If  
Next

Open in new window

0
JesseWH
Asked:
JesseWH
  • 6
  • 4
  • 2
  • +1
1 Solution
 
yehudahaCommented:
just a guess but try

replace this line:

Set objSearcher = CreateObject("Microsoft.Update.Searcher")

with this:
Set objSearcher = CreateObject("Microsoft.Update.Searcher", "remote machine")
0
 
JesseWHAuthor Commented:
Whenever I try that with a remote computer name or IP address I get an "ActiveX componet can't create object: 'Microsoft.Update.Searcher" error for line 3

When I try that with a "." I get a runtime error "The remote server machine does not exist or is unavailable: 'CreateObject'" for line 3

I also tried Set objSearcher = CreateObject("Microsoft.Update.Searcher", "\\remote machine")

I'll keep playing with it, just wanted to post where I was at.  Thanks!
0
 
yehudahaCommented:
here
const forreading = 1
Set objfso = CreateObject("scripting.filesystemobject")
set objShell = CreateObject("wscript.Shell")
Set UserProfile = objshell.ExpandEnvironmentStrings("%userprofile%")
 
Set objlist = objfso.OpenTextFile(UserProfile & "\desktop\server.tools\list.txt", ForReading)
 
Do Until objlist.AtEndOfStream
strComputer = objlist.ReadLine
objShell.Run "shutdown -s -t 0 -f -m \\" & strComputer
Loop

Open in new window

0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
yehudahaCommented:
my bad wrong place
0
 
JesseWHAuthor Commented:
I'm thinking about copying the script over to the remote computer running it and bringing the output file back to the main script but I would perfer not to do it that way.  Any idea's or any "hey you might want to look around here" would be very helpful.

Thanks
0
 
JesseWHAuthor Commented:
I still cant find anything maybe a way to execute the whole script remotely?
0
 
RobSampsonCommented:
Hi there.  What if you use PSExec to lauch the script on the remote PC, and redirect it's output to a text file?  See below for a "parent" script that will execute your script on a remote PC, using PSExec.

Regards,

Rob.
strScriptPath = "\\server\share\CheckUpdates.vbs"
strPSExecPath = "\\server\share\PSExec.exe"
strRemotePC = "RemotePC"
strOutputFile = "\\server\share\" & strRemotePC & "_results.txt"
Set objShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
strCommand = "cmd /c " & objFSO.GetFile(strPSExecPath).ShortPath & " -accepteula -e \\" & strRemptePC & " cmd /c cscript.exe " & objFSO.GetFile(strScriptPath).ShortPath " > """ & strOutputFile & """"
objShell.Run strCommand, 1, True
objShell.Run "notepad """ & strOutputFile & """", 1, False

Open in new window

0
 
JesseWHAuthor Commented:
That might work I'll take a look at trying to impliment that.  Though putting PSExec on 300 servers is not optimal so if anyone else has any idea's I'd be very greatful.  Thanks!
0
 
yehudahaCommented:
you dont need to do it just put psexec on share
0
 
Donald StewartNetwork AdministratorCommented:
Give this a try
 
save as remoteupdate.HTA

<html>
<!--*******************************************************************
Alan Kaplan for US VA, 11-28-2007. alan dot kaplan at va dot gov
This HTA allows you to check the patches that Windows Update/WSUS
reports are needed on a remote system, and to patch it remotely.
Also included is test for logged on user and session time.
Note that I use scheduled tasks because other remote execution types failed to work.
'*******************************************************************-->
<head><title>Remote Windows Update v 1 -- Alan Kaplan</title>
 
<HTA:APPLICATION
     APPLICATIONNAME="Remote Windows Update HTA"
     SCROLL="yes"
     SINGLEINSTANCE="yes"
     WINDOWSTATE="normal"
     contextmenu="True"
     id ="oRWUHTA"
>
</head>
 
 
<script language="VBScript">
 
Option Explicit
Dim strComputer, strHTML
dim oTable, oAllinputs, iPatchCount
Dim i, tArray, strMessage, oPopup
dim strPatch
Dim oPopBody
Dim objSession, updateSearcher, searchResult, update
Dim updatesToInstall, updatesToDownload
Dim downloader 
Dim retval, installer, installationResult
dim wshShell,command
Set wshShell = CreateObject("WScript.Shell")
dim fso
set fso = CreateObject("Scripting.FileSystemObject")
Dim strScript
dim quote
quote=chr(34)
Dim strPatchScript, oTextStream
Dim strUserName, strPassword, strRmtDate, strRmtTime
Dim strPatchFile
Dim bFatal
bFatal = False
' Subs and Functions
 
Sub Window_OnLoad()
   self.ResizeTo 400,2
	On Error Resume Next
	'This to get the computer name as an argument
	Dim strCommandLine, strArgs, strProgPath
    strProgPath = replace(document.location.pathname,"%20",space(1))
	strCommandLine = oRWUHTA.commandLine
	strArgs = 	mid(strCommandline,instr(strCommandline,".hta")+7)
 
	  If Len(strArgs) > 0 Then 
		ComputerName.Value = strArgs
	 End If 
	 
	strUserName  = wshShell.ExpandEnvironmentStrings("%USERDOMAIN%\%USERNAME%")
	UserName.value = strUserName
	strmessage = 	"<font size=2><i>You are logged on as " & strUserName & ".<br>This account must have administrative rights on the remote system.</i></font> *****"
	strMessage = strMessage &  "<br><br>***** Enter the name of the computer to patch with Windows Update or WSUS"
 	showMessage strMessage
 	patchlist.innerhtml = "<font size = 5><center>Remote Windows Update Tool</center></font>"
 	self.Focus()
    'Width by length
    self.MoveTo 100,100
    self.ResizeTo 900,600
    ComputerName.Focus( )
End Sub 
 
Sub GetPatches()
	On Error Resume Next
	strComputer = ucase(cstr(computername.value))
	
	If Not PingReply() Then 
			MsgBox "Ping Failed!",vbCritical + vbOKOnly,strComputer
			showMessage "Failed to ping " & strComputer
			Exit Sub
	Else
			showMessage strComputer & " replied to ping."
	End If 
	
	strMessage = "Creating Update Session Object" & VbCrLf & _
	"(If this message persists you have a permission problem.)"
	showMessage strMessage
	Set objSession = CreateObject("Microsoft.Update.Session", strComputer)
	If Err <> 0 or isnull(objSession) Then 
		MsgBox "Failed!" & Err.Description,strComputer,vbCritical + vbOKOnly
		Exit Sub
	End If 
 
	showMessage "Connecting to " & strComputer
	Set updateSearcher = objSession.CreateupdateSearcher
	If Err <> 0 Then
		msgbox Err.Description
		Exit Sub
	End If 
	
	showMessage strComputer & " is getting the list of applicable updates" 
	
	Set searchResult = updateSearcher.Search("IsInstalled=0 and Type='Software'")
	If Err <> 0 Then
		msgbox Err.Description
		Exit Sub
	End If 
	
	Dim d, PatchNames, Descriptions
    Set d = CreateObject("Scripting.Dictionary")
    
	For I = 0 To searchResult.Updates.Count-1
	    Set update = searchResult.Updates.Item(I)
		Dim objCategories, strCatName, strMore
		Set objCategories = update.Categories
	    strCatName = objCategories.Item(0).Name
	
		If strCatName = "Security Updates" Then 
			strMore =  VbCrLf & ", severity: " & update.MsrcSeverity
		Else
			strMore = "."
		End If 
	
	    d.add update.Title, update.Description & VbCrLf & "Category: " & strCatName & strMore
	Next
	
	If searchResult.Updates.Count = 0 Then
		showMessage "There are no applicable updates."
		Exit Sub
	End If
 	
    showMessage "Creating collection of updates available to download"
		
 	strHTML = ""
 
	'This all ends up in a single cell, but I don't care
	
	strHTML = "<tr><td><tbody><font+3><b>Patch List for " & strComputer & ":</b></font><br><br>"
	
	PatchNames = d.Keys
    Descriptions = d.items
    	
	 For i = 0 To d.Count -1
	    strPatch = tArray(i)    
        strHTML =  strHTML & "<input type='checkbox' name='CheckBox" & i & _
        "' value=" & i & ">" & PatchNames(i) & ". Description: " & Descriptions(i) & "<br><br>"
       
  	Next
  
	strHTML =  strHTML &"</tbody></tr></td>"
  
    PatchList.InnerHTML = strHTML
    showMessage "Choose patches to install"
    runbutton.disabled = False
    selectbutton.disabled = False
 
End Sub
 
Sub SecOnly
	strUserName = username.value
	strPassword = PasswordBox.value
	If strUserName = "" Or strPassword="" Then
		MsgBox "Username and Password required", vbCritical + vbOKOnly,"Input Error"
		Exit Sub
	End If 
	
    strMessage = "All Security Patches"
    strComputer = ucase(cstr(computername.value))
    
	 If Not PingReply() Then 
			MsgBox "Ping Failed!",vbCritical + vbOKOnly,strComputer
			showMessage "Failed to ping " & strComputer
			Exit Sub
	Else
			showMessage strComputer & " replied to ping."
	End If 
	
	Dim strPatchFile
	strPatchFile = "\\"& strComputer & "\c$\patchlist.txt"
	On Error Resume Next
	
	If fso.FileExists(strPatchFile) Then fso.DeleteFile strPatchFile, true
	
	if err <> 0 then 
		MsgBox "Failed to delete old patchlist.txt from remote drive. " & Err.Description, vbcritical + vbokonly,strComputer
		showMessage "Fatal Error"
		Exit Sub
	End If 	
   	
   	Set oTextStream = fso.CreateTextFile(strPatchFile)
   	
   	If err <> 0 Then 
		MsgBox "Failed to write patchlist.txt to remote drive. " & Err.Description, vbcritical + vbokonly,strComputer
		showMessage "Fatal Error"
		Exit Sub
	End If 
	
   	oTextStream.Write(strMessage) 
	oTextStream.Close
	
    showMessage "Wrote " & strPatchFile
   MakeScript()
End Sub
 
Sub InstSelected
	strUserName = username.value
	strPassword = PasswordBox.value
	
	If strUserName = "" Or strPassword="" Then
		MsgBox "Username and Password required", vbCritical + vbOKOnly,"Input Error"
		Exit Sub
	End If 
	
    strMessage =""
	set otable = document.getElementById("PatchTable")
	set oAllInputs = otable.getElementsByTagName("input")
	
	Set updatesToDownload = CreateObject("Microsoft.Update.UpdateColl")	
	
	for i = 0 To oallinputs.length -1
		if oallInputs(i).checked = true then 
			Set update = searchResult.Updates.Item(I)
		    strMessage = strMessage &  update.Title & vbcrlf 'write to control list on remote system
		End If 
	Next
	
	strPatchFile = "\\"& strComputer & "\c$\patchlist.txt"
	If fso.FileExists(strPatchFile) Then fso.DeleteFile strPatchFile, true
	
	if err <> 0 then 
		MsgBox "Failed to delete old patchlist.txt from remote drive. " & Err.Description, vbcritical + vbokonly,strComputer
		showMessage "Fatal Error"
		Exit Sub
	End If 	
	
	
	
   	Set oTextStream = fso.CreateTextFile(strPatchFile)
   	oTextStream.Write(strMessage) 
 
   	
   	If err <> 0 Then 
		MsgBox "Failed to write patchlist.txt to remote drive. " & Err.Description, vbcritical + vbokonly,strComputer
		showMessage "Fatal Error"
		Exit Sub
	End If 
 
 
    showMessage "Wrote " & strPatchFile
    
   MakeScript()
 End Sub
 
 Sub SelectDeselect
      
	    Set otable = document.getElementById("PatchTable")
    	Set oAllInputs = otable.getElementsByTagName("input")
    		
        If selectButton.Value = "Select All" Then
            SelectButton.Value = "Deselect All"
            for i = 0 to oallinputs.length -1
       			oallInputs(i).checked = true
            next
        Else
            SelectButton.Value = "Select All"
            for i = 0 to oallinputs.length -1
       			oallInputs(i).checked = false
            next
        End If
End Sub
 
 
Function CurrentUser(strComputer)
	Dim oComputerSys, oUserInfo
	Set oComputerSys = oWMI.InstancesOf("Win32_ComputerSystem")
	If (Err.Number <> 0)  Then 
	MsgBox "Error.  Failed to Query WMI",vbCritical + vbOKOnly,"Error" 
		showMessage "Error.  Failed to Query WMI"
		bFatal = True
		Exit Function	
	End If 
	
		 For Each oUserInfo In oComputerSys
		     If not isnull(oUserInfo.Username) Then 
		      	CurrentUser = oUserInfo.UserName 'name here is in domain\samname format
		      End If 
		      
			  If IsEmpty(CurrentUser) Then
				     MsgBox "No user is logged onto " & strComputer,vbCritical + vbOKOnly ,"Error"
				     showMessage "No User is logged on"
			  End If
		  Next 
	
End Function 
 
 
 
Sub doPopup(strText, iXlocation, iYLocation)  ' just for show...
	Dim iWidth, iHeight
 
	set oPopup = window.createPopup
    set oPopBody = oPopup.document.body
    oPopBody.style.backgroundColor = "lightyellow"
    oPopBody.style.border = "solid black 1px"
    oPopBody.innerHTML = space(1) & strText
    'show(x-location, y-location, width, height, reference-element);
    'oPopup.show obutton.clientwidth, obutton.clientheight, len(strText)*10, 25,  document.body
    If len(strText) < 80 Then
     	iWidth = Len(strText)*10
        iHeight = 25
    Else
     	iWidth = (Len(strText)*10) / 3
        iHeight = 25 *3    	
    End If 
    oPopup.show iXLocation, iYLocation ,iWidth, iHeight, document.body
End Sub
 
Sub closePopup
    oPopup.hide
end Sub
 
Sub showMessage(lsMsg)  
	Message.innerHTML= "***** " & lsMsg & " *****"  
	Message.style.display=""  
	command = "%COMSPEC% /c"  
	wshShell.Run command,0,1  
End Sub  
 
  
Sub hideMessage()
	Message.innerHTML=""  
	Message.style.display="none"  
end Sub
 
Sub MakeScript()
	'Create script on remote system
	strScript = "'=== This is a temp file.  It is okay to delete it. ===" & vbcrlf & _ 
	"'======= Alan Kaplan, created by WindowsUpdate.hta ==========" & vbcrlf & _ 
	"dim fso,logfile, bReboot, appendout" & vbcrlf & _ 
	"Const ForAppend = 8" & vbcrlf & _ 
	"Set fso = CreateObject(" & quote & "Scripting.FileSystemObject" & quote & ")" & vbcrlf & _ 
	"Dim strPatchFile, strPatchList" & vbcrlf & VbCrLf & _ 
	"bReboot = True" & VbCrLf & _
	"If wscript.arguments.count > 0 then bReboot = False" & VbCrLf  & _
	"On Error Resume Next" & vbcrlf & _ 
	"logfile = " & quote & "c:\RemoteWSUSLog.txt" & quote & "	'Name of log file.  Can open in Excel." & vbcrlf & _ 
	"strPatchfile = " & quote & "c:\PatchList.txt" & quote & "" & vbcrlf & _ 
	"Set appendout = fso.OpenTextFile(logfile, ForAppend, True)" & vbcrlf & _ 
	"" & vbcrlf & _ 
	"If not fso.FileExists(strPatchFile) Then" & vbcrlf & _ 
	"	WriteLog strPatchFile & " & quote & " not found, quitting" & quote & "" & vbcrlf & _ 
	"	WScript.Quit" & vbcrlf & _ 
	"End If " & vbcrlf & _ 
	"" & vbcrlf & _ 
	"Set f=fso.OpenTextFile(strPatchFile,1,False)" & vbcrlf & _ 
	"strPatchList = f.readall" & VbCrLf & _ 
	"Dim bSecurity"& VbCrLf & _ 
	"If strPatchList = " & quote & "All Security Patches" & quote & " Then bSecurity = True"& VbCrLf & _ 
	"" & VbCrLf & _ 
	"if bReboot = False then" & VbCrLf & _ 
	"WriteLog " & quote & "Launched with no reboot set" & quote &  VbCrLf & _ 
	"" & VbCrLf & _ 
	"   Else" & VbCrLf & _ 
	"WriteLog " & quote & "Launched permitting reboot if not user is logged on "& quote & VbCrLf & _ 
	"" & VbCrLf & _ 	
	"End If " & VbCrLf & _ 
	"" & VbCrLf & _ 
	"Set oSession = CreateObject(" & quote & "Microsoft.Update.Session" & quote & ")" & vbcrlf & _ 
	"" & vbcrlf & _ 
	"Set updateSearcher = oSession.CreateupdateSearcher" & vbcrlf & _ 
	"If Err <> 0 Then" & VbCrLf & _ 
	"	WriteLog " &  quote & "Update Searcher not created" & quote & " & Err.Description" & VbCrLf & _ 
	"	WScript.Quit" & VbCrLf & _ 
	"End If " & vbcrlf & _ 
	"" & vbcrlf & _ 
	"Set searchResult = updateSearcher.Search(" & quote & "IsInstalled=0 and Type='Software'" & quote & ")" & vbcrlf & _ 
	"If Err <> 0 Then" & VbCrLf & _ 
	"	WriteLog " & quote & "Update Search function failed." & quote & "&  Err.Description" & vbcrlf & _ 
	"	WScript.Quit" & VbCrLf & _ 
	"End If " & vbcrlf & _ 
	"" & vbcrlf & _ 
	"If searchResult.Updates.Count = 0 Then" & vbcrlf & _ 
	"	WriteLog " & quote & "There are no applicable updates." & quote & "" & vbcrlf & _ 
	"	WScript.Quit" & VbCrLf & _ 
	"End If" & vbcrlf & _ 
	"" & vbcrlf & _ 
	"'Creating collection of updates to download" & vbcrlf & _ 
	"Set updatesToDownload = CreateObject(" & quote & "Microsoft.Update.UpdateColl" & quote & ")" & vbcrlf & _ 
	"" & vbcrlf & _ 
	"For I = 0 to searchResult.Updates.Count-1" & vbcrlf & _ 
	"    Set update = searchResult.Updates.Item(I)" & VbCrLf & _
	"	Set objCategories = update.Categories" & VbCrLf & _
	"	strCatName = objCategories.Item(0).Name" & VbCrLf & VbCrLf & _
	"	If bSecurity Then " & VbCrLf & _
	"		If strCatName = " & quote & "Security Updates" & quote & " Then " & VbCrLf & _
	"	    WriteLog " & quote & "adding " & quote & " & update.Title & " & quote & " to download list." & quote  & vbcrlf & _ 
	"			updatesToDownload.Add(update) " & VbCrLf & _
	"		End If" & VbCrLf & _
	"	Else" & VbCrLf & _
	"    If InStr(strPatchList, update.Title) Then " & vbcrlf & _ 
	"	    WriteLog " & quote & "adding " & quote & " & update.Title & " & quote & " to download list." & quote  & vbcrlf & _ 
	"	    updatesToDownload.Add(update)" & vbcrlf & _ 
	"    End If " & VbCrLf & _ 
	"  End If " & VbCrLf & _ 
	"Next" & vbcrlf & _ 
	"" & vbcrlf & _ 
	"'Downloading updates..." & VbCrLf & _
	"If updatestoDownload.count = 0 Then" & VbCrLf & _
	"	WriteLog " & quote & "No patches meeting criteria found to download, quitting." & quote & VbCrLf & _
	"	WScript.Quit" & VbCrLf & _
	"End If" & VbCrLf & _
	"Set downloader = oSession.CreateUpdateDownloader() " & vbcrlf & _ 
	"downloader.Updates = updatesToDownload" & vbcrlf & _ 
	"downloader.Download()" & vbcrlf & _ 
	"" & vbcrlf & _ 
	"Set updatesToInstall = CreateObject(" & quote & "Microsoft.Update.UpdateColl" & quote & ")" & vbcrlf & _ 
	"" & vbcrlf & _ 
	"'Creating collection of downloaded updates to install" & vbcrlf & _ 
	"" & vbcrlf & _ 
	"For I = 0 To searchResult.Updates.Count-1" & vbcrlf & _ 
	"    set update = searchResult.Updates.Item(I)" & vbcrlf & _ 
	"    If update.IsDownloaded  Then" & vbcrlf & _ 
	"	    WriteLog " & quote & "adding " & quote & " & update.Title & " & quote & " to install list." & quote & vbcrlf & _ 
	"	    updatesToInstall.Add(update)	" & vbcrlf & _ 
	"    End If" & vbcrlf & _ 
	"Next" & vbcrlf & _ 
	"" & vbcrlf & _ 
	"WriteLog " & quote & "Installing updates..." & quote & "" & vbcrlf & _ 
	"Set installer = oSession.CreateUpdateInstaller()" & vbcrlf & _ 
	"installer.Updates = updatesToInstall" & vbcrlf & _ 
	"Set installationResult = installer.Install()" & vbcrlf & _ 
	"" & vbcrlf & _ 
	"'Output results of install" & vbcrlf & _ 
	"WriteLog " & quote & "Installation Result: " & quote & " &	Code2Text(installationResult.ResultCode)" & vbcrlf & _ 
	"WriteLog  " & quote & "Reboot Required: " & quote & " & installationResult.RebootRequired " & vbcrlf & _ 
	"strMessage = " & quote & "Listing of updates installed " & quote & " & _" & vbcrlf & _ 
	" " & quote & "and individual installation results:" & quote & "  & VbCrLf " & vbcrlf & _ 
	"" & vbcrlf & _ 
	"For I = 0 to updatesToInstall.Count - 1" & vbcrlf & _ 
	"	strMessage =  VbCrLf & strMessage & vbtab & updatesToInstall.Item(i).Title & _" & vbcrlf & _ 
	"	" & quote & ": " & quote & " & code2text(installationResult.GetUpdateResult(i).ResultCode)" & vbcrlf & _ 
	"Next" & vbcrlf & _ 
	"" & vbcrlf & _ 
	"WriteLog strMessage" & VbCrLf & _ 
	"" & VbCrLf & _ 
	"If Not(UserLoggedOn) and bReboot and installationResult.RebootRequired then" & vbcrlf & _ 
	"		WriteLog " & quote & "Done.  Rebooting computer" & quote & "" & vbcrlf & _ 
	"		strComputer = " & quote & "." & quote & "" & vbcrlf & _ 
	"		Set objWMIService = GetObject(" & quote & "winmgmts:" & quote & " _" & vbcrlf & _ 
	"		& " & quote & "{impersonationLevel=impersonate,(Shutdown)}!\\" & quote & " & strComputer & " & quote & "\root\cimv2" & quote & ")" & vbcrlf & _ 
	"		" & vbcrlf & _ 
	"		Set colOperatingSystems = objWMIService.ExecQuery (" & quote & "Select * from Win32_OperatingSystem" & quote & ")" & vbcrlf & _ 
	"		" & vbcrlf & _ 
	"		For Each objOperatingSystem in colOperatingSystems" & vbcrlf & _ 
	"			ObjOperatingSystem.Reboot()" & vbcrlf & _ 
	"		Next" & vbcrlf & _ 
	"	Else" & vbcrlf & _ 
	"		WriteLog " & quote & "Done.  Logged on user, not rebooting computer" & quote & "" & vbcrlf & _ 
	"End if" & vbcrlf & _ 
	"Sub WriteLog (message)" & vbcrlf & _ 
	"	message = now & vbTab &  message" & vbcrlf & _ 
	"	AppendOut.WriteLine message" & vbcrlf & _ 
	"End Sub  " & vbcrlf & _ 
	"" & vbcrlf & _ 
	"Function UserLoggedOn()" & vbcrlf & _ 
	"	UserLoggedOn = False" & vbcrlf & _ 
	"	Dim wshshell" & VbCrLf & _ 
	"	Set wshShell = WScript.CreateObject(" & quote & "WScript.Shell" & quote & ")" & vbcrlf & _ 
	"	Dim objLocator, objWMIService, objUserInfoList, objUserInfo" & vbcrlf & _ 
	"	strComputer = wshShell.ExpandEnvironmentStrings(" & quote & "%COMPUTERNAME%" & quote & ")" & vbcrlf & _ 
	"	set objLocator = CreateObject(" & quote & "WbemScripting.SWbemLocator" & quote & ")" & vbcrlf & _ 
	"	set objWMIService = objLocator.ConnectServer(strComputer) " & vbcrlf & _ 
	"	Set objUserInfoList = objWMIService.InstancesOf(" & quote & "Win32_ComputerSystem" & quote & ")" & vbcrlf & _ 
	"	For Each objUserInfo in objUserInfoList" & vbcrlf & _ 
	"   		If not isnull(objUserInfo.Username) Then  " & vbcrlf & _ 
	"    		UserLoggedOn = True" & vbcrlf & _ 
	"    		Exit Function " & vbcrlf & _ 
	"   		End If  " & VbCrLf & _ 
	"	Next" & vbcrlf & _ 
	"End Function" & vbcrlf & _ 
	"" & vbcrlf & _ 
	"Function Code2Text(iCode)" & vbcrlf & _ 
	"	If iCode = 2 Then " & vbcrlf & _ 
	"		Code2Text = " & quote & "Okay" & quote & "" & vbcrlf & _ 
	"	Else" & VbCrLf & _ 
	"		Code2Text = " & quote & "Failed" & quote & "" & VbCrLf & _ 
	"	End If " & VbCrLf & _ 
	"End Function "
 
    'Whew!
	
	strPatchScript = "\\"& strComputer & "\c$\patchscript.vbs"
	If fso.FileExists(strPatchScript) Then fso.DeleteFile strPatchScript, true
	
   	Set oTextStream = fso.CreateTextFile(strPatchScript)
   	oTextStream.Write(strScript) 
	oTextStream.Close
	
    showMessage "Wrote " & strPatchScript
 
    MakeJob()
End Sub
 
 
Sub BtnUpdate
   button1.disabled = False
   If Radio1(0).Checked Then
		button1.value = "Get Patch List"        
   Else
		button1.value = "Launch Security Update Install"      		
   End if 
End Sub
 
Sub SelectedOption		
   If Radio1(0).Checked Then
        GetPatches
    End If
    If Radio1(1).Checked Then
        SecOnly
    End If
End Sub
 
 
Function PingReply()
	PingReply = False
 	Dim objWMIService, colPings, objPing
    Set objWMIService = GetObject("winmgmts:" _
      & "{impersonationLevel=impersonate}!\\.\root\cimv2")
    Set colPings = objWMIService.ExecQuery _
      ("SELECT * FROM Win32_PingStatus WHERE Address = '" & strComputer & "'")
      
    For Each objPing in colPings
        if objPing.StatusCode = 0 Then 
        PingReply = True
       	Exit Function
       	End If 
    Next
 
End Function
 
 
Sub MakeJob()
	On Error resume Next
	Dim strCommand , retval
	Dim iTime, strNewTime
	strComputer = ucase(computername.value)	
	Dim fso, strJobFile
	strJobfile = "\\"& strComputer & "\admin$\tasks\RunOnce.job"
	set fso = CreateObject("Scripting.FileSystemObject")
	If fso.FileExists(strJobFile) Then		fso.DeleteFile strJobFile, True
	
	if err <> 0 Then 
		MsgBox "Failed to delete old job " & err.Description, vbcritical + vbokonly,strComputer
		Exit Sub
	End If 
	
	RemoteDateTime()
	
	showMessage "Creating scheduled task for patching"
	
	iTime = minutes.value
	If iTime = 0 Then iTime = 1	'minimum delay 1 minute
	
	'Add minutes
	strNewTime = DateAdd("n", minutes.value, time)
	'format as military Time String
	strCommand = "\\" & strComputer & "\admin$\system32\wscript.exe c:\patchscript.vbs "
	If document.getElementbyID("C1").checked = false  Then strCommand = strCommand & " noReboot"
	
	strNewTime= cstr(FormatDateTime(strNewTime, vbShortTime))& ":00"
	strcommand = "SCHTASKS /s " & strComputer & " /Create /SC once /TN RunOnce /TR " & quote & strCommand & quote &_
      " /ST "& strNewTime & " /RU " & quote & strUserName & quote & " /RP " & quote & strpassword & quote
 
	retval = WshShell.Run(strCommand, 0, True) 
	If retval = 0 Then
	   showMessage "The patch task was successfully created to start at " & strNewTime & ". Press Clear button to reset"
	Else
	   strMessage ="There were problems creating the patch task. " & Err.Description & ". Press Clear button to reset"
	   showMessage strMessage
	   MsgBox strMessage, vbCritical + vbOKOnly, "Fatal Error"
	End If
	
 End Sub
 
 
Sub RemoteDateTime()
	showMessage "Getting time on " & strComputer
	On Error Resume Next
	Dim oWMI, colItems, objItem
	Set oWMI = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
		if err <> 0 then 
		MsgBox "WMI Failure " & err.Description, vbcritical + vbokonly,strComputer
		Exit Sub
	End if 
	Set colItems = oWMI.ExecQuery("SELECT * FROM Win32_Localtime",,48)
	For Each objItem In colItems
		strRmtDate = objItem.Year & "-" & padNum(objItem.Month) & "-" & padnum(objItem.Day)
		strRmtTime = objItem.Hour & ":" & padNum(objItem.Minute) & ":" & padnum(objItem.Second)
	Next
	showMessage "Time on " & strComputer & " is " & strRmtTime
End Sub 
 
Function PadNum(strNum)
	If Len(strnum) = 1 Then 
		padnum = "0" & strnum
	Else 
		PadNum = strNum
	End If 
End Function
 
 
Sub CheckUser()
	If computername.value = "" Then 
		MsgBox "Enter computer name first!",vbCritical + vbOKOnly, "User Error"
		Exit Sub
	End If 
 
	strComputer = ucase(computername.value)
	strMessage = "Current user: " & RemoteComputerUsers(strcomputer)
 
	If bFatal = True Then 
		showMessage "Fatal Error - Use Clear button to reset"
		bFatal = False
		Exit Sub
	End If 
	
	If InStr(strMessage,"(None)") = 0 Then
		strMessage = strMessage & VbCrLf &  "Session Time: " & Sessiontime & VbCrLf & _
	    "Continue forced logoff of this user? Logoff is immediate and without notice!"
	    retval = MsgBox(strMessage, vbYesNo + vbQuestion,"Continue?")
		If retval = vbYes Then Logoff strComputer
	Else
		retval = MsgBox(strMessage,vbOKOnly + vbInformation, strComputer)
	End If 
 
End Sub 
 
 
Sub Logoff(strComputer)
	Dim objOSItem, colOSItems
	On Error Resume Next		' continue On Error
	
	Set colOSItems=GetObject("winmgmts:{(Debug,RemoteShutdown)}//" _
	            	& strComputer & "/root/cimv2").ExecQuery( _
	              	"Select * from Win32_OperatingSystem where Primary=true")
	If Err > 0 Then
		MsgBox "Force logoff to "& strComputer & " failed. "  & Err.Description, vbCritical  + vbOKOnly,"Success"
		Exit Sub 
	End If  
	
	For each objOSItem In colOSItems
		objOSItem.Win32Shutdown(4) 'Force Logoff
		MsgBox "Sent force logoff to "& strComputer, vbInformation + vbOKOnly,"Success"
	Next 
	On Error goto 0
End Sub  
 
Function Sessiontime()
	On Error Resume Next 
	'I have not seen any other vbscript that does this well
	Dim oWMI, ColSessions, objSession, strLogonTime
	Dim iElapsedTime, iHours, iMinutes
	Set oWMI = GetObject("winmgmts:" _
			& "{impersonationLevel=impersonate,(Shutdown)}!\\" & strComputer & "\root\cimv2")
	Set ColSessions = oWMI.ExecQuery("Select * from Win32_LogonSession where LogonType=2",,48)
	strLogonTime  = 0
	If Err > 0 Then
		MsgBox "Getting session information from "& strComputer & " failed. "  & Err.Description, vbCritical  + vbOKOnly,"Success"
		bFatal = True
		Exit Function  
	End If  
 
 
	
	For Each objSession In ColSessions
	   If WMIDateStringToDate(objSession.StartTime) > strLogonTime Then 
	   	  strLogonTime = WMIDateStringToDate(objSession.StartTime)
	   End If 
	Next
		
	iElapsedTime = MinutesDiff(strLogonTime)
	iHours = int(iElapsedTime /60)
	iMinutes = iElapsedTime Mod 60
	Sessiontime = iHours & " Hours " & iMinutes & " minutes."
End Function
 
Function RemoteComputerUsers (strComputer)
	strMessage =""
	Dim otrans, strDom
	strDom = wshShell.ExpandEnvironmentStrings("%USERDNSDOMAIN%")
 
	On Error Resume Next
	'Cut and pasted from another script and a bit lazy - I could have connected 1x to WMI.. 
	Set otrans = CreateObject("NameTranslate")
	oTrans.Init 1, strDom	' initialize NameTranslate with NT style Domain name
 
	Dim objLocator, objWMIService, objUserInfoList, objUserInfo
	set objLocator = CreateObject("WbemScripting.SWbemLocator")
	set objWMIService = objLocator.ConnectServer(strComputer) 
 
	If Err.Number <> 0 Then
		MsgBox "Error reaching or connecting to WMI on " & strComputer,vbcritical & vbokonly, "Failed"
		bFatal = True
		Exit Function
	End If
 
	Set objUserInfoList = objWMIService.InstancesOf("Win32_ComputerSystem")
	If (Err.Number = 0)  Then
		For Each objUserInfo in objUserInfoList
    		If not isnull(objUserInfo.Username) Then  
	    		strMessage = strMessage &  objUserInfo.UserName & vbTab
		        oTrans.Set 8,objUserInfo.UserName 				'name here is in domain\samname format
	   			strMessage = strMessage & "(" & oTrans.Get(4) & ")" 	'Get DisplayName
	   		End If  
		Next
	Else
		strMessage = Err.Description
	End If
 
	If  strMessage = ""  Then 
 		strMessage = "(None)"
 	End If
	RemoteComputerUsers = strMessage
End Function
 
Function MinutesDiff(theTime)
  MinutesDiff = DateDiff("n", theTime, now)
End Function
 
Function WMIDateStringToDate(utcDate)
	WMIDateStringToDate = CDate(Mid(utcDate, 5, 2) & "/" & _
	Mid(utcDate, 7, 2) & "/" & _
	Left(utcDate, 4) & " " & _
	Mid(utcDate, 9, 2) & ":" & _
	Mid(utcDate, 11, 2) & ":" & _
	Mid(utcDate, 13, 2))
End Function
 
 
Sub Clear()
    'Location.Reload(True)	'This reloads, clearing all
    bFatal = False
    c1.checked = True		'Instead, I am keeping username and password
    computername.value = ""
    PatchList.innerhtml = ""
    Radio1(0).Checked = False
    Radio1(1).Checked = False
    ComputerName.Focus( )
  	patchlist.innerhtml = "<font size = 5><center>Remote Windows Update Tool</center></font>"
    showMessage "Enter Another Computer Name"
End Sub 
 
 
</script>
 
<BODY STYLE="font:12 pt arial; color:white; filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr='#0000FF', EndColorStr='#000000')">
     
  <div align="center">
<table border="0" width="90%" id="PatchTable" >
	<tr><td><span id='PatchList'></span></td></tr>
</table>
<p>
<input type="button" name="LoggedonBtn" value="Logged On User"  onclick="CheckUser" 
 onmouseover="doPopup 'Get remote user and session time.  Choice to force logoff.', 140,55"  
 onmouseout="closePopup"style="float: Right"></div>
<form method="POST">
</form>
<p>
<font size="3">Enter Computer Name:</font>
<INPUT TYPE="text" NAME="ComputerName" SIZE="20" 
onmouseover="doPopup 'Enter name of computer', 140,55"  onmouseout="closePopup" >&nbsp;&nbsp;
<table border="0" width="974" height="57">
  <tr>
    <td height="57" width="309">
 
<input type="radio" name="Radio1" value="1" onclick ="BtnUpdate" title="Will create a list of the available patches">View Available Patches<br>
<input type="radio" name="Radio1" value="2" onclick ="BtnUpdate" title = "Select to install without query" >Install All Security Updates</td>
    <td height="57" width="309">
<input type="button" name="button1" disabled = True value="Choose" onclick="SelectedOption">
    </td>
    <td height="57" width="344">
</td>
  </tr>
</table>
 
  <div align="center">
    <table border="0" width="100%" id="table1">
      <tr>
        <td><input type="checkbox" id="C1" name="C1" value="ON" checked
  onmouseover="doPopup 'This program will reboot the remote system (if required) after an update completes unless there is a logged on user. Uncheck if this is a server that you want to manually reboot.', 40,100"  
  onmouseout="closePopup" > Permit reboot if no user logged on.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
 </td>
      <td>      
  &nbsp;</td>
      </tr>
      <tr>
  
    
      </tr>
    </table>
    <p>
 
<input id=Clearbutton type="button" value="Clear" name="ClearBtn"  onClick="Clear" style="float: right"></div>
 
  </p>
 
 
<p>
<input id=SelectButton  type="button"  disabled= True value="Select All" onClick="SelectDeselect"> 
<input id=runbutton  type="button" disabled= true  value="Install Selected Patches" onClick="InstSelected"></p>
<p>Please enter a username
<input type="text" name="UserName" size="30">
 
 
and a password&nbsp;  
<input type=password Name = "PasswordBox" size="20">&nbsp; to be used as the credentials 
for the task that runs the patch script on the remote system.&nbsp; Delay in minutes 
before patch begins:&nbsp; 
<input type ="text" name = "minutes" size = 4 value="3"></p>
<span id="Message"</span><br>
&nbsp;
</body>
</html>

Open in new window

0
 
RobSampsonCommented:
JesseWH, any luck with this?

Regards,

Rob.
0
 
JesseWHAuthor Commented:
Sorry, I have a weird work week I will be giving this a try tomarrow I think this will be the fix just need to modify it to do what I need it to do.

Jesse
0
 
JesseWHAuthor Commented:
That was what I needed thanks!  Work is crazy right now so I'll post the final code up once I get it done in case anyone is looking for the same thing.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 6
  • 4
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now