本文提供了一个脚本,用于编译所有已注册的托管对象格式 (MOF) 文件。
Windows Management Instrumentation (WMI) 存储库通过编译多个 MOF 文件来创建类和提供程序注册。
大多数 MOF 文件位于 C:\Windows\System32\wbem 文件夹中,但许多其他文件可能也位于注册其他类或提供程序的应用程序文件夹中。
编译的 MOF 列表保留在注册表值 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Wbem\CIMOM\Autorecover MOFs中。
如果 WMI 检测到存储库已损坏且不可用,它将创建新的空存储库,并自动编译注册表值中列出的所有 MOF 以还原所有预期的对象。
如果遇到可能与某些类或提供程序未正确注册相关的奇怪行为,则可以使用以下脚本重新编译所有 MOF 文件。 该脚本在开始编译并记录所有已执行操作及其结果的日志之前导出注册表值的副本。
重要
此示例脚本在任何Microsoft标准支持计划或服务下都不受支持。
示例脚本按原样提供,没有任何保证。 Microsoft进一步否认所有默示担保,包括不限于适销性或针对特定用途的适用性的任何默示担保。
示例脚本和文档的使用或性能导致的整个风险依然存在。 在任何情况下,不得Microsoft、其作者或参与创建、制作或交付脚本的任何其他人对任何损害负责(包括但不限于业务利润损失、业务中断、业务中断、业务信息损失或其他经济损失)因使用或无法使用示例脚本或文档而导致的损害。 即使Microsoft被告知这种损害的可能性。
Function Write-Log {
param( [string] $msg )
$msg = (get-date).ToString("yyyyMMdd HH:mm:ss.fff") + " " + $msg
Write-Host $msg
$msg | Out-File -FilePath $outfile -Append
}
$myWindowsID = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal = new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
$adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator
if (-not $myWindowsPrincipal.IsInRole($adminRole)) {
Write-Output "This script needs to be run as Administrator"
exit
}
$Root = Split-Path (Get-Variable MyInvocation).Value.MyCommand.Path
$resName = "CompMOF-" + $env:computername +"-" + $(get-date -f yyyyMMdd_HHmmss)
$resDir = $Root + "\" + $resName
$outfile = $resDir + "\script-output.txt"
$errfile = $resDir + "\script-errors.txt"
$RdrOut = " >>""" + $outfile + """"
$RdrErr = " 2>>""" + $errfile + """"
New-Item -itemtype directory -path $resDir | Out-Null
New-PSDrive -PSProvider registry -Root HKEY_LOCAL_MACHINE -Name HKLM -ErrorAction SilentlyContinue | Out-Null
$mof = (get-itemproperty -ErrorAction SilentlyContinue -literalpath ("HKLM:\SOFTWARE\Microsoft\Wbem\CIMOM")).'Autorecover MOFs'
if ($mof.length -eq 0) {
Write-Log ("The registry key ""HKLM:\SOFTWARE\Microsoft\Wbem\CIMOM\Autorecover MOFs"" is missing or empty")
exit
}
$mof | Out-File ($resDir + "\Autorecover MOFs.txt")
foreach ($line in $mof) {
if ($line.ToLower().contains("uninstall")) {
Write-Log ("Skipping " + $line)
} else {
$line = $line.Replace("%windir%", $env:windir)
$line = $line.Replace("%ProgramFiles%", $env:ProgramFiles)
if ($line -gt "") {
if (Test-path $line) {
Write-Log ("Compiling " + $line)
$cmd = "mofcomp """ + $line + """"+ $RdrErr
Write-Log $cmd
Invoke-Expression ($cmd) | Out-File -FilePath $outfile -Append
} else {
Write-Log ("Missing file " + $line)
}
}
}
}