AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / computer / 问题 / 1614623
Accepted
Ξένη Γήινος
Ξένη Γήινος
Asked: 2021-01-04 02:37:59 +0800 CST2021-01-04 02:37:59 +0800 CST 2021-01-04 02:37:59 +0800 CST

如何将 .reg 文件自动转换为 PowerShell set-itemproperty 命令?

  • 772

我是一个经常修改注册表的修补匠,我讨厌不得不.reg一个一个地单击许多文件;如何自动将.reg文件转换为 PowerShellSet-ItemProperty命令?

  • 我找到了一个这样做的站点 [ Registry to PowerShell Converter ],但是输出不是我想要的格式;Set-ItemProperty我希望它使用/ Remove-Item/具有与以下完全相同的语法,仅此New-Item而已:
    Windows Registry Editor Version 5.00
    
    [HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\PushNotifications]
    "NoToastApplicationNotification"=dword:00000001
    
    • cmd:
      Reg Add "HKLM\Software\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" /v "NoToastApplicationNotification" /t REG_DWORD /d 1
      
    • powershell:
      Set-ItemProperty -Path "HKLM:\Software\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" -Name "NoToastApplicationNotification" -Type DWord -Value 1
      

  • 产生预期结果的命令应该是:
    "Set-ItemProperty -Path " + $path + "-Name " + $name + "-Value " + $value
    
    • 我创建了一个 ASCII 表,其中包含在此处找到并上传到此处的信息,管理此 [输出]:
      $ASCII=import-csv ".\desktop\ascii.csv"
      [array]$AsciiTable=0..255 | foreach-object{
        $Decimal=$ASCII[$_].DEC
        $Hexadecimal=$ASCII[$_].HEX
        $Binary=$ASCII[$_].BIN
        $Octonary=$ASCII[$_].OCT
        $Symbol=$ASCII[$_].Symbol
        $Value=[char]$_
        $Description=$ASCII[$_].Description
        $HTMLName=$ASCII[$_].HTMLName
        $HTMLNumber=$ASCII[$_].HTMLNumber
        [pscustomobject]@{Decimal=$Decimal;Hexadecimal=$Hexadecimal;Binary=$Binary;Octonary=$Octonary;Symbol=$Symbol;Value=$Value;Description=$Description;HTMLName=$HTMLName;HTMLNumber=$HTMLNumber}
      }
      $AsciiTable | Export-csv ".\Desktop\AsciiTable.csv"
      


目前我已经管理了这个,这是不完整的,但想法是通过文件循环index,通过正则表达式匹配为变量分配值,将类型和配置单元名更改为 PowerShell 中使用的值:

$registry=get-content $regfile

