Worklet: Enable Controlled Windows 10 Feature Updates through Automox Patching

This Worklet will allow you to define a Windows 10 Feature version, and make it possible to install that Feature Update through Standard Automox Patching Policies.

Please see the following Community post for additional details:
https://community.automox.com/t/controlled-windows-10-feature-updates-through-automox-patching/1366

Setting the Target Release Version enables the ability to manage your preferred Win 10 Feature version.

NEED TO KNOW:

  • IMPORTANT: For version 1909 this worklet will do everything you need. FOR 2004 and 20H2 THERE IS A FINALIZATION WORKLET NEEDED TO COMPLETE THE UPGRADE. Please see Worklet: Finalize Windows 10 Feature Update to 2004 or 20H2 Applied From a Patch Policy

  • Your devices must be running 1803 or newer

  • Your OS must be a manageable SKU (Education, Enterprise, Professional, Business)

  • The version can be set to the current version, or newer feature update version than is currently installed. This will keep a device on that version and can help to avoid automatic upgrades before you are ready for them. Please note, Microsoft may still force upgrades when versions go out of support.

  • Setting it to a previous version will not cause issues (example, it will not roll the version back), but it doesn’t make much sense to do this.

  • Do not set these keys when using WSUS. You can already deploy feature updates by approving them in WSUS. Enabling these features when using WSUS can also enable DualScan, allowing your device to automatically update from Windows Update, and bypass your WSUS server approval controls.

BEST PRACTICE
Please review the following article for best practices for deploying Feature Updates: What Are the Recommended Best Practices for Patching in Automox?
Create a Patch Only Patch policy, and specify: Everything “Feature update to Windows 10”.
ENSURE THE POLICY HAS THE “AUTOMOMATIC REBOOT” OPTION SET, as this will handle the needed finalization commands to apply the final restart and complete the upgrade. Please see the Article linked at the top in the same topic for more information.

BENEFITS

  • Upgrading between versions released in the same year starting with 1903 and 1909 will leverage enablement packages. Enablement packages turn on previously download and installed components and flip the version switch to the new version. This package is very small, and can be installed in less than 5 minutes.
  • Feature Updates spanning to another annual version set (ex 1809-1903) will still require a large update, and will take some time to install. These packages are generally smaller than an ISO, and are dynamically updated by Microsoft. This method may also apply additional updates (such as additional Cumulative Updates) along with the upgrade process.
  • If you utilize Delivery Optimization (DO), your local devices can share downloaded content to reduce bandwidth and download time.
  • No need to script a Worklet to upgrade to a newer version of Windows 10 (unless you need to customize the upgrade process).

Actions:
Set the $rValue and $rInfoValue in both the evaluation and remediation code to enable the feature and set the preferred version. The values must match in both code blocks.

EVALUATION CODE

#Evalaution Script - Determine if Target Release Version Registry keys exist and are set 


# Define Values in this section and ensure they match the values set in the remediation script
#############################################
$rValue = '1' #Enable Target Release Version 0 = Disabled, 1 = Enabled
$rInfoValue = '2004' #Specify Windows 10 Target Release Version.  Select the preferred version from https://docs.microsoft.com/en-us/windows/release-information/ 
#############################################

#Predefined variables
$rPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate'
$rVersion = 'TargetReleaseVersion'
$rVersionInfo = 'TargetReleaseVersionInfo'

#Check if $rVersion registry value missing

try{
    $cVersion = Get-ItemPropertyValue -Path $rPath -Name $rVersion -ErrorAction Stop
    $cVersionInfo = Get-ItemPropertyValue -Path $rPath -Name $rVersionInfo -ErrorAction Stop
}
catch{
    Write-Error "Unable to read registry values"
    Exit -1
}

#Check if registry value data matches defined values
if (($cVersion -eq $rValue) -and ($rInfoValue -eq $cVersionInfo)) {
   Exit 0
} else { Exit -1 }

REMEDIATION CODE

<#
.SYNOPSIS
Configure Windows 10 Target Release Version

.DESCRIPTION
  Uses group policy registry keys to Enable and configure Target Release Version for Windows 10.  
  
Target Release Version
Enable = 1 or Disable = 0

Target Releaese Version Info
Specify the preferred version of Windows 10.  Enter version from https://docs.microsoft.com/en-us/windows/release-information/

.NOTES
Author: Automox
Please note, these settings remain in the registry, and would require modification or removal to change or revert back to default. 

.PREREQUISITES
  Windows 10 1803 or higher
  Managable SKU (Pro, Education, Enterprise, Business)
#>

# Define Values in this section
#############################################
$rValue = '1' #Enable Target Release Version 0 = Disabled, 1 = Enabled
$rInfoValue = '2004' #Specify Windows 10 Target Release Version.  Select the preferred version from https://docs.microsoft.com/en-us/windows/release-information/ 
#############################################
$rPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate'
$rKeyPath = 'HKLM:\Software\Policies\Microsoft\Windows'
$rVersion = 'TargetReleaseVersion'
$rVersionInfo = 'TargetReleaseVersionInfo'

try {
  if(-not(Test-Path -path $rPath)){
    New-Item -Path $rPath -Force -ErrorAction Stop | Out-Null
  }
    Write-Output "SUCCESS: Target Release Version keys set`t"
    New-ItemProperty -Path $rPath -Name $rVersion -PropertyType DWord -Value $rValue -Force -ErrorAction Stop | Out-Null
    Write-Output "$rpath exists`t"
    New-ItemProperty -Path $rPath -Name $rVersionInfo -PropertyType String -Value $rInfoValue -Force -ErrorAction Stop | Out-Null
    Write-Output "$rVersion = $rvalue and $rVersionInfo = $rInfoValue`t"    
    
    Exit 0
} catch { $Exception = $error[0].Exception.Message + "`nAt Line " + $error[0].InvocationInfo.ScriptLineNumber
    Write-Error $Exception
    Exit 90
}