Windows – Configure Windows Update in Windows Server 2016

group-policypowershell-5.0windowswindows updatewindows-server-2016

Problem

Enable Windows Update to Automatically download and schedule install.
Schedule to run on a particular day (Saturday).

Solution I tried

Write a powershell script using gpmc/grouppolicy module to change Windows Update settings.

The end state I'm looking for is :

gpedit.msc –> Administrative Templates/Windows Components/Windows Update

Configure Automatic Update ->

Enabled

Auto download and schedule the install (4)

Every Saturday (7)

Issues Faced

Not finding any documentation to do this for Windows Server 2016 using powershell.

Notes:

  • The machine is not part of AD.
  • I'm trying to change local policy.

Best Answer

Unfortunately, the Get-GPO cmdlet can only get GPOs from a domain; there does not appear to be any managed equivalent of the COM method IGroupPolicyObject::OpenLocalMachineGPO. There are other ways to set this, though. Assuming the existing Group Policy doesn't already specify this policy setting, tweaking the Registry directly should work fine:

$hklm = [Microsoft.Win32.RegistryKey]::OpenBaseKey('LocalMachine', 'Default')
$wu = $hklm.CreateSubKey('SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU')
$wu.SetValue('NoAutoUpdate', 0, 'DWord')
$wu.SetValue('AUOptions', 4, 'DWord')
$wu.SetValue('ScheduledInstallDay', 7, 'DWord')
$wu.SetValue('ScheduledInstallTime', 0, 'DWord')
$wu.Dispose()
$hklm.Dispose()

This will not affect what you see in the Local Group Policy Editor, but it will be seen by the Windows Update infrastructure. Since you didn't say what hour of the day the updates should be installed, I set it to midnight. You can change that by altering the ScheduledInstallTime value.

To determine what Registry settings correspond to a given policy, you can use the Element Inspector tool in my open-source application Policy Plus. Speaking of Policy Plus, you can also load it as an assembly from PowerShell to edit the local GPO. First, download it and use the Properties tab in Explorer to "unblock" it; this allows .NET to load it into another process. Then place it in the same directory as this script:

[System.Reflection.Assembly]::LoadFile((gi '.\Policy Plus.exe').FullName) | Out-Null
$loader = [PolicyPlus.PolicyLoader]::new('LocalGpo', '', $false)
$pol = $loader.OpenSource()
$pol.SetValue('SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU', 'NoAutoUpdate', 0, 'DWord')
$pol.SetValue('SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU', 'AUOptions', 4, 'DWord')
$pol.SetValue('SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU', 'ScheduledInstallDay', 7, 'DWord')
$pol.SetValue('SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU', 'ScheduledInstallTime', 0, 'DWord')
$loader.Save()
$loader.Close()

This takes advantage of Policy Plus's PolicyLoader and PolFile classes. When the script completes, you should see this output (due to the last two calls):

saved to disk and invoked policy refresh
True

This way, the changes will be visible in the Local Group Policy Editor and the normal Group Policy infrastructure will apply them to the Registry.

Related Question