for ($i=0;$i -lt $registry.count;$i++){
  $line=$registry | select-object -index $i
  if ($line -match '\[' -and '\]') {
    $path=$line -replace '\[|\]'
    switch ($path)
    {
      {$path -match "HKEY_CLASSES_ROOT"}    {$path=$path -replace "HKEY_CLASSES_ROOT","HKCR:"}
      {$path -match "HKEY_CURRENT_USER"}    {$path=$path -replace "HKEY_CURRENT_USER","HKCU:"}
      {$path -match "HKEY_LOCAL_MACHINE"}   {$path=$path -replace "HKEY_LOCAL_MACHINE","HKLM:"}
      {$path -match "HKEY_USERS"}           {$path=$path -replace "HKEY_USERS","HKU:"}
      {$path -match "HKEY_CURRENT_CONFIG"}  {$path=$path -replace "HKEY_CURRENT_CONFIG","HKCC:"}
    }
  }
  else {
    $name=($line | select-string -pattern "`"([^`"=]+)`"").matches.value | select-object -first 1
    switch ($line)
  {
  {$line -match}
}


有六种注册表值类型 [ REG_SZ, REG_BINARY, REG_DWORD, REG_QWORD, REG_MULTI_SZ, REG_EXPAND_SZ] 并且我在文件中只看到一种DWORD值类型.reg,尽管我设法创建了一个包含所有类型的注册表项:

  • RegEdit:
    在此处输入图像描述
  • .reg:
    Windows Registry Editor Version 5.00
    
    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AarSvc]
    "DependOnService"=hex(7):41,00,75,00,64,00,69,00,6f,00,73,00,72,00,76,00,00,00,\
      00,00
    "Description"="@%SystemRoot%\\system32\\AarSvc.dll,-101"
    "DisplayName"="@%SystemRoot%\\system32\\AarSvc.dll,-100"
    "ErrorControl"=dword:00000001
    "FailureActions"=hex:80,51,01,00,00,00,00,00,00,00,00,00,04,00,00,00,14,00,00,\
      00,01,00,00,00,10,27,00,00,01,00,00,00,10,27,00,00,01,00,00,00,10,27,00,00,\
      00,00,00,00,00,00,00,00
    "ImagePath"=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,\
      74,00,25,00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,73,\
      00,76,00,63,00,68,00,6f,00,73,00,74,00,2e,00,65,00,78,00,65,00,20,00,2d,00,\
      6b,00,20,00,41,00,61,00,72,00,53,00,76,00,63,00,47,00,72,00,6f,00,75,00,70,\
      00,20,00,2d,00,70,00,00,00
    "ObjectName"="NT Authority\\LocalService"
    "RequiredPrivileges"=hex(7):53,00,65,00,49,00,6d,00,70,00,65,00,72,00,73,00,6f,\
      00,6e,00,61,00,74,00,65,00,50,00,72,00,69,00,76,00,69,00,6c,00,65,00,67,00,\
      65,00,00,00,00,00
    "ServiceSidType"=dword:00000001
    "Start"=dword:00000003
    "Type"=dword:00000060
    "UserServiceFlags"=dword:00000003
    "New Value #1"=hex(b):00,00,00,00,00,00,00,00
    
    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AarSvc\Parameters]
    "ServiceDll"=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,\
      00,74,00,25,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,\
      41,00,61,00,72,00,53,00,76,00,63,00,2e,00,64,00,6c,00,6c,00,00,00
    "ServiceDllUnloadOnStop"=dword:00000001
    "ServiceMain"="ServiceMain"
    


如何在 a 中确定注册表类型.reg,因为预期的最终结果是包含转换后的命令的文本文件/字符串数组/PowerShell 脚本?

  • 在 a.reg中,我知道 type 的值REG_DWORD写为dword,REG_SZ用引号括起来的纯文本,REG_QWORD如qword(此处所示),并且已经将注册表类型映射到其相应的 PowerShell 属性:
    REG_SZ        → String
    REG_EXPAND_SZ → ExpandString
    REG_MULTI_SZ  → MultiString
    REG_BINARY    → Binary
    REG_DWORD     → DWord
    REG_QWORD     → QWord
    
    从上面推断的关系:
    switch ($line)
    {
      {$line -match '"="'}      {$type="string"}
      {$line -match "dword"}    {$type="dword"}
      {$line -match "qword"}    {$type="qword"}
      {$line -match "hex\(2\)"} {$type="expandstring";break}
      {$line -match "hex\(7\)"} {$type="multistring";break}
      {$line -match "hex\(b\)"} {$type="qword";break}
      {$line -match "hex"}      {$type="binary"}
    }
    


如何检测和解码注册表 hex babbles 以及是否有其他方法可以在 a 中写入REG_EXPAND_SZ、REG_MULTI_SZ和REG_BINARYtypes .reg(即分别为 as和ExpandStringtype )?MultiStringBinary

  • 将注册表可扩展字符串值解析为纯文本的脚本:
    function parse-expandstring {
      PARAM (
        [Parameter(ValueFromPipeline=$true, Mandatory=$true)] [System.String]$expandstring
      )
    
      $AsciiTable=import-csv ".\desktop\AsciiTable.csv"
      [array]$hex=$expandstring -split'[\,\\]' | where {-not ([string]::IsNullOrWhiteSpace($_))} | %{$_.trimstart()}
      $hexadecimal=0..($hex.count-1) | where {$_ % 2 -ne 1} | foreach-object {$hex[$_]}
      $text=@()
      foreach ($hexadecima in $hexadecimal) {
        for ($i=0;$i -le 255;$i++) {
          if ($AsciiTable[$i].hexadecimal -eq $hexadecima) {
            $text+=$AsciiTable[$i].value
          }
        }
      }
      $text=$text -join ""
      $text
    }
    
  • Function解析REG_QWORD:
    function parse-qword {
      PARAM (
        [Parameter(ValueFromPipeline=$true, Mandatory=$true)] [System.String]$qword
      )
      [array]$qword=$qword -split','
      $qword=for ($i=$qword.count-1;$i -ge 0;$i--) {$qword[$i]}
      $hexvalue=$qword -join ""
      $hexvalue=$hexvalue.trimstart("0")
      $hexvalue
    }
    
  • Function解析REG_BINARY:
    function parse-binary {
      PARAM (
        [Parameter(ValueFromPipeline=$true, Mandatory=$true)] [System.String]$binary
      )
      [array]$hex=$binary -split'[,\\]' | where {-not ([string]::IsNullOrWhiteSpace($_))} | %{$_.trimstart()}
      $hex=$hex -join ""
        $hex
    }
    
  • Function解析REG_MULTI_SZ:
    function parse-multistring {
      PARAM (
        [Parameter(ValueFromPipeline=$true, Mandatory=$true)] [System.String]$multistring
        )
    
      $AsciiTable=import-csv ".\desktop\AsciiTable.csv"
      [array]$hex=$multistring -split'[\,\\]' | where {-not ([string]::IsNullOrWhiteSpace($_))} | %{$_.trimstart()}
      $hexadecimal=0..($hex.count-1) | where {$_ % 2 -ne 1} | foreach-object {$hex[$_]}
      $text=@()
      foreach ($hexadecima in $hexadecimal) {
        for ($i=0;$i -le 255;$i++) {
          if ($AsciiTable[$i].hexadecimal -eq $hexadecima) {
            if ($i -ne 0) {$text+=$AsciiTable[$i].value}
            else {$text+="\0"}
          }
        }
      }
      $text=$text -join ""
      $text
    }
    


脚本几乎完成了,已经创建了Remove-Item, New-Item, 和Remove-ItemPropertyswitch 条件;现在,难题的最后一部分是编写一个匹配值的正则表达式。完成后,我将在此处发布它作为答案。

  • 伪代码:
    if $line match [ and ]->$line match [-HKEY -> Remove-Item
    else $registry[$i+1] eq ""->New-Item
    elseif $line match "=-" -> Remove-ItemProperty
    
  • 我创建了一个 ASCII 哈希表用作字典:
    $asciihex=@{}
    0..255 | % {
      $number=$_
      [string]$hex=$number.tostring('x')
      if ($hex.length -eq 1) {$hex='{1}{0}' -f $hex,'0'}
      $char=[char]$number
      $asciihex.add($hex,$char)
      }
    
    • 要在给定代码点查找字符:
      # Change:
        $asciihex.'00'
      
      # to:
        $asciihex.'ff'
      
    • 要在任何代码点查找字符:
      # Don't use $asciihex to print it
        $asciihex.$codepoint
      

要从行中 grep 值,请使用-replace $name+$type获取值。

powershell command-line
  • 2 2 个回答
  • 3413 Views

2 个回答

  • Voted
  1. Best Answer
    Xeнεi Ξэnвϵς
    2021-01-05T21:05:29+08:002021-01-05T21:05:29+08:00

    最终版本:

    Function reg2ps1 {
    
        [CmdLetBinding()]
        Param(
            [Parameter(ValueFromPipeline=$true, Mandatory=$true)]
            [Alias("FullName")]
            [string]$path,
            $Encoding = "utf8"
        )
    
        Begin {
            $hive = @{
                "HKEY_CLASSES_ROOT" = "HKCR:"
                "HKEY_CURRENT_USER" = "HKCU:"
                "HKEY_LOCAL_MACHINE" = "HKLM:"
                "HKEY_USERS" = "HKU:"
                "HKEY_CURRENT_CONFIG" = "HKCC:"
            }
            [system.boolean]$isfolder=$false
            $addedpath=@()
        }
        Process {
            switch (test-path $path -pathtype container)
            {
                $true {$files=(get-childitem -path $path -recurse -force -file -filter "*.reg").fullname;$isfolder=$true}
                $false {if($path.endswith(".reg")){$files=$path}}
            }
            foreach($File in $Files) {
                $Commands = @()
                [string]$text=$nul
                $FileContent = Get-Content $File | Where-Object {![string]::IsNullOrWhiteSpace($_)} | ForEach-Object { $_.Trim() }
                $joinedlines = @()
                for ($i=0;$i -lt $FileContent.count;$i++){
                    if ($FileContent[$i].EndsWith("\")) {
                        $text=$text+($FileContent[$i] -replace "\\").trim()
                    } else {
                        $joinedlines+=$text+$FileContent[$i]
                        [string]$text=$nul
                    }
                }
    
                foreach ($joinedline in $joinedlines) {
                    if ($joinedline -match '\[' -and $joinedline -match '\]' -and $joinedline -match 'HKEY') {
                        $key=$joinedline -replace '\[|\]'
                        switch ($key.StartsWith("-HKEY"))
                        {
                            $true {
                                $key=$key.substring(1,$key.length-1)
                                $hivename = $key.split('\')[0]
                                $key = "`"" + ($key -replace $hivename,$hive.$hivename) + "`""
                                $Commands += 'Remove-Item -Path {0} -Force -Recurse' -f $key
                            }
                            $false {
                                $hivename = $key.split('\')[0]
                                $key = "`"" + ($key -replace $hivename,$hive.$hivename) + "`""
                                if ($addedpath -notcontains $key) {
                                    $Commands += 'New-Item -Path {0} -ErrorAction SilentlyContinue | Out-Null'-f $key
                                    $addedpath+=$key
                                }
                            }
                        }
                    }
                    elseif ($joinedline -match "`"([^`"=]+)`"=") {
                        [System.Boolean]$delete=$false
                        $name=($joinedline | select-string -pattern "`"([^`"=]+)`"").matches.value | select-object -first 1
                        switch ($joinedline)
                        {
                            {$joinedline -match "=-"} {$commands+=$Commands += 'Remove-ItemProperty -Path {0} -Name {1} -Force' -f $key, $Name;$delete=$true}
                            {$joinedline -match '"="'} {
                                $type="string"
                                $value=$joinedline -replace "`"([^`"=]+)`"="
                            }
                            {$joinedline -match "dword"} {
                                $type="dword"
                                $value=$joinedline -replace "`"([^`"=]+)`"=dword:"
                                $value="0x"+$value
                            }
                            {$joinedline -match "qword"} {
                                $type="qword"
                                $value=$joinedline -replace "`"([^`"=]+)`"=qword:"
                                $value="0x"+$value
                            }
                            {$joinedline -match "hex(\([2,7,b]\))?:"} {
                                $value=($joinedline -replace "`"[^`"=]+`"=hex(\([2,7,b]\))?:").split(",")
                                $hextype=($joinedline | select-string -pattern "hex(\([2,7,b]\))?").matches.value
                                switch ($hextype)
                                {
                                    {$hextype -eq 'hex(2)' -or $hextype -eq 'hex(7)'} {
                                        $value=for ($i=0;$i -lt $value.count;$i+=2) {
                                            switch ($hextype)
                                            {
                                                'hex(2)' {if ($value[$i] -ne '00') {[string][char][int]('0x'+$value[$i])}}
                                                'hex(7)' {if ($value[$i] -ne '00') {[string][char][int]('0x'+$value[$i])} else {"\0"}}
                                            }
                                        }
                                        $value=$value -join ""
                                        switch ($hextype)
                                        {
                                            'hex(2)' {$type="expandstring"}
                                            'hex(7)' {$type="multistring"}
                                        }
                                    }
                                    'hex(b)' {
                                        $type="qword"
                                        $value=for ($i=$value.count-1;$i -ge 0;$i--) {$value[$i]}
                                        $value='0x'+($value -join "").trimstart('0')
                                    }
                                    'hex' {
                                        $type="binary"
                                        $value='0x'+($value -join "")
                                    }
                                }
                            }
                        }
                        if ($delete -eq $false) {$commands+='Set-ItemProperty -Path {0} -Name {1} -Type {2} -Value {3}' -f $key, $name, $type, $value}
                    }
                    elseif ($joinedline -match "@=") {
                        $name='"(Default)"';$type='string';$value=$joinedline -replace '@='
                        $commands+='Set-ItemProperty -Path {0} -Name {1} -Type {2} -Value {3}' -f $key, $name, $type, $value
                    }
                
                }
                $parent=split-path $file -parent
                $filename=[System.IO.Path]::GetFileNameWithoutExtension($file)
                $Commands | out-file -path "${parent}\${filename}_reg.ps1" -encoding $encoding
            }
            if ($isfolder -eq $true) {
                $allcommands=(get-childitem -path $path -recurse -force -file -filter "*_reg.ps1").fullname | where-object {$_ -notmatch "allcommands_reg"} | foreach-object {get-content $_}
                $allcommands | out-file -path "${path}\allcommands_reg.ps1" -encoding $encoding
            }
        }
    }
    $path = Read-Host "input path"
    reg2ps1 $path
    

    This is the final version, based on my previous script and the script provided by SimonS. The script is truly complete, all bugs fixed, it can correctly parse all 6 registry value types: REG_SZ, REG_DWORD, REG_QWORD, REG_BINARY, REG_MULTI_SZ and REG_EXPAND_SZ, converts each [HKEY_* line to a New-Item line, each [-HKEY_* to a Remove-Item line, each "([^"=]+)"=- line to a Remove-ItemProperty line, and each "([^"=]+)"= line to an appropriate Set-ItemProperty line based on the property type. It accepts an inputted path, automatically detect whether the path points to a file or a folder, if a file with extension of .reg, it outputs converted commands to a file at the parent folder of the file with ${filename}_reg.ps1 as its filename; If a folder, converts all .reg files inside that folder, and outputs a ${filename}_reg.ps1 file for each .reg file to that folder, and then put all _reg.ps1 commands into one allcommands.ps1 in the folder.

    I made numerous tests and have confirmed it is really really working. The script is now complete. I made major improvements, used better formats, and simplified the code greatly, used better logics and made many other enhancements.

    This is truly complete, to use my final version, copy paste the function into an opened powershell window, and invoke it like reg2ps1 "full\path\to\content" or save it as a .ps1 file and run it by cd $scriptdir and .\reg2ps1.ps1, then input full\path\to\content, notice you shouldn't use any quotes, or the path can't be found...


    Update

    I made a mistake in the code, by specifying the -Force parameter when using New-Item, if the item already exists, it will re-create the item, emptying the item in the process, this is not what I intended, now it's fixed. By removing -Force parameter in the New-Item line, trying to create an item that already exists will generate an error that tells the item exists, and will not reset the item. The error message is hidden by -ErrorAction SilentlyContinue. If the item doesn't exist, it will be created, the item will be empty, the process will prompt a message that tells the item is created, the message is hidden by | Out-Null.

    • 3
  2. Pete Gomersall
    2022-06-12T13:06:52+08:002022-06-12T13:06:52+08:00

    This is pretty good, but you have some errors in your conversion code.

    1. 在包含转义字符的 reg 值文本中,例如“cmd.exe /s /k pushd "%V"”,您的转换不会将 " 替换为 `" 或类似字符。
    2. 使用 -Type 属性时,您需要 New-ItemProperty 而不是 Set-ItemProperty。
    3. 如果不先设置驱动器,PowerShell 无法与“HKCR:”等一起使用。
    4. Out-File 路径参数为 -FilePath

    可能值得修复

    • 0

相关问题

  • 将前景颜色添加到 Powershell 配置文件?

  • Python 的“pass”参数的批处理等价物是什么?

  • 禁用后无法启用 Microsoft Print to PDF

  • 我可以让这个 PowerShell 脚本接受逗号吗?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何减少“vmmem”进程的消耗?

    • 11 个回答
  • Marko Smith

    从 Microsoft Stream 下载视频

    • 4 个回答
  • Marko Smith

    Google Chrome DevTools 无法解析 SourceMap:chrome-extension

    • 6 个回答
  • Marko Smith

    Windows 照片查看器因为内存不足而无法运行?

    • 5 个回答
  • Marko Smith

    支持结束后如何激活 WindowsXP?

    • 6 个回答
  • Marko Smith

    远程桌面间歇性冻结

    • 7 个回答
  • Marko Smith

    子网掩码 /32 是什么意思?

    • 6 个回答
  • Marko Smith

    鼠标指针在 Windows 中按下的箭头键上移动?

    • 1 个回答
  • Marko Smith

    VirtualBox 无法以 VERR_NEM_VM_CREATE_FAILED 启动

    • 8 个回答
  • Marko Smith

    应用程序不会出现在 MacBook 的摄像头和麦克风隐私设置中

    • 5 个回答
  • Martin Hope
    Saaru Lindestøkke 为什么使用 Python 的 tar 库时 tar.xz 文件比 macOS tar 小 15 倍? 2021-03-14 09:37:48 +0800 CST
  • Martin Hope
    CiaranWelsh 如何减少“vmmem”进程的消耗? 2020-06-10 02:06:58 +0800 CST
  • Martin Hope
    Jim Windows 10 搜索未加载,显示空白窗口 2020-02-06 03:28:26 +0800 CST
  • Martin Hope
    v15 为什么通过电缆(同轴电缆)的千兆位/秒 Internet 连接不能像光纤一样提供对称速度? 2020-01-25 08:53:31 +0800 CST
  • Martin Hope
    andre_ss6 远程桌面间歇性冻结 2019-09-11 12:56:40 +0800 CST
  • Martin Hope
    Riley Carney 为什么在 URL 后面加一个点会删除登录信息? 2019-08-06 10:59:24 +0800 CST
  • Martin Hope
    zdimension 鼠标指针在 Windows 中按下的箭头键上移动? 2019-08-04 06:39:57 +0800 CST
  • Martin Hope
    jonsca 我所有的 Firefox 附加组件突然被禁用了,我该如何重新启用它们? 2019-05-04 17:58:52 +0800 CST
  • Martin Hope
    MCK 是否可以使用文本创建二维码? 2019-04-02 06:32:14 +0800 CST
  • Martin Hope
    SoniEx2 更改 git init 默认分支名称 2019-04-01 06:16:56 +0800 CST

热门标签

windows-10 linux windows microsoft-excel networking ubuntu worksheet-function bash command-line hard-drive

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve