{"id":343,"date":"2026-09-23T22:52:41","date_gmt":"2026-09-23T20:52:41","guid":{"rendered":"https:\/\/tillnet.se\/?p=343"},"modified":"2026-09-23T22:52:41","modified_gmt":"2026-09-23T20:52:41","slug":"wu-troubleshooter","status":"publish","type":"post","link":"https:\/\/tillnet.se\/?p=343","title":{"rendered":"WU-Troubleshooter"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">A batch of Windows Server 2025 machines, all deployed from the same image, started failing the latest cumulative update with <code>0x80073712<\/code>. The network was fine and the update client was fine. <code>DISM \/RestoreHealth<\/code> didn&#8217;t help, because the real problem was a corrupt en-gb language pack baked into the golden image. Finding that took far longer than it should have. So I built a toolset that works the problem in a fixed order and points at the actual cause instead of sending you round a blind repair loop.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/github.com\/tobiastillstam\/WU-Troubleshooter\">github.com\/tobiastillstam\/WU-Troubleshooter<\/a><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">A PowerShell toolset for troubleshooting Windows Update on Windows Server 2025. It works the problem in the order that actually isolates it: <strong>wire \u2192 client \u2192 errors \u2192 repair<\/strong>.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">It works with both online Windows Update and WSUS-managed servers. The update source is auto-detected from the policy registry keys, so a WSUS box reports a clean result instead of false connectivity failures.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Quick start<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>git clone https:\/\/github.com\/tobiastillstam\/WU-Troubleshooter.git\ncd WU-Troubleshooter\nGet-ChildItem *.ps1 | Unblock-File\n\n# from an elevated prompt \u2013 runs everything into .\\logs\\WUDiag_&lt;timestamp&gt;\\\n.\\Invoke-WUDiagnostics.ps1<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">What&#8217;s in it<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Test-WUOnlineConnectivity.ps1 (the wire).<\/strong> It runs DNS, TCP, TLS and proxy-aware HTTP checks against the documented Microsoft endpoints, over both the direct and proxy paths. A non-Microsoft certificate issuer is flagged as likely SSL inspection, which breaks WU&#8217;s certificate pinning.<\/li>\n\n\n\n<li><strong>Test-WULocalClient.ps1 (the client).<\/strong> It checks services, the SYSTEM-context proxy, the update source and policy, and common blockers such as a pending reboot, disk space, TLS and time. It also covers BITS, the datastore, update history and event logs, with an optional live scan.<\/li>\n\n\n\n<li><strong>Get-WUErrors.ps1 (the errors).<\/strong> It decodes the WU ETL logs, filters out benign noise, groups failures by HRESULT and adds known-issue hints. It also has a per-update timeline mode and a CBS component-store corruption scan.<\/li>\n\n\n\n<li><strong>Invoke-WUDiagnostics.ps1 (the orchestrator).<\/strong> It runs all three in order into one timestamped folder and writes a combined summary.<\/li>\n\n\n\n<li><strong>Read-only by default.<\/strong> Repairs only run when you pass their switch: service fixes, the WinHTTP proxy import, the SoftwareDistribution reset and DISM\/SFC. Every repair can be previewed with <code>-WhatIf<\/code>.<\/li>\n\n\n\n<li><strong>Consistent output.<\/strong> Each check reports PASS, WARN, FAIL or INFO. Every script writes a transcript to a <code>logs<\/code> folder and returns objects you can capture for further processing.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Requires Windows PowerShell 5.1 or later and an elevated session. It also runs on Windows 10, Server 2016+ and Windows 11 24H2. MIT licensed.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A batch of Windows Server 2025 machines, all deployed from the same image, started failing the latest cumulative update with 0x80073712. The network was fine &hellip;<\/p>\n","protected":false},"author":1,"featured_media":344,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-343","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-it"],"jetpack_featured_media_url":"https:\/\/tillnet.se\/wp-content\/uploads\/2026\/09\/Gemini_Generated_Image_3a46ij3a46ij3a46.jpeg","_links":{"self":[{"href":"https:\/\/tillnet.se\/index.php?rest_route=\/wp\/v2\/posts\/343","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tillnet.se\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tillnet.se\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tillnet.se\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tillnet.se\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=343"}],"version-history":[{"count":1,"href":"https:\/\/tillnet.se\/index.php?rest_route=\/wp\/v2\/posts\/343\/revisions"}],"predecessor-version":[{"id":345,"href":"https:\/\/tillnet.se\/index.php?rest_route=\/wp\/v2\/posts\/343\/revisions\/345"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/tillnet.se\/index.php?rest_route=\/wp\/v2\/media\/344"}],"wp:attachment":[{"href":"https:\/\/tillnet.se\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=343"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tillnet.se\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=343"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tillnet.se\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=343"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}