windows-update-noreboot
Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| windows-update-noreboot [2024/09/10 13:41] – created jsanders | windows-update-noreboot [2024/09/10 14:04] (current) – jsanders | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ===== Windows Update: Prevent system from automatically rebooting ===== | ===== Windows Update: Prevent system from automatically rebooting ===== | ||
| + | ==== Manual Override ==== | ||
| + | You should still get a notification saying a restart is scheduled, but it will just never restart because the restart task can't be scheduled. | ||
| + | - Go to C: | ||
| + | - There should be a file named " | ||
| + | - Take ownership of it | ||
| + | - Remove all other user/group from its security properties except you (your login account). | ||
| + | - Disable the " | ||
| + | |||
| + | ---- | ||
| + | ==== All-in-one Powershell Script ==== | ||
| + | Here is a Powershell script that will adjust the reboot task permissions in update orchestrator to prevent windows from automatically rebooting. The script will permanently disable auto reboot until the next feature update. This is due to how Windows wipes the Windows directory during updates. | ||
| + | <code powershell Disable-UpdateReboot.ps1> | ||
| + | <# | ||
| + | |||
| + | .SYNOPSIS | ||
| + | Disable Windows update auto reboot | ||
| + | |||
| + | .DESCRIPTION | ||
| + | This script disables and sets permissions on registry key and task files to prevent the system | ||
| + | from re-enabling reboot task | ||
| + | |||
| + | .NOTES | ||
| + | Script will have to be run again after feature updates. This is because windows wipes the windows directory during it's update process. | ||
| + | This script was created by SCUR0 | ||
| + | |||
| + | .LINK | ||
| + | https:// | ||
| + | |||
| + | #> | ||
| + | |||
| + | [cmdletbinding()] | ||
| + | param () | ||
| + | |||
| + | If (!([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]:: | ||
| + | IsInRole([Security.Principal.WindowsBuiltInRole] " | ||
| + | Write-Error "Admin permissions are required to run this script. Please open powershell as administrator." | ||
| + | pause | ||
| + | break | ||
| + | } | ||
| + | |||
| + | #Variables | ||
| + | $Errors=$null | ||
| + | $RebootTaskError=$null | ||
| + | $RebootRegKey=" | ||
| + | $RebootReg=" | ||
| + | $RebootTask=" | ||
| + | $RegAdminRule = New-Object System.Security.AccessControl.RegistryAccessRule (" | ||
| + | $RegSystemRule = New-Object System.Security.AccessControl.RegistryAccessRule (" | ||
| + | $RegUserRule = New-Object System.Security.AccessControl.RegistryAccessRule ($env: | ||
| + | $FileAdminRule = New-Object System.Security.AccessControl.filesystemaccessrule (" | ||
| + | $FileSystemRule = New-Object System.Security.AccessControl.filesystemaccessrule (" | ||
| + | $FileUserRule = New-Object System.Security.AccessControl.filesystemaccessrule ($env: | ||
| + | $owner = [Security.Principal.NTAccount]$env: | ||
| + | |||
| + | |||
| + | Function Enable-Privilege { | ||
| + | param($Privilege) | ||
| + | $Definition = @' | ||
| + | using System; | ||
| + | using System.Runtime.InteropServices; | ||
| + | public class AdjPriv { | ||
| + | [DllImport(" | ||
| + | internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, | ||
| + | ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr rele); | ||
| + | [DllImport(" | ||
| + | internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok); | ||
| + | [DllImport(" | ||
| + | internal static extern bool LookupPrivilegeValue(string host, string name, | ||
| + | ref long pluid); | ||
| + | [StructLayout(LayoutKind.Sequential, | ||
| + | internal struct TokPriv1Luid { | ||
| + | public int Count; | ||
| + | public long Luid; | ||
| + | public int Attr; | ||
| + | } | ||
| + | internal const int SE_PRIVILEGE_ENABLED = 0x00000002; | ||
| + | internal const int TOKEN_QUERY = 0x00000008; | ||
| + | internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; | ||
| + | public static bool EnablePrivilege(long processHandle, | ||
| + | bool retVal; | ||
| + | TokPriv1Luid tp; | ||
| + | IntPtr hproc = new IntPtr(processHandle); | ||
| + | IntPtr htok = IntPtr.Zero; | ||
| + | retVal = OpenProcessToken(hproc, | ||
| + | ref htok); | ||
| + | tp.Count = 1; | ||
| + | tp.Luid = 0; | ||
| + | tp.Attr = SE_PRIVILEGE_ENABLED; | ||
| + | retVal = LookupPrivilegeValue(null, | ||
| + | retVal = AdjustTokenPrivileges(htok, | ||
| + | IntPtr.Zero); | ||
| + | return retVal; | ||
| + | } | ||
| + | } | ||
| + | '@ | ||
| + | $ProcessHandle = (Get-Process -id $pid).Handle | ||
| + | $type = Add-Type $definition -PassThru | ||
| + | $type[0]:: | ||
| + | } | ||
| + | |||
| + | #verify task is created | ||
| + | If (!(test-path $RebootTask)){ | ||
| + | Write-Output " | ||
| + | }else{ | ||
| + | do {} until (Enable-Privilege SeTakeOwnershipPrivilege) | ||
| + | |||
| + | |||
| + | #SET ACL for registry key | ||
| + | #Set ownership | ||
| + | Write-Verbose " | ||
| + | $key = [Microsoft.Win32.Registry]:: | ||
| + | [Microsoft.Win32.RegistryKeyPermissionCheck]:: | ||
| + | $RegACL = $key.GetAccessControl() | ||
| + | if ($null -eq $RegACL){ | ||
| + | Write-Warning "Error encountered while trying to modify registry for reboot" | ||
| + | $Errors=$true | ||
| + | }else{ | ||
| + | $RegACL.SetOwner($owner) | ||
| + | $key.SetAccessControl($RegACL) | ||
| + | |||
| + | #Modify permissions | ||
| + | $RegACL = $key.GetAccessControl() | ||
| + | $RegACL.ResetAccessRule($RegAdminRule) | ||
| + | $RegACL.SetAccessRule($RegSystemRule) | ||
| + | $RegACL.SetAccessRule($RegUserRule) | ||
| + | $key.SetAccessControl($RegACL) | ||
| + | |||
| + | #remove inheritance | ||
| + | $RegACL = Get-Acl -Path $RebootReg | ||
| + | $RegACL.SetAccessRuleProtection($true, | ||
| + | $RegACL | Set-Acl | ||
| + | } | ||
| + | |||
| + | #SET ACL for task file | ||
| + | #Change owner | ||
| + | Write-Verbose " | ||
| + | $FileACL = Get-ACL -Path $RebootTask -ErrorAction SilentlyContinue | ||
| + | if ($null -eq $FileACL){ | ||
| + | Write-Warning "Error encountered while trying to modify task file for reboot" | ||
| + | $Errors=$true | ||
| + | }else{ | ||
| + | $FileACL.SetOwner($owner) | ||
| + | Set-Acl -Path $RebootTask -AclObject $FileACL | ||
| + | |||
| + | #remove inheritance | ||
| + | $FileACL = Get-Acl -Path $RebootTask | ||
| + | $FileACL.SetAccessRuleProtection($true, | ||
| + | $FileACL | Set-Acl -ErrorAction Stop | ||
| + | |||
| + | #remove and set permissions | ||
| + | $FileACL = Get-ACL -Path $RebootTask | ||
| + | $FileACL.Access | %{$FileACL.RemoveAccessRule($_)} |Out-Null | ||
| + | $FileACL.SetAccessRule($FileAdminRule) | ||
| + | $FileACL.SetAccessRule($FileSystemRule) | ||
| + | $FileACL.SetAccessRule($FileUserRule) | ||
| + | Set-Acl -Path $RebootTask -AclObject $FileACL | ||
| + | } | ||
| + | if (!$Errors){ | ||
| + | #attempt to set task to disabled | ||
| + | Write-Verbose " | ||
| + | try{ | ||
| + | Get-ScheduledTask Reboot -ErrorAction Stop | Disable-ScheduledTask -ErrorAction Stop | Out-Null | ||
| + | }catch{ | ||
| + | $RebootTaskError=$true | ||
| + | } | ||
| + | if (!$RebootTaskError){ | ||
| + | #remove admin permissions | ||
| + | Write-Verbose " | ||
| + | $RegACL.RemoveAccessRule($RegAdminRule) | Out-Null | ||
| + | $key.SetAccessControl($RegACL) | ||
| + | |||
| + | $FileACL.RemoveAccessRule($FileAdminRule) | Out-Null | ||
| + | Set-Acl -Path $RebootTask -AclObject $FileACL | ||
| + | |||
| + | Write-Verbose " | ||
| + | Write-Warning " | ||
| + | } | ||
| + | }else{ | ||
| + | Write-Output " | ||
| + | } | ||
| + | }</ | ||
| + | ==== References ==== | ||
| + | [[https:// | ||
windows-update-noreboot.1725990065.txt.gz · Last modified: by jsanders
