Created
September 13, 2025 20:53
-
-
Save mxxcon/9f25a596b04967136011536ec11d5a55 to your computer and use it in GitHub Desktop.
This PowerShell script implements professional best practices for repairing WMI. It verifies repository consistency, attempts non-destructive repair, supports backup and hard reset, and avoids risky file operations. All actions are thoroughly logged and documented.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <# | |
| .SYNOPSIS | |
| Safely Diagnoses and Repairs WMI (Windows Management Instrumentation) Repository Issues. | |
| .DESCRIPTION | |
| This PowerShell script implements professional best practices for repairing WMI. | |
| It verifies repository consistency, attempts non-destructive repair, supports backup and hard reset, | |
| and avoids risky file operations. | |
| All actions are thoroughly logged and documented. | |
| .NOTES | |
| - Requires Administrator privileges. | |
| - Consider running during maintenance windows. | |
| - For advanced users and IT professionals. | |
| - Third-party WMI providers may need manual reinstallation after hard resets. | |
| - Use at your own risk; always backup system state if possible. | |
| #> | |
| #region Admin Privilege Check | |
| # Ensure the script is running with administrative rights. | |
| if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { | |
| Write-Warning "This script must be run as an administrator!" | |
| exit 1 | |
| } | |
| #endregion | |
| #region Logging Setup | |
| $LogPath = "$env:SystemRoot\Logs\WMIRepair_$(Get-Date -Format 'yyyyMMdd_HHmmss').log" | |
| Function Write-Log { | |
| param([string]$Message) | |
| $TS = Get-Date -Format "yyyy-MM-dd HH:mm:ss" | |
| Write-Output "[$TS] $Message" | Tee-Object -FilePath $LogPath -Append | |
| } | |
| Write-Log "---------- WMI Repair Script Started ----------" | |
| #endregion | |
| #region Backup WMI Repository | |
| # Optionally backup the current repository before repair. | |
| try { | |
| $BackupFile = "$env:SystemRoot\System32\wbem\Repository_Backup_$(Get-Date -Format 'yyyyMMdd_HHmmss').zip" | |
| $RepositoryPath = "$env:SystemRoot\System32\wbem\Repository" | |
| if (Test-Path $RepositoryPath) { | |
| Write-Log "Backing up WMI repository to $BackupFile" | |
| Compress-Archive -Path "$RepositoryPath\*" -DestinationPath $BackupFile -Force | |
| } | |
| } catch { | |
| Write-Log "Warning: Failed to create repository backup. $_" | |
| } | |
| #endregion | |
| #region Diagnostics | |
| try { | |
| Write-Log "Diagnosing WMI repository health..." | |
| $verifyResult = & winmgmt /verifyrepository | |
| Write-Log "winmgmt /verifyrepository: $verifyResult" | |
| if ($verifyResult -like "*repository is consistent*") { | |
| Write-Log "Result: WMI repository is consistent. No repair needed." | |
| exit 0 | |
| } else { | |
| Write-Log "Repository is not consistent. Proceeding with salvage." | |
| } | |
| } | |
| catch { | |
| Write-Log "Error during repository check: $_" | |
| } | |
| #endregion | |
| #region Attempting Salvage Repair | |
| try { | |
| $salvageResult = & winmgmt /salvagerepository | |
| Write-Log "winmgmt /salvagerepository: $salvageResult" | |
| $verifyAgain = & winmgmt /verifyrepository | |
| Write-Log "After salvage, verify: $verifyAgain" | |
| if ($verifyAgain -like "*repository is consistent*") { | |
| Write-Log "Salvage succeeded. Exiting." | |
| exit 0 | |
| } else { | |
| Write-Log "Salvage failed. Preparing for hard reset." | |
| } | |
| } | |
| catch { | |
| Write-Log "Error during salvage repair: $_" | |
| } | |
| #endregion | |
| #region Prepare for WMI Service Operations | |
| try { | |
| Write-Log "Stopping Winmgmt service (and dependents)..." | |
| Stop-Service -Name winmgmt -Force -ErrorAction Stop | |
| Start-Sleep -Seconds 5 | |
| } catch { | |
| Write-Log "Warning: Could not stop Winmgmt service $($_.Exception.Message)" | |
| } | |
| #endregion | |
| #region Hard Repository Reset | |
| try { | |
| Write-Log "Resetting WMI repository. This operation will restore WMI to a default state." | |
| & winmgmt /resetrepository | Out-Null | |
| Write-Log "Repository reset complete. Now verifying consistency." | |
| $resetVerify = & winmgmt /verifyrepository | |
| Write-Log "After reset, verify: $resetVerify" | |
| if ($resetVerify -notlike "*repository is consistent*") { | |
| Write-Log "Critical: WMI repository is still inconsistent after reset." | |
| throw "WMI repository reset failed." | |
| } | |
| } | |
| catch { | |
| Write-Log "Error during hard repository reset: $_" | |
| exit 1 | |
| } | |
| #endregion | |
| #region Selective DLL Re-Registration | |
| # Only register critical WMI DLLs, not all in the directory. Avoid indiscriminate registration! | |
| # Common files: scecli.dll, userenv.dll, wmiprvse.exe (when needed). | |
| try { | |
| $dllList = @('scecli.dll', 'userenv.dll') | |
| foreach ($dll in $dllList) { | |
| $fullPath = Join-Path $env:SystemRoot "System32\$dll" | |
| if (Test-Path $fullPath) { | |
| Write-Log "Registering $dll with regsvr32" | |
| & regsvr32.exe /s $fullPath | |
| } else { | |
| Write-Log "Warning: $dll not found at expected location." | |
| } | |
| } | |
| # Optionally, register WMI provider host: | |
| $wmiprvse = Join-Path $env:SystemRoot "System32\wbem\wmiprvse.exe" | |
| if (Test-Path $wmiprvse) { | |
| Write-Log "Registering wmiprvse.exe" | |
| & $wmiprvse /regserver | |
| } | |
| } catch { | |
| Write-Log "Error during DLL re-registration: $_" | |
| } | |
| #endregion | |
| #region MOF and MFL Recompilation | |
| # Only recompile MOF/MFL files not related to uninstall or removal. | |
| try { | |
| $wbemPath = "$env:SystemRoot\System32\wbem" | |
| $mofFiles = Get-ChildItem "$wbemPath\*.mof" | Where-Object { $_.Name -notmatch 'uninstall|remove' } | |
| $mflFiles = Get-ChildItem "$wbemPath\*.mfl" | Where-Object { $_.Name -notmatch 'uninstall|remove' } | |
| foreach ($file in $mofFiles) { | |
| Write-Log "Compiling MOF file: $($file.FullName)" | |
| & mofcomp.exe $file.FullName | Out-Null | |
| } | |
| foreach ($file in $mflFiles) { | |
| Write-Log "Compiling MFL file: $($file.FullName)" | |
| & mofcomp.exe $file.FullName | Out-Null | |
| } | |
| } catch { | |
| Write-Log "Error during MOF/MFL recompilation: $_" | |
| } | |
| #endregion | |
| #region Restart WMI Service | |
| try { | |
| Write-Log "Configuring Winmgmt service to automatic and starting service..." | |
| Set-Service -Name winmgmt -StartupType Automatic | |
| Start-Service -Name winmgmt -ErrorAction Stop | |
| Write-Log "Winmgmt service started." | |
| Start-Sleep -Seconds 5 | |
| } catch { | |
| Write-Log "Error restarting Winmgmt service: $_" | |
| } | |
| #endregion | |
| #region Final Verification and Summary | |
| try { | |
| $finalResult = & winmgmt /verifyrepository | |
| Write-Log "Final verification: $finalResult" | |
| if ($finalResult -like "*repository is consistent*") { | |
| Write-Log "WMI repair successful. WMI repository is now consistent." | |
| } else { | |
| Write-Log "Repair process completed, but WMI repository may still have issues. Manual intervention required." | |
| } | |
| } | |
| catch { | |
| Write-Log "Error during final verification: $_" | |
| } | |
| Write-Log "---------- WMI Repair Script Finished ----------" | |
| #endregion |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment