I am configuring Automatic Updates on my servers via GPO however I would prefer to install once a month rather than "Every" monday, tuesday, etc?

Hello EE,

I would like to limit my server reboots and schedule them around our maintenance window.
Currently I have GPO set to 4 to auto download and schedule the install, but my only options are "every" (select day of week) and I'd like to schedule it the last x of the month type of thing.  Is this possible?
operationsITAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Gabriel CliftonNet AdminCommented:
What I do is I have a scheduled task that runs one script that installs updates and another one that checks if an update needs a reboot and reboots my servers at scheduled times if needed. I am not in my office right now to post the scripts.
operationsITAuthor Commented:
@Gabriel so every server you have created 2 tasks (or using same 2 scripts)?
I would be interested if you wouldn't mind sharing the scripts when you are in to see if this would work for me as well.  The weekly thing on my servers is just to much troubleshooting of what updates are breaking the next day :-)
Gabriel CliftonNet AdminCommented:
OK, I am back at my office.
Code for installing updates. Use scheduled task to run this with cscript.
ServerUpdates.vbs
Set updateSession = CreateObject("Microsoft.Update.Session")
updateSession.ClientApplicationID = "MSDN Sample Script"

Set updateSearcher = updateSession.CreateUpdateSearcher()

WScript.Echo "Searching for updates..." & vbCRLF

Set searchResult = _
updateSearcher.Search("IsAssigned=1 and IsInstalled=0 and Type='Software' and IsHidden=0")

WScript.Echo "List of applicable items on the machine:"

For I = 0 To searchResult.Updates.Count-1
    Set update = searchResult.Updates.Item(I)
    WScript.Echo I + 1 & "> " & update.Title
Next

If searchResult.Updates.Count = 0 Then
    WScript.Echo "There are no applicable updates."
    WScript.Quit
End If

WScript.Echo vbCRLF & "Creating collection of updates to download:"

Set updatesToDownload = CreateObject("Microsoft.Update.UpdateColl")

For I = 0 to searchResult.Updates.Count-1
    Set update = searchResult.Updates.Item(I)
    addThisUpdate = false
    If update.InstallationBehavior.CanRequestUserInput = true Then
        WScript.Echo I + 1 & "> skipping: " & update.Title & _
        " because it requires user input"
    Else
        If update.EulaAccepted = false Then
            WScript.Echo I + 1 & "> note: " & update.Title & _
            " has a license agreement that must be accepted:"
            WScript.Echo update.EulaText
            WScript.Echo "Do you accept this license agreement? (Y/N)"
            strInput = WScript.StdIn.Readline
            WScript.Echo 
            If (strInput = "Y" or strInput = "y") Then
                update.AcceptEula()
                addThisUpdate = true
            Else
                WScript.Echo I + 1 & "> skipping: " & update.Title & _
                " because the license agreement was declined"
            End If
        Else
            addThisUpdate = true
        End If
    End If
    If addThisUpdate = true Then
        WScript.Echo I + 1 & "> adding: " & update.Title 
        updatesToDownload.Add(update)
    If update.EulaAccepted = False Then 
        update.AcceptEula
        WScript.Echo I + 1 & ">     Accept EULA " & update.Title 
		End If
		End If
		Next

If updatesToDownload.Count = 0 Then
    WScript.Echo "All applicable updates were skipped."
    WScript.Quit
End If
    
WScript.Echo vbCRLF & "Downloading updates..."

Set downloader = updateSession.CreateUpdateDownloader() 
downloader.Updates = updatesToDownload
downloader.Download()

Set updatesToInstall = CreateObject("Microsoft.Update.UpdateColl")

rebootMayBeRequired = false

WScript.Echo vbCRLF & "Successfully downloaded updates:"

For I = 0 To searchResult.Updates.Count-1
    set update = searchResult.Updates.Item(I)
    If update.IsDownloaded = true Then
        WScript.Echo I + 1 & "> " & update.Title 
        updatesToInstall.Add(update) 
        If update.InstallationBehavior.RebootBehavior > 0 Then
            rebootMayBeRequired = true
        End If
    End If
Next

If updatesToInstall.Count = 0 Then
    WScript.Echo "No updates were successfully downloaded."
    WScript.Quit
End If

REM If rebootMayBeRequired = true Then
    REM WScript.Echo vbCRLF & "These updates may require a reboot."
REM End If

REM WScript.Echo  vbCRLF & "Would you like to install updates now? (Y/N)"
REM strInput = WScript.StdIn.Readline
REM WScript.Echo 

