11<#
22. SYNOPSIS
3- Validates the presence of Microsoft.UpdateServices.Administration.dll in the Global Assembly Cache (GAC ).
3+ Validates and loads Microsoft.UpdateServices.Administration.dll (WSUS Admin API ).
44
55. DESCRIPTION
6- This script checks whether the WSUS Administration Console assembly is loaded in the current PowerShell session.
7- If not, it attempts to load it from the Global Assembly Cache (GAC). If that fails, it attempts to load it directly
8- from a known file path. The script also displays GUI message boxes to assist the user with guidance and diagnostics.
6+ - Prefers Import-Module UpdateServices (works when WSUS Management Tools are installed).
7+ - If the module isn't available, attempts to load the WSUS Admin assembly from the GAC.
8+ - Searches common GAC roots on modern and legacy systems.
9+ - Falls back to a known explicit path if provided.
10+ - Uses small WinForms message boxes for guidance/diagnostics.
11+ - Hides the console window (comment out [Window]::Hide() while debugging).
912
1013.AUTHOR
1114 Luiz Hamilton Silva - @brazilianscriptguy
1215
1316.VERSION
14- Last Updated: July 11 , 2025
17+ Last Updated: Sep 15 , 2025
1518#>
1619
17- # Hide Console Window
20+ # ---------------- Console (hidden) ----------------
1821Add-Type @"
1922using System;
2023using System.Runtime.InteropServices;
@@ -24,76 +27,135 @@ public class Window {
2427 [DllImport("user32.dll", SetLastError = true)]
2528 [return: MarshalAs(UnmanagedType.Bool)]
2629 static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
27- public static void Hide() {
28- var handle = GetConsoleWindow();
29- ShowWindow(handle, 0);
30- }
30+ public static void Hide() { var handle = GetConsoleWindow(); ShowWindow(handle, 0); }
3131}
3232"@
33- [Window ]::Hide()
33+ [Window ]::Hide() # <-- comment this line while debugging to keep the console visible
3434
35- # Load required assemblies
35+ # ---------------- UI + utils ----------------
3636Add-Type - AssemblyName System.Windows.Forms
3737[System.Windows.Forms.Application ]::EnableVisualStyles()
3838
39- # Logging function
4039function Write-Log {
41- param (
42- [string ]$Message ,
43- [ValidateSet (" INFO" , " WARNING" , " ERROR" )][string ]$Level
40+ param (
41+ [Parameter ( Mandatory )][ string ]$Message ,
42+ [ValidateSet (" INFO" , " WARNING" , " ERROR" )] [string ]$Level = " INFO "
4443 )
45-
46- $timestamp = Get-Date - Format " yyyy-MM-dd HH:mm:ss"
47- $formatted = " [$timestamp ] [$Level ] $Message "
48- Write-Output $formatted
44+ $stamp = Get-Date - Format " yyyy-MM-dd HH:mm:ss"
45+ Write-Output " [$stamp ] [$Level ] $Message "
4946}
5047
5148function Show-MessageBox {
52- param (
53- [string ]$Message ,
49+ param (
50+ [Parameter ( Mandatory )][ string ]$Message ,
5451 [string ]$Title = " WSUS Administration Assembly Check" ,
5552 [System.Windows.Forms.MessageBoxButtons ]$Buttons = [System.Windows.Forms.MessageBoxButtons ]::OK,
5653 [System.Windows.Forms.MessageBoxIcon ]$Icon = [System.Windows.Forms.MessageBoxIcon ]::Information
5754 )
5855 [System.Windows.Forms.MessageBox ]::Show($Message , $Title , $Buttons , $Icon ) | Out-Null
5956}
6057
61- # Define the expected path to the WSUS Administration assembly in the GAC
62- $wsusAssemblyPath = " C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.UpdateServices.Administration\v4.0_4.0.0.0__31bf3856ad364e35\Microsoft.UpdateServices.Administration.dll"
58+ # If you want to pin a known path (kept from your original script).
59+ $ExplicitAssemblyPath = " C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.UpdateServices.Administration\v4.0_4.0.0.0__31bf3856ad364e35\Microsoft.UpdateServices.Administration.dll"
60+
61+ # Common GAC roots on modern/legacy systems
62+ # Common GAC roots on modern/legacy systems
63+ $GacRoots = @ (
64+ (Join-Path $env: WINDIR ' Microsoft.NET\assembly\GAC_MSIL' ) # .NET 4+ (Win10/2016+)
65+ (Join-Path $env: WINDIR ' assembly\GAC_MSIL' ) # legacy view
66+ )
67+
68+ # ---------------- Helper: Is Assembly Loaded? ----------------
69+ function Test-AssemblyLoaded {
70+ [OutputType ([bool ])]
71+ param ([string ]$PartialName = " Microsoft.UpdateServices.Administration" )
72+ return [AppDomain ]::CurrentDomain.GetAssemblies().FullName -match [regex ]::Escape($PartialName )
73+ }
74+
75+ # ---------------- Try 1: Import-Module UpdateServices ----------------
76+ try {
77+ if ($PSVersionTable.PSEdition -eq ' Core' ) {
78+ # PowerShell 7+: use Windows PowerShell compatibility shim if available
79+ Import-Module - Name UpdateServices - UseWindowsPowerShell - ErrorAction Stop
80+ } else {
81+ Import-Module - Name UpdateServices - ErrorAction Stop
82+ }
83+
84+ if (Test-AssemblyLoaded ) {
85+ Write-Log " WSUS Administration assembly available via UpdateServices module." - Level INFO
86+ Show-MessageBox - Message " WSUS Administration assembly is available (loaded with UpdateServices module)."
87+ return
88+ }
89+ } catch {
90+ Write-Log " UpdateServices module not available or failed to load: $ ( $_.Exception.Message ) " - Level WARNING
91+ }
6392
64- # Attempt to load the assembly by partial name (GAC)
93+ # ---------------- Try 2: Load from GAC ( by partial name) ----------------
6594try {
66- $assembly = [System.Reflection.Assembly ]::LoadWithPartialName(" Microsoft.UpdateServices.Administration" )
67- if ($assembly ) {
68- Write-Log " WSUS Administration assembly loaded successfully from GAC." - Level INFO
69- Show-MessageBox - Message " WSUS Administration assembly loaded successfully from the Global Assembly Cache (GAC)."
95+ $asm = [System.Reflection.Assembly ]::LoadWithPartialName(" Microsoft.UpdateServices.Administration" )
96+ if ($asm -and ( Test-AssemblyLoaded ) ) {
97+ Write-Log " WSUS Administration assembly loaded from GAC via partial name ." - Level INFO
98+ Show-MessageBox - Message " WSUS Administration assembly loaded from the Global Assembly Cache (GAC)."
7099 return
71100 } else {
72- throw " Assembly not loaded from GAC ."
101+ throw " LoadWithPartialName returned null ."
73102 }
74103} catch {
75- Write-Log " Failed to load WSUS assembly from GAC : $_ " - Level WARNING
104+ Write-Log " Could not load WSUS assembly by partial name : $ ( $_ .Exception.Message ) " - Level WARNING
76105}
77106
78- # Attempt to load the assembly directly from known GAC path
79- if (Test-Path $wsusAssemblyPath ) {
107+ # ---------------- Try 3: Probe known GAC folders and Add-Type ----------------
108+ $foundPath = $null
109+ foreach ($root in $GacRoots ) {
110+ if (-not (Test-Path $root )) { continue }
80111 try {
81- Add-Type - Path $wsusAssemblyPath - ErrorAction Stop
82- Write-Log " WSUS Administration assembly loaded successfully from $wsusAssemblyPath ." - Level INFO
83- Show-MessageBox - Message " WSUS Administration assembly loaded successfully from path:`n $wsusAssemblyPath "
112+ $candidate = Get-ChildItem - Path $root - Recurse - Filter " Microsoft.UpdateServices.Administration.dll" - ErrorAction SilentlyContinue | Select-Object - First 1
113+ if ($candidate ) { $foundPath = $candidate.FullName ; break }
114+ } catch { }
115+ }
116+
117+ if (-not $foundPath -and (Test-Path $ExplicitAssemblyPath )) {
118+ $foundPath = $ExplicitAssemblyPath
119+ }
120+
121+ if ($foundPath ) {
122+ try {
123+ Add-Type - Path $foundPath - ErrorAction Stop
124+ if (Test-AssemblyLoaded ) {
125+ Write-Log " WSUS Administration assembly loaded from: $foundPath " - Level INFO
126+ Show-MessageBox - Message " WSUS Administration assembly loaded from:`n $foundPath "
127+ return
128+ } else {
129+ throw " Add-Type succeeded but assembly not visible in current AppDomain."
130+ }
84131 } catch {
85- $msg = " Error: Failed to load WSUS assembly from:`n $wsusAssemblyPath `n`n Details: $_ "
132+ $msg = " Failed to load WSUS assembly from:`n $foundPath `n`n Details: $ ( $_ .Exception.Message ) "
86133 Write-Log $msg - Level ERROR
87134 Show-MessageBox - Message $msg - Icon ' Error'
88135 exit 1
89136 }
90- } else {
91- $msg = " WSUS assembly not found at:`n $wsusAssemblyPath `n`n Ensure the WSUS Administration Console is installed using one of the following methods:`n "
92- $msg += " `n 1. Server Manager:`n - Add Roles and Features > Features > Windows Server Update Services > WSUS Tools"
93- $msg += " `n 2. PowerShell:`n - Install-WindowsFeature -Name UpdateServices-UI"
94- Write-Log " Error: WSUS assembly not found at $wsusAssemblyPath ." - Level ERROR
95- Show-MessageBox - Message $msg - Icon ' Error'
96- exit 1
97137}
98138
139+ # ---------------- Final guidance (not found) ----------------
140+ $help = @"
141+ WSUS Administration assembly was not found.
142+
143+ Install WSUS Management Tools (Administration Console) using one of the following:
144+
145+ 1) Server Manager
146+ - Add Roles and Features ➜ Features ➜ Windows Server Update Services ➜ WSUS Tools
147+
148+ 2) PowerShell (Windows Server)
149+ Install-WindowsFeature -Name UpdateServices-UI
150+
151+ 3) Windows Client (RSAT on Windows 10/11)
152+ DISM /Online /Enable-Feature /FeatureName:Rsat.WSUS.Tools~~~~0.0.1.0 /All
153+
154+ After installing, re-run this script.
155+ "@
156+
157+ Write-Log " WSUS Administration assembly not found in GAC paths or explicit path." - Level ERROR
158+ Show-MessageBox - Message $help - Icon ' Error'
159+ exit 1
160+
99161# End of script
0 commit comments