none
[分享]如何解決因註冊表訪問權限被錯誤設置導致程序不能正常運行的例子和相關 PowerShell 解決代碼 RRS feed

  • 常规讨论

  • 前不久我在升級 Flash Player ActiveX 10.1 後發現標準用戶下 Internet Explorer 不能打開某些頁面的 Flash 對象(管理員帳戶可以), 遂進行檢查, 最後找出了原因和解決方法.

    不能打開的 Flash 對象的截圖:

    原因:
    因為註冊表項 HKCR\MIME 的訪問權限被錯誤設置, Administrators 組和 Users 組都擁有完全訪問權限, 而 Flash 對應的 application/x-shockwave-flash 卻是 Administrators 組和 SYSTEM 組擁有訪問權限(因當時忘保存錯誤的權限設置, 所以這個只是大概回憶), 這就導致了在標準用戶帳戶下 Internet Explorer 不能打開指定的 MIME 類型的 Flash 對象.

    解決方法:
    通過 regedit 或 PowerShell 將 HKLM\MIME 項的訪問權限設置為從父項繼承.

    相關 PowerShell 代碼:

    復制以下代碼

    #begin
    
    $regAcl = get-acl 'HKLM:\SOFTWARE\Classes\MIME';
    $rules = $regAcl.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier]);
    foreach ($r in $rules) {$regAcl.RemoveAccessRule($r)};
    $regAcl.SetAccessRuleProtection($false, $true);
    $regAcl | set-acl;
    
    $regChilditems = get-childitem 'HKLM:\SOFTWARE\Classes\MIME' -Recurse;
    
    foreach ($ci in $regChilditems) {
    	if ($ci -eq $null) {continue;};
    	$regAcl = get-acl ($ci.Name -replace 'HKEY_LOCAL_MACHINE', 'HKLM:');
    	$rules = $regAcl.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier]);
    	foreach ($r in $rules) {$regAcl.RemoveAccessRule($r)};
    	$regAcl.SetAccessRuleProtection($false, $true);
    	$regAcl | set-acl;
    }
    
    #end

    復制以上代碼


    注:
    1. 如果你的系統沒有類似問題, 不要重置註冊表項的訪問權限.
    2. 如果要以 PowerShell 解決該問題, 請直接複製上述代碼到 PowerShell 中(以管理員身份運行 PowerShell), 如果遇到 >> 符號, 請直接按 ENTER 鍵直到沒有該提示為止.
    或者將代碼保存一個 ps1 腳本文件. 因為默認情況下 PowerShell 不允許執行腳本, 所以需要以管理員身份運行 PowerShell 并執行命令:

    set-executionpolicy remotesigned

    如果啟用了該命令後仍然不能執行, 那麼請打開 Check-RegAclEx.ps1 的屬性窗體并 "單擊解除鎖定" 按鈕.

    爲了以後在遇到類似問題時, 能一次找出不能訪問的註冊表項. 我也編寫了一個 PowerShell 腳本 Check-RegAclEx.ps1

    用法:

    .\Check-RegAclEx.ps1 '註冊表路徑' 是否遍歷所有子項的布爾值

    注:
    1. 所謂不能訪問的註冊表項是指: 當前用戶權限不能讀操作訪問的註冊表項. 對於找出的註冊表項, 並不表明其訪問權限設置一定有問題, 因為有的項確實是只能通過 Administrators 組, SYSTEM 用戶或 TrustedInstaller 服務才能訪問, 結果只是簡單羅列, 是否真的有問題需要仔細甄別.
    2. 註冊表路徑只支持符合 PowerShell Drive 命名的 HKCU: 和 HKLM: 及其子項.
    3. 對於找到的不能訪問的註冊表項, 將以一個 System.String 返回, 你可以用 Out-File 或 Add-Content cmdlet 轉儲為文本文件.
    4. 如果啟用了遍歷, 那麼對於整個 HKLM:\ 子項的檢查, 會耗費相當長的時間, 32位Windows XP 為 73 分鐘, 64位Windows 7 為 92 分鐘.
    5. 如果想在遍歷過程中終止檢查, 請按 Ctrl+C. 但會丟棄(轉儲)已經找到的不能訪問的註冊表項.

    下載地址:
    http://cid-1536000e36ab647b.office.live.com/self.aspx/.Public/PowerShell%20V2.0/Check-RegAclEx.ps1

    真是汗顏, 其實還有兩個 SysinternalsSuite 工具可以實現: AccessChk 和 AccessEnum.

    下載地址:
    AccessChk (更新日期: 2010年04月28日)
    http://technet.microsoft.com/en-us/sysinternals/bb664922.aspx

    AccessEnum (更新日期: 2006年11月01日)
    http://technet.microsoft.com/en-us/sysinternals/bb897332.aspx


    Folding@Home
    • 已更改类型 repl 2010年6月24日 9:10 錯誤選擇
    • 已编辑 repl 2010年9月27日 12:56 對 PowerShell 代碼進行排版
    2010年6月24日 9:09

全部回复