This is a PowerShell script I wrote a while ago that converts Windows Registry files to PowerShell commands(New-Item
, Remove-Item
, Set-ItemProperty
and Remove-ItemProperty
), it supports conversion of all six registry value types (REG_SZ, REG_DWORD, REG_QWORD, REG_BINARY, REG_EXPAND_SZ and REG_MULTI_SZ), and you got it right, I figured out how to correctly convert binary types.
You can view my original script here:https://superuser.com/a/1615077/1250181
Today I improved it, and this is the final version of my script, I used reg add
to add REG_BINARY values because Set-ItemProperty can't add them, I used commas instead of "\0" because that's the correct way to add them with Set-ItemProperty
, and Registry PSProvider does only provide 2 PSDrives by default: HKCU: and HKLM:, so if the registry files modifies other hives I added the lines to create them.
Please review my code(Tested on PowerShell 7, lower versions may not work):
Function reg2ps1 {
[CmdLetBinding()]
Param(
[Parameter(ValueFromPipeline=$true, Mandatory=$true)]
[Alias("FullName")]
[string]$path,
$Encoding = "utf8"
)
Begin {
$hive = @{
"HKEY_CLASSES_ROOT" = "HKCR:"
"HKEY_CURRENT_CONFIG" = "HKCC:"
"HKEY_CURRENT_USER" = "HKCU:"
"HKEY_LOCAL_MACHINE" = "HKLM:"
"HKEY_USERS" = "HKU:"
}
[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 = @()
if ($(Get-Content -Path $File -Raw) -match "HKEY_CLASSES_ROOT") {$commands+="New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT | Out-Null"}
elseif ($(Get-Content -Path $File -Raw) -match "HKEY_CURRENT_CONFIG") {$commands+="New-PSDrive -Name HKCC -PSProvider Registry -Root HKEY_CURRENT_CONFIG | Out-Null"}
elseif ($(Get-Content -Path $File -Raw) -match "HKEY_USERS") {$commands+="New-PSDrive -Name HKU -PSProvider Registry -Root HKEY_USERS | Out-Null"}
[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
[System.Boolean]$binary=$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 -match 'hex(\([2,7])\)'} {
$ValueEx='$value=for ($i=0;$i -lt $value.count;$i+=2) {if ($value[$i] -ne "00") {[string][char][int]("0x"+$value[$i])}'
switch ($hextype)
{
'hex(2)' {$type="ExpandString"; invoke-expression $($ValueEx+'}')}
'hex(7)' {$type="MultiString"; invoke-expression $($ValueEx+' else {","}}'); $value=0..$($value.count-3) | %{$value[$_]}}
}
$value=$value -join ""
if ($type -eq "ExpandString") {$value='"'+$value+'"'}
}
'hex(b)' {
$type="Qword"
$value=for ($i=$value.count-1;$i -ge 0;$i--) {$value[$i]}
$value='0x'+($value -join "").trimstart('0')
}
'hex' {
$type="REG_BINARY"
$value=$value -join ""
$binary=$true
}
}
}
}
if ($delete -eq $false) {
switch ($binary)
{
$false {$line='Set-ItemProperty -Path {0} -Name {1} -Type {2} -Value {3}'}
$true {$line='Reg Add {0} /v {1} /t {2} /d {3} /f';$key=$key.replace(":\","\")}
}
$commands+=$line -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 = $args[0]
reg2ps1 $path
Usage example: .\reg2ps1.ps1 "path\to\reg.reg"
Sample Input:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DPS]
"DelayedAutoStart"=dword:00000000
"Description"="@%systemroot%\\system32\\dps.dll,-501"
"DisplayName"="Diagnostic Policy Service"
"ErrorControl"=dword:00000001
"FailureActions"=hex:80,51,01,00,00,00,00,00,00,00,00,00,03,00,00,00,14,00,00,\
00,01,00,00,00,c0,d4,01,00,01,00,00,00,e0,93,04,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,53,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,4c,00,6f,00,63,00,61,00,6c,00,53,00,65,00,72,00,76,00,69,00,63,\
00,65,00,4e,00,6f,00,4e,00,65,00,74,00,77,00,6f,00,72,00,6b,00,20,00,2d,00,\
70,00,00,00
"ObjectName"="NT AUTHORITY\\LocalService"
"RequiredPrivileges"=hex(7):53,00,65,00,43,00,68,00,61,00,6e,00,67,00,65,00,4e,\
00,6f,00,74,00,69,00,66,00,79,00,50,00,72,00,69,00,76,00,69,00,6c,00,65,00,\
67,00,65,00,00,00,53,00,65,00,43,00,72,00,65,00,61,00,74,00,65,00,47,00,6c,\
00,6f,00,62,00,61,00,6c,00,50,00,72,00,69,00,76,00,69,00,6c,00,65,00,67,00,\
65,00,00,00,53,00,65,00,41,00,73,00,73,00,69,00,67,00,6e,00,50,00,72,00,69,\
00,6d,00,61,00,72,00,79,00,54,00,6f,00,6b,00,65,00,6e,00,50,00,72,00,69,00,\
76,00,69,00,6c,00,65,00,67,00,65,00,00,00,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:00000003
"Start"=dword:00000003
"Type"=dword:00000020
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DPS\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,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,\
64,00,70,00,73,00,2e,00,64,00,6c,00,6c,00,00,00
"ServiceDllUnloadOnStop"=dword:00000001
"ServiceMain"="ServiceMain"
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DPS\Security]
"Security"=hex:01,00,14,80,8c,00,00,00,98,00,00,00,14,00,00,00,30,00,00,00,02,\
00,1c,00,01,00,00,00,02,80,14,00,ff,01,0f,00,01,01,00,00,00,00,00,01,00,00,\
00,00,02,00,5c,00,04,00,00,00,00,00,14,00,ff,01,0f,00,01,01,00,00,00,00,00,\
05,12,00,00,00,00,00,18,00,ff,01,02,00,01,02,00,00,00,00,00,05,20,00,00,00,\
20,02,00,00,00,00,14,00,8d,01,02,00,01,01,00,00,00,00,00,05,04,00,00,00,00,\
00,14,00,8d,01,02,00,01,01,00,00,00,00,00,05,06,00,00,00,01,01,00,00,00,00,\
00,05,12,00,00,00,01,01,00,00,00,00,00,05,12,00,00,00
Sample Output:
New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\DPS" -ErrorAction SilentlyContinue | Out-Null
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\DPS" -Name "DelayedAutoStart" -Type Dword -Value 0x00000000
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\DPS" -Name "Description" -Type String -Value "@%systemroot%\\system32\\dps.dll,-501"
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\DPS" -Name "DisplayName" -Type String -Value "Diagnostic Policy Service"
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\DPS" -Name "ErrorControl" -Type Dword -Value 0x00000001
Reg Add "HKLM\SYSTEM\CurrentControlSet\Services\DPS" /v "FailureActions" /t REG_BINARY /d 805101000000000000000000030000001400000001000000c0d4010001000000e09304000000000000000000 /f
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\DPS" -Name "ImagePath" -Type ExpandString -Value "%SystemRoot%\System32\svchost.exe -k LocalServiceNoNetwork -p"
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\DPS" -Name "ObjectName" -Type String -Value "NT AUTHORITY\\LocalService"
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\DPS" -Name "RequiredPrivileges" -Type MultiString -Value SeChangeNotifyPrivilege,SeCreateGlobalPrivilege,SeAssignPrimaryTokenPrivilege,SeImpersonatePrivilege
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\DPS" -Name "ServiceSidType" -Type Dword -Value 0x00000003
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\DPS" -Name "Start" -Type Dword -Value 0x00000003
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\DPS" -Name "Type" -Type Dword -Value 0x00000020
New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\DPS\Parameters" -ErrorAction SilentlyContinue | Out-Null
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\DPS\Parameters" -Name "ServiceDll" -Type ExpandString -Value "%SystemRoot%\system32\dps.dll"
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\DPS\Parameters" -Name "ServiceDllUnloadOnStop" -Type Dword -Value 0x00000001
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\DPS\Parameters" -Name "ServiceMain" -Type String -Value "ServiceMain"
New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Services\DPS\Security" -ErrorAction SilentlyContinue | Out-Null
Reg Add "HKLM\SYSTEM\CurrentControlSet\Services\DPS\Security" /v "Security" /t REG_BINARY /d 010014808c00000098000000140000003000000002001c000100000002801400ff010f0001010000000000010000000002005c000400000000001400ff010f0001010000000000051200000000001800ff01020001020000000000052000000020020000000014008d010200010100000000000504000000000014008d010200010100000000000506000000010100000000000512000000010100000000000512000000 /f
Registry Editor View: