Troubleshooting ShutdownWithUpdates Errors on Windows

Automating ShutdownWithUpdates with Scripts and Task Scheduler

Automating ShutdownWithUpdates lets you install pending Windows updates and power off machines without manual intervention — useful for maintenance windows, lab machines, and overnight updates. This guide shows a reproducible approach using PowerShell scripts and Task Scheduler to run ShutdownWithUpdates reliably and safely.

What “ShutdownWithUpdates” does

  • Closes running apps, installs pending quality and feature updates, and then powers off the PC.
  • Ensures updates apply without leaving the system in a partially-updated state that needs a manual restart.

Overview of the solution

  1. Create a PowerShell script that:
    • Checks for pending updates.
    • Warns or notifies logged-on users (optional).
    • Initiates an update-and-shutdown operation.
  2. Create a Scheduled Task to run the script at desired times with appropriate privileges.
  3. Optionally add safeguards (user deferral window, logging, retry).

PowerShell script (automated update + shutdown)

Save this as C:\Scripts\ShutdownWithUpdates.ps1. Adjust paths and options as needed.

powershell

# Requires running as Administrator \(logFile</span><span> = </span><span class="token" style="color: rgb(163, 21, 21);">'C:\Scripts\ShutdownWithUpdates.log'</span><span> </span><span></span><span class="token" style="color: rgb(57, 58, 52);">Add-Content</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span>Path </span><span class="token" style="color: rgb(54, 172, 170);">\)logFile -Value ”===== \(</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(57, 58, 52);">Get-Date</span><span class="token" style="color: rgb(57, 58, 52);"> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span class="token" style="color: rgb(57, 58, 52);">Format o</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span class="token" style="color: rgb(163, 21, 21);"> Starting ShutdownWithUpdates check ====="</span><span> </span> <span></span><span class="token" style="color: rgb(0, 0, 255);">try</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">{</span><span> </span><span></span><span class="token" style="color: rgb(0, 128, 0); font-style: italic;"># 1) Detect if updates are pending using Windows Update COM API</span><span> </span><span> </span><span class="token" style="color: rgb(54, 172, 170);">\)updateSession = New-Object -ComObject Microsoft.Update.Session \(updateSearcher</span><span> = </span><span class="token" style="color: rgb(54, 172, 170);">\)updateSession.CreateUpdateSearcher() \(searchResult</span><span> = </span><span class="token" style="color: rgb(54, 172, 170);">\)updateSearcher.Search(“IsInstalled=0 and Type=‘Software’ and IsHidden=0”) \(pendingCount</span><span> = </span><span class="token" style="color: rgb(54, 172, 170);">\)searchResult.Updates.Count Add-Content -Path \(logFile</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span>Value </span><span class="token" style="color: rgb(163, 21, 21);">"Found </span><span class="token" style="color: rgb(54, 172, 170);">\)pendingCount pending updates.” if (\(pendingCount</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-eq</span><span> 0</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">{</span><span> </span><span> </span><span class="token" style="color: rgb(57, 58, 52);">Add-Content</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span>Path </span><span class="token" style="color: rgb(54, 172, 170);">\)logFile -Value “No pending updates. Exiting.” exit 0 } # 2) Optional: notify interactive user(s) via a 5-minute toast/message \(notifyMinutes</span><span> = 5 </span><span> </span><span class="token" style="color: rgb(0, 0, 255);">try</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">{</span><span> </span><span> </span><span class="token" style="color: rgb(0, 128, 0); font-style: italic;"># If an interactive session exists, create a popup via msg.exe</span><span> </span><span> </span><span class="token" style="color: rgb(54, 172, 170);">\)sessions = quser 2>\(null</span><span> </span><span> </span><span class="token" style="color: rgb(0, 0, 255);">if</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(54, 172, 170);">\)sessions) { # Send simple message to all sessions msg “System will install updates and shut down in \(notifyMinutes</span><span class="token" style="color: rgb(163, 21, 21);"> minutes. Save your work."</span><span> </span><span> </span><span class="token" style="color: rgb(57, 58, 52);">}</span><span> </span><span> </span><span class="token" style="color: rgb(57, 58, 52);">}</span><span> </span><span class="token" style="color: rgb(0, 0, 255);">catch</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">{</span><span class="token" style="color: rgb(57, 58, 52);">}</span><span> </span> <span> </span><span class="token" style="color: rgb(57, 58, 52);">Start-Sleep</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span>Seconds </span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(54, 172, 170);">\)notifyMinutes 60) # 3) Download and install updates \(updatesToInstall</span><span> = </span><span class="token" style="color: rgb(57, 58, 52);">New-Object</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span>ComObject Microsoft</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span>Update</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span>UpdateColl </span><span> </span><span class="token" style="color: rgb(0, 0, 255);">foreach</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(54, 172, 170);">\)update in \(searchResult</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span>Updates</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">{</span><span> </span><span> </span><span class="token" style="color: rgb(54, 172, 170);">\)updatesToInstall.Add(\(update</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">|</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">Out-Null</span><span> </span><span> </span><span class="token" style="color: rgb(57, 58, 52);">}</span><span> </span> <span> </span><span class="token" style="color: rgb(54, 172, 170);">\)downloader = \(updateSession</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span>CreateUpdateDownloader</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span><span> </span><span class="token" style="color: rgb(54, 172, 170);">\)downloader.Updates = \(updatesToInstall</span><span> </span><span> </span><span class="token" style="color: rgb(57, 58, 52);">Add-Content</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span>Path </span><span class="token" style="color: rgb(54, 172, 170);">\)logFile -Value “Downloading updates…” \(downloadResult</span><span> = </span><span class="token" style="color: rgb(54, 172, 170);">\)downloader.Download() Add-Content -Path \(logFile</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span>Value </span><span class="token" style="color: rgb(163, 21, 21);">"Download result: </span><span class="token" style="color: rgb(57, 58, 52);">\)(\(downloadResult</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span class="token" style="color: rgb(57, 58, 52);">ResultCode</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span class="token" style="color: rgb(163, 21, 21);">"</span><span> </span> <span> </span><span class="token" style="color: rgb(54, 172, 170);">\)installer = \(updateSession</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span>CreateUpdateInstaller</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span><span> </span><span class="token" style="color: rgb(54, 172, 170);">\)installer.Updates = \(updatesToInstall</span><span> </span><span> </span><span class="token" style="color: rgb(57, 58, 52);">Add-Content</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span>Path </span><span class="token" style="color: rgb(54, 172, 170);">\)logFile -Value “Installing updates…” \(installResult</span><span> = </span><span class="token" style="color: rgb(54, 172, 170);">\)installer.Install() Add-Content -Path \(logFile</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span>Value </span><span class="token" style="color: rgb(163, 21, 21);">"Install result: </span><span class="token" style="color: rgb(57, 58, 52);">\)(\(installResult</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span class="token" style="color: rgb(57, 58, 52);">ResultCode</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span class="token" style="color: rgb(163, 21, 21);">; RebootRequired=</span><span class="token" style="color: rgb(57, 58, 52);">\)(\(installResult</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span class="token" style="color: rgb(57, 58, 52);">RebootRequired</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span class="token" style="color: rgb(163, 21, 21);">"</span><span> </span> <span> </span><span class="token" style="color: rgb(0, 128, 0); font-style: italic;"># 4) If install succeeded (or reboot required), initiate shutdown with applied updates</span><span> </span><span> </span><span class="token" style="color: rgb(0, 0, 255);">if</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(54, 172, 170);">\)installResult.ResultCode -eq 2 -or \(installResult</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span>RebootRequired</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">{</span><span> </span><span> </span><span class="token" style="color: rgb(57, 58, 52);">Add-Content</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span>Path </span><span class="token" style="color: rgb(54, 172, 170);">\)logFile -Value “Initiating shutdown to complete updates…” # Force apps closed after a 60-second warning; change /t to adjust delay shutdown.exe /s /t 60 /f /d p:2:17 /c “Installing updates — system will shut down to finish installation.” } else { Add-Content -Path \(logFile</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span>Value </span><span class="token" style="color: rgb(163, 21, 21);">"Install did not require reboot or failed. No shutdown."</span><span> </span><span> </span><span class="token" style="color: rgb(57, 58, 52);">}</span><span> </span><span></span><span class="token" style="color: rgb(57, 58, 52);">}</span><span> </span><span class="token" style="color: rgb(0, 0, 255);">catch</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">{</span><span> </span><span> </span><span class="token" style="color: rgb(57, 58, 52);">Add-Content</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span>Path </span><span class="token" style="color: rgb(54, 172, 170);">\)logFile -Value “ERROR: $_ exit 1 }

Notes:

  • The script uses the Microsoft.Update.Session COM API (Windows Update Agent). It requires Administrator privileges.
  • ResultCode values: 2 typically means succeeded. Adjust checks for your environment.
  • The script logs basic progress to C:\Scripts\ShutdownWithUpdates.log.

Create a Scheduled Task

Use Task Scheduler to run the script with highest privileges.

  1. Open Task Scheduler > Create Task.
  2. General:
    • Name: ShutdownWithUpdates
    • Run whether user is logged on or not
    • Check “Run with highest privileges”
    • Configure for: Windows ⁄11 (or your OS)
  3. Triggers:
    • New… choose schedule (e.g., Weekly at 2:00 AM on Sundays).
  4. Actions:
    • New…
    • Action: Start a program
    • Program/script: powershell.exe
    • Add arguments: -ExecutionPolicy Bypass -NoProfile -File “C:\Scripts\ShutdownWithUpdates.ps1”
  5. Conditions:
    • (Optional) Start only if the computer is idle for… or only if on AC power.
  6. Settings:
    • Allow task to be run on demand
    • If the task fails, restart every X minutes (optional)
  7. Save and supply admin credentials if prompted.

Safeguards and best practices

  • Test manually before scheduling. Run the script in a test VM.
  • User deferral: Increase notify time or implement an interactive dismissal mechanism.
  • Logging & alerts: Centralize logs or send email on failure.
  • Scope: For many machines, use Group Policy, SCCM, or Windows Update for Business for scale.
  • Backup critical systems before automating updates.

Troubleshooting quick tips

  • Task fails to run: ensure “Run with highest privileges” and correct credentials.
  • COM object errors: ensure Windows Update Agent is present and script runs as admin.
  • No shutdown: check installResult.RebootRequired and ResultCode values in the log.

Example: quick one-liner Scheduled Task action

Program: powershell.exe Arguments: -ExecutionPolicy Bypass -NoProfile -Command “Start-Process -FilePath ‘C:\Scripts\ShutdownWithUpdates.ps1’ -Verb RunAs”


This setup automates installing updates and powering off systems safely during maintenance windows. Adjust notification, timing, and logging to match your environment.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *