首页 > 解决方案 > PowerShell 与 reg.exe 同步

问题描述

我想为大量注册表项设置相同的值,因此我创建了一个 PowerShell 2.0 脚本来遍历这些注册表项。

PowerShell 脚本:

function Main {
    param (
        [ Parameter( Mandatory = $true ) ] $ScriptInvocation
    )
    RequireElevation -ScriptInvocation $ScriptInvocation
    $ScriptFolder = Split-Path -Parent $ScriptInvocation.MyCommand.Definition
    Push-Location -Path $ScriptFolder
    ApplyVariants
    Pop-Location
}

function RequireElevation {
    param (
        [ Parameter( Mandatory = $true ) ] $ScriptInvocation
    )
    $CurrentIdentity = [Security.Principal.WindowsIdentity]::GetCurrent()
    $CurrentPrincipal = [Security.Principal.WindowsPrincipal] $CurrentIdentity
    $AdministratorRole = [Security.Principal.WindowsBuiltInRole]::Administrator
    if( -not $CurrentPrincipal.IsInRole( $AdministratorRole ) ) {
        $ScriptPath = $ScriptInvocation.MyCommand.Path
        Start-Process -FilePath 'powershell.exe' -ArgumentList '-File', """$ScriptPath""" -Verb RunAs
        Exit
    }
}

function ApplyVariants {
    ApplyVariant -RegFilePath '.\Folder View Per TopView.reg' -Change @{ `
        OldString = '{5c4f28b5-f869-4e84-8e60-f11db97c5cc7}\TopViews\{00000000-0000-0000-0000-000000000000}'; `
        NewString = '{5c4f28b5-f869-4e84-8e60-f11db97c5cc7}\TopViews\{00000000-0000-0000-0000-000000000000}' }
    ApplyVariant -RegFilePath '.\Folder View Per TopView.reg' -Change @{ `
        OldString = '{5c4f28b5-f869-4e84-8e60-f11db97c5cc7}\TopViews\{00000000-0000-0000-0000-000000000000}'; `
        NewString = '{5f4eab9a-6833-4f61-899d-31cf46979d49}\TopViews\{77f0bfb4-6aa3-440b-9f6d-1c147467806d}' }
    ApplyVariant -RegFilePath '.\Folder View Per TopView.reg' -Change @{ `
        OldString = '{5c4f28b5-f869-4e84-8e60-f11db97c5cc7}\TopViews\{00000000-0000-0000-0000-000000000000}'; `
        NewString = '{5f4eab9a-6833-4f61-899d-31cf46979d49}\TopViews\{82ba0782-5b7a-4569-b5d7-ec83085f08cc}' }
    ApplyVariant -RegFilePath '.\Folder View Per TopView.reg' -Change @{ `
        OldString = '{5c4f28b5-f869-4e84-8e60-f11db97c5cc7}\TopViews\{00000000-0000-0000-0000-000000000000}'; `
        NewString = '{5f4eab9a-6833-4f61-899d-31cf46979d49}\TopViews\{92d203dc-8565-4902-b92c-eaaa54d7364a}' }
    # And many, many more ...
}

function ApplyVariant {
    param (
        [ Parameter( Mandatory = $true ) ] $RegFilePath,
        [ Parameter( Mandatory = $true ) ] $Change
    )
    $TmpFilePath = '.\TemporaryFileCreatedByPowerShell.reg'
    $OriginalText = Get-Content -Path $RegFilePath
    $VariantText = $OriginalText -replace [Regex]::Escape( $Change.OldString ), $Change.NewString
    Set-Content -Path $TmpFilePath -Value $VariantText
    # I hope the file is saved before this line
    UpdateRegistry -RegFilePath $TmpFilePath
    # I hope the file is not required after this line
    Remove-Item -Path $TmpFilePath
}

function UpdateRegistry {
    param (
        [ Parameter( Mandatory = $true ) ] $RegFilePath
    )
    # Does this really wait?
    Start-Process -FilePath 'reg.exe' -ArgumentList 'import', """$RegFilePath""" -Wait
}

Main -ScriptInvocation $MyInvocation

我要设置的值在这个 .reg 文件中:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderTypes\{5c4f28b5-f869-4e84-8e60-f11db97c5cc7}\TopViews\{00000000-0000-0000-0000-000000000000}]
"LogicalViewMode"=dword:00000001
"Mode"=-
"IconSize"=-
"HideFileNames"=-
"ColumnList"="prop:0(34)System.ItemNameDisplay;0System.Size;0System.DateModified;0System.DateCreated"
"SortByList"="prop:System.ItemNameDisplay"
"GroupBy"=-
"GroupAscending"=-
"StackBy"=-
"DateCategorizerInfo"=-
"PrimaryProperty"=-

当我运行这个脚本时,我没有收到任何错误消息。(即使我-NoExit在 PowerShell 的命令行中添加了一个参数。)

但是,对于某些键,运行脚本后未设置值。但是,如果我注释掉 中的行ApplyVariants并单独运行每一行,则设置给定键的值。

我怀疑存在一些同步问题。也许这些文件在 reg.exe 读取它们之前就被删除了。

-Wait等待 reg.exe 完成就足够了吗?什么会导致这个问题?

标签: powershellsynchronizationregistry

解决方案


推荐阅读