SCCM Compliance - enforce Unified Write Filter on Windows 10

Posted on 12 February, 2018

I am in the final stages of deploying a new solution to libraries across a borough in London. The solution involved replacing a Windows 7 physical desktop that had the Deep Freeze product, with Windows 10.

I didn’t want to use Deep Freeze as the console is clunky and it’s yet another agent to manage on the client OS. Windows 10 has the Unified Write Filter (UWF) built-in and this would do the job perfectly.

All the desktops are managed using SCCM and SCCM fully supports the Windows write filters.

I started off looking at basic batch files calling uwfmgr.exe, but things quickly got messy, so I switched to trusty old WMI, but managed using PowerShell and SCCM of course :)

I’ve tried to break it down into sections.

It is best practice to have the pagefile on a separate disk when using UWF as it cannot be added to the exclusions list, so here we have a function that we can pass in your new volume and remove the NTFS permissions to stop normal users from fiddling:

The main function to enable the Unified Write Filter, configure the overlay, exclusions and pagefile.

First part of the function is to check if UWF is currently enabled or not. If we need to enable it, it will require a restart before the write filter becomes active.

functionEnable-UWF{# Global variables$NAMESPACE="root\standardcimv2\embedded"######################################################################################################################### Get current state of UWF$objUWFFilter=Get-WmiObject-Namespace$NAMESPACE-ClassUWF_Filter;if(!$objUWFFilter){write-output"`nUnable to retrieve Unified Write Filter settings. from $NAMESPACE"|out-file-FilePath$env:temp\UWF.log-Appendreturn;}# Check if UWF is enabledif(($objUWFFilter.CurrentEnabled)-or($objUWFFilter.NextEnabled)){write-output"`nUWF Filter is enabled"|out-file-FilePath$env:temp\UWF.log-Append}else{write-output"`nUWF Filter is NOT enabled, enabling now..."|out-file-FilePath$env:temp\UWF.log-Append# Call the method to enable UWF after the next restart. This sets the NextEnabled property to false.$retval=$objUWFFilter.Enable();# Check the return value to verify that the enable is successfulif($retval.ReturnValue-eq0){write-output"Unified Write Filter will be enabled after the next system restart."|out-file-FilePath$env:temp\UWF.log-Append}else{"Unknown Error: "+"{0:x0}"-f$retval.ReturnValue}}

Once the computer has restarted, SCCM compliance will run again at your specified evaluation schedule, at which point the following (also still part of the Enable-UWF function) will run to protect the C drive:

Set the overlay size based on the % of free space remaining on the disk:

# Overlay size and type$objUWFOverlayConfig=Get-WmiObject-Namespace$NAMESPACE-ClassUWF_OverlayConfig-Filter"CurrentSession = false"If($objUWFOverlayConfig.MaximumSize-le1024){# need to set maximum size$OverlaySize=(Get-Volume-DriveLetterC).SizeRemaining-((Get-Volume-DriveLetterC).SizeRemaining/2)|%{[math]::truncate($_/1MB)}write-output"`nTry to set overlay max size to $OverlaySize MB."|out-file-FilePath$env:temp\UWF.log-Append$objUWFOverlayConfig.SetMaximumSize($OverlaySize);$WarningSize=[math]::Round($OverlaySize/10*8)$CriticalSize=[math]::Round($OverlaySize/10*9)uwfmgr.exeoverlayset-warningthreshold$WarningSizeuwfmgr.exeoverlayset-criticalthreshold$CriticalSize}If($objUWFOverlayConfig.Type-ne1){# Set overlay type to Disk basedwrite-host"`nTry to set overlay type to Disk based"-ForegroundColorYellow$objUWFOverlayConfig.SetType(1)}

Set all the file and registry exclusions based on best practice and Microsoft recommendations (links included in the code below):

Bringing it all together, calling the functions above, and installing the UWF feature if its not currently:

$UWF_Feature=(Get-WindowsOptionalFeature-Online-FeatureNameClient-UnifiedWriteFilter-ErrorActionSilentlyContinue).StateIf($UWF_Feature-eq"Disabled"){write-host"Not installed"Enable-WindowsOptionalFeature-Online-FeatureNameClient-UnifiedWriteFilter-All-ErrorActionSilentlyContinuewrite-host"Please run this script again after a restart, to enable UWF filter"-ForegroundColorYellowpauseexit3010}else{write-host"`nClient-UnifiedWriteFilter WindowsOptionalFeature installed, now configure UWF"-ForegroundColorGreenEnable-UWF-ErrorActionSilentlyContinueIf(test-pathp:){$folder="P:\"Remove-NTFSPermissions$folder"Authenticated Users""Modify"Remove-NTFSPermissions$folder"Users""ReadAndExecute"}}