REM If (strInput = "Y" or strInput = "y") Then
    WScript.Echo "Installing updates..."
    Set installer = updateSession.CreateUpdateInstaller()
    installer.Updates = updatesToInstall
    Set installationResult = installer.Install()
 
    'Output results of install
    WScript.Echo "Installation Result: " & _
    installationResult.ResultCode 
    WScript.Echo "Reboot Required: " & _ 
    installationResult.RebootRequired & vbCRLF 
    WScript.Echo "Listing of updates installed " & _
    "and individual installation results:" 
 
    For I = 0 to updatesToInstall.Count - 1
        WScript.Echo I + 1 & "> " & _
        updatesToInstall.Item(i).Title & _
        ": " & installationResult.GetUpdateResult(i).ResultCode   
    Next
REM End If

Open in new window

TestForUpdateReboot.bat
@echo off
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired"2>nul && goto found || goto :eof

:found
shutdown /f /r /t 20 /c "Windows Update Reboot" /d p:2:17

Open in new window

On my Server 2008 and newer servers, I have both scripts in one scheduled task, you can separate them if you want the install to happen one day and the reboot another. The first script will look for updates (from WSUS or Microsoft if WSUS is not available) and installs them, but will not reboot.
The second script looks for the flag in the registry that updates are needing the computer to reboot and if found will reboot the server, if not the script will just exit.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

operationsITAuthor Commented:
Thank you so much I will test now.  As for Control Panel > Windows Updates what do you have this set to?
Gabriel CliftonNet AdminCommented:
I have it set to "Download updates but let me choose whether to install them"
operationsITAuthor Commented:
I am testing it now but it's been at "searching for updates" for 2 hours.  How long did yours take?
Gabriel CliftonNet AdminCommented:
2 hours can be a little long, but it usually depends on how many updates there are. I have had a little as 15 minutes for one update and around 1 hour to 1-1/2 hour for many.
operationsITAuthor Commented:
Let it run all night and still sitting at searching for updates...
Gabriel CliftonNet AdminCommented:
How long does it take for the server to search for updates manually? You are running it with cscript.exe and not wscript.exe right. I have tested the code posted on a few systems and workstations and it appears to be working fine. I have attached the same script that I use just in case of some weird copy paste problem on posting. I find these scripts to be invaluable and I want it to work the same for you.
ServerUpdate.vbs
operationsITAuthor Commented:
Thanks I will try that.  Can you share how I can confirm it is with cscript as I believe I did set it up right.
operationsITAuthor Commented:
I am starting a program C:\windows\system32\cscript.exe with the argument serverupdates.vbs
Gabriel CliftonNet AdminCommented:
Have you tried manually running the script from command line? Have you tried with other systems? How long does it take to search for Windows updates when you manually check without script?
operationsITAuthor Commented:
runs find from command line.  Are you running cscript as a program and the .vbs as an argument??
Gabriel CliftonNet AdminCommented:
I do have
Run with hightest privileges checked
Action: Start a program
Program/script: cscript.exe
Add arguments: "PathToVBS\ServerUpdate.vbs"
Scheduled Task Action
operationsITAuthor Commented:
This is fabulous thank you so much for sharing!
Gabriel CliftonNet AdminCommented:
No problem, I enjoy it as well.
operationsITAuthor Commented:
@Gabriel, I am trying to run this on other servers and getting an error on line 8 field 1.  Any ideas?
Gabriel CliftonNet AdminCommented:
The script is a modified version of this one from MSN https://msdn.microsoft.com/en-us/library/windows/desktop/aa387102(v=vs.85).aspx, you can try the original to see if it work for you and modify from there.
Gabriel CliftonNet AdminCommented:
Testing the script a bit, I have found that "IsAssigned=1 and " in line 9 can cause an error. This usually works for me with it there but you may see this as your issue. Just remove that part. Also, you can change the "Type='Software'" to "Type='Driver'" to download drivers, or remove that to search for both. The "IsHidden=0" will not install updates that you have manually hidden.
operationsITAuthor Commented:
Ok tried that and it actually is the line before it actually where it is failing (line 8 character 1)
I've tried the suggestions you made and the one direct off line.  Just curious if you would have any thoughts.  I"ll continue to poke as I feel I'm close and you've been so helpful!
operationsITAuthor Commented:
One note is we use a WSUS server so don't actually go to windows online for updates
Gabriel CliftonNet AdminCommented:
I have been working on this one, give it a try. On line 15 you can specify WSUS (ssManagedServer), Microsoft (ssWindowsUpdate), or anything else from lines 2-5.

'ServerSelection values 
ssDefault = 0 
ssManagedServer   = 1 
ssWindowsUpdate   = 2 
ssOthers          = 3 
 
'InStr values 
intSearchStartChar = 1
 
dim strTitle 
 
Set updateSession = CreateObject("Microsoft.Update.Session") 
Set updateSearcher = updateSession.CreateupdateSearcher() 
 
updateSearcher.ServerSelection = ssManagedServer
Set searchResult = updateSearcher.Search("IsInstalled=0 and IsHidden=0") 
 
WScript.Echo "List of applicable items on the machine:" 
 
For I = 0 To searchResult.Updates.Count-1 
    Set update = searchResult.Updates.Item(I) 
    WScript.Echo I + 1 & "> " & update.Title 
Next 
 
If searchResult.Updates.Count = 0 Then 
    WScript.Echo "There are no applicable updates." 
    WScript.Quit 
End If 
 
WScript.Echo vbCRLF & "Creating collection of updates to download:" 
 
Set updatesToDownload = CreateObject("Microsoft.Update.UpdateColl") 
 
For I = 0 to searchResult.Updates.Count-1 
    Set update = searchResult.Updates.Item(I) 
    addThisUpdate = False
    Select Case update.Title
    Case "Internet Explorer 11 for Windows 7" 
        WScript.Echo I + 1 & "> skipping: " & update.Title & _ 
        " because of specified requirements"
        addThisUpdate = False
    Case "Internet Explorer 10 for Windows 7" 
        WScript.Echo I + 1 & "> skipping: " & update.Title & _ 
        " because of specified requirements"
        addThisUpdate = False
    Case Else
    	If update.InstallationBehavior.CanRequestUserInput = true Then 
	        WScript.Echo I + 1 & "> skipping: " & update.Title & _ 
	        " because it requires user input" 
    	Else
			If update.EulaAccepted = false Then 
            	WScript.Echo I + 1 & "> note: " & update.Title & _ 
            	" has a license agreement that must be accepted:" 
            	WScript.Echo update.EulaText 
'            	WScript.Echo "Do you accept this license agreement? (Y/N)" 
            	''strInput = WScript.StdIn.ReadLine 
            	strInput = "Y" 
            	WScript.Echo  
	            If (strInput = "Y" or strInput = "y") Then 
	                update.AcceptEula() 
	                addThisUpdate = true 
	            Else 
	                WScript.Echo I + 1 & "> skipping: " & update.Title & _ 
	                " because the license agreement was declined" 
	            End If 
       		 Else 
            	addThisUpdate = true 
        	End If 
    	End If 	 	
    End Select
    If addThisUpdate = true Then 
        WScript.Echo I + 1 & "> adding: " & update.Title  
        updatesToDownload.Add(update) 
    End If 
Next 
 
If updatesToDownload.Count = 0 Then 
    WScript.Echo "All applicable updates were skipped." 
    WScript.Quit 
End If 
     
WScript.Echo vbCRLF & "Downloading updates..." 
 
Set downloader = updateSession.CreateUpdateDownloader()  
downloader.Updates = updatesToDownload 
downloader.Download() 
 
Set updatesToInstall = CreateObject("Microsoft.Update.UpdateColl") 
 
rebootMayBeRequired = false 
 
WScript.Echo vbCRLF & "Successfully downloaded updates:" 
 
For I = 0 To searchResult.Updates.Count-1 
    set update = searchResult.Updates.Item(I) 
    If update.IsDownloaded = true Then 
        WScript.Echo I + 1 & "> " & update.Title  
        updatesToInstall.Add(update)     
        If update.InstallationBehavior.RebootBehavior > 0 Then 
            rebootMayBeRequired = true 
        End If 
    End If 
Next 
 
If updatesToInstall.Count = 0 Then 
    WScript.Echo "No updates were successfully downloaded." 
    WScript.Quit 
End If 
 
If rebootMayBeRequired = true Then 
    WScript.Echo vbCRLF & "These updates may require a reboot." 
End If 
 
'WScript.Echo  vbCRLF & "Would you like to install updates now? (Y/N)" 
'strInput = WScript.StdIn.ReadLine 
strInput = "Y" 
WScript.Echo  
 
If (strInput = "Y" or strInput = "y") Then 
    WScript.Echo "Installing updates..." 
    Set installer = updateSession.CreateUpdateInstaller() 
    installer.Updates = updatesToInstall 
    Set installationResult = installer.Install() 
     
    'Output results of install 
    WScript.Echo "Installation Result: " & _ 
    installationResult.ResultCode  
    WScript.Echo "Reboot Required: " & _  
    installationResult.RebootRequired & vbCRLF  
    WScript.Echo "Listing of updates installed " & _ 
    "and individual installation results:"  
     
    For I = 0 to updatesToInstall.Count - 1 
        WScript.Echo I + 1 & "> " & _ 
        updatesToInstall.Item(i).Title & _ 
        ": " & installationResult.GetUpdateResult(i).ResultCode          
    Next 
End If 

Open in new window

operationsITAuthor Commented:
Ok giving it a go...
operationsITAuthor Commented:
It seems to run

Installing updates....
Installation Result: 3
Re Reboot Required: False

Listing of updates installed and individual installation results:
1. Adobe 2
2. Security 4
3. Security 4
4. Security 4
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Active Directory

From novice to tech pro — start learning today.