Surprisingly there doesn’t seem to be any obvious way to import “reg” files into Group Policy Preferences. And using the Registry Import Wizard can be tedious ticking many many tick boxes.
Looking around existing tools I could find one commercial tool but nothing freely available, so put together a PowerShell script to convert a .REG file to a .XML file that can be dragged and dropped into a Group Policy Preference.
This script supports the following registry types:
- REG_DWORD
- REG_QWORD
- REG_EXPAND_SZ
- REG_MULTI_SZ
- REG_BINARY
- REG_SZ
Note: Your reg file should contain data from one hive only (i.e. HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE) as the Group Policy preference XML doesn’t allow two hive types.
Usage:
Convert-Reg2Xml -regPath input.reg -xmlPath output.xml
Then drag and drop XML file into the registry section of Group Policy preference editor.
(Tested on Windows Server 2012 R2 only, but expect it to work on other servers/clients)
Note: There is pretty much no error checking currently in script. It is assumed reg file is exported from reg edit. If you manually created reg file with slight differences from reg edit export this tool may not process reg file correctly.
Script can be downloaded here: https://onedrive.live.com/redir?resid=93A8E9D387076121!1388&authkey=!AJFuJBPvhP5vAyk&ithint=file%2c.zip
function Convert-RegEscapeCodes { Param( [Parameter(Position=1)][string]$regstring) return $regstring.Replace("\\","\").Replace('\"','"') } function Convert-Reg2Xml { Param( [Parameter(Mandatory=$True)][string]$regPath, [Parameter(Mandatory=$True)][string]$xmlPath ) $clsidCollection = "{53B533F5-224C-47e3-B01B-CA3B3F3FF4BF}" $clsidRegistry = "{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" $settings = New-Object System.Xml.XmlWriterSettings $settings.Indent=$True $settings.Encoding = [System.Text.Encoding]::UTF8 $xml = [System.Xml.XmlWriter]::Create($xmlPath,$settings) $descr = "Imported Reg File" $action = "U" $unicoder = New-Object System.Text.UnicodeEncoding $lastHive=""; $lastKey=""; $sr=New-Object System.IO.StreamReader($regPath) $lastHive="" $lastKey="" $collectionCount=0 while (!$sr.EndOfStream) { $line = $sr.ReadLine() if ($line.StartsWith("[")) { $currentHive=$line.Substring(1,$line.IndexOf("\")-1) $currentKey=$line.Substring($line.IndexOf("\")+1,$line.Length-$line.IndexOf("\")-2) if ($lastHive -eq "") { $xml.WriteStartElement("Collection") $xml.WriteAttributeString("clsid",$clsidCollection) $xml.WriteAttributeString("name",$currentHive) $collectionCount++ ForEach ($key in $currentKey.Split('\')) { $xml.WriteStartElement("Collection") $xml.WriteAttributeString("clsid",$clsidCollection) $xml.WriteAttributeString("name",$key) $collectionCount++ } } else { # hives don't match - settings.xml doesn't support this! if ($currentHive -ne $lastHive) { # invalid - settings.xml only supports one HIVE type per file Throw "Reg file format is not supported by settings .XML. Please use only $currentHive or $lastHive per XML file" return } else { # going up a key if ($currentKey.StartsWith($lastKey + "\")) { $newKey=$currentKey.Substring($lastKey.Length+1) ForEach ($key in $newKey.Split('\')) { $xml.WriteStartElement("Collection") $xml.WriteAttributeString("clsid",$clsidCollection) $xml.WriteAttributeString("name",$key) $collectionCount++ } } else { # funky logic to handle change in key path # maybe this logic even works :) $currentKeySplit=$currentKey.Split('\') $lastKeySplit=$lastKey.Split('\') $match=$true $i=-1 while ($match) { $i++ if ($i -ge $currentKeySplit.Length -or $i -ge $lastKeySplit.Length) { $match=$false } else { if ($currentKeySplit[$i] -ne $lastKeySplit[$i]) { $match=$false } } } for ($x=$lastKeySplit.Length;$x -gt $i;$x--) { $xml.WriteEndElement() $collectionCount-- } for ($x=$i;$x -lt $currentKeySplit.Length;$x++) { $xml.WriteStartElement("Collection") $xml.WriteAttributeString("clsid",$clsidCollection) $xml.WriteAttributeString("name",$currentKeySplit[$x]) $collectionCount++ } } } } $lastHive=$currentHive $lastKey=$currentKey } else { if ($line.Contains("=")) { $regType=[Microsoft.Win32.RegistryValueKind]::Unknown # detect registry type if ($line.StartsWith("@=") -or $line.Contains('"="')) { $regType=[Microsoft.Win32.RegistryValueKind]::String } if ($line.Contains("=hex:")) { $regType=[Microsoft.Win32.RegistryValueKind]::Binary } if ($line.Contains("=dword:")) { $regType=[Microsoft.Win32.RegistryValueKind]::DWord } if ($line.Contains("=hex(7):")) { $regType=[Microsoft.Win32.RegistryValueKind]::MultiString } if ($line.Contains("=hex(2):")) { $regType=[Microsoft.Win32.RegistryValueKind]::ExpandString } if ($line.Contains("=hex(b):")) { $regType=[Microsoft.Win32.RegistryValueKind]::QWord } switch ($regType) { # *** PROCESS REG_SZ ([Microsoft.Win32.RegistryValueKind]::String) { $default="0" if ($line.StartsWith("@=")) { $valueName="" $value=$line.Substring(3,$line.Length-4) "Name = '$valueName' Value = '$value'" $default="1" } else { $i = $line.IndexOf('"="') $valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1) $value=Convert-RegEscapeCodes $line.Substring($i+3,$line.Length-$i-4) "Name = '$valueName' Value = '$value'" } $xml.WriteStartElement("Registry") $xml.WriteAttributeString("clsid",$clsidRegistry) $xml.WriteAttributeString("name",$valueName) $xml.WriteAttributeString("descr",$descr) $xml.WriteAttributeString("image","7") $xml.WriteStartElement("Properties") $xml.WriteAttributeString("action",$action) $xml.WriteAttributeString("hive",$currentHive) $xml.WriteAttributeString("key",$currentKey) $xml.WriteattributeString("name",$valueName) $xml.WriteattributeString("default",$default) $xml.WriteattributeString("type","REG_SZ") $xml.WriteattributeString("displayDecimal","0") $xml.WriteAttributeString("value",$value) $xml.WriteEndElement() $xml.WriteEndElement() } # *** PROCESS REG_BINARY ([Microsoft.Win32.RegistryValueKind]::Binary) { # read binary key to end while ($line.EndsWith("\")) { $line=$line.Substring(0,$line.Length-1)+$sr.ReadLine().Trim() } $i = $line.IndexOf('"=hex:') $valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1) $value=$line.Substring($i+6).Replace(",","") "Name = '$valueName' Value = '$value'" # build XML $xml.WriteStartElement("Registry") $xml.WriteAttributeString("clsid",$clsidRegistry) $xml.WriteAttributeString("name",$valueName) $xml.WriteAttributeString("descr",$descr) $xml.WriteAttributeString("image","17") $xml.WriteStartElement("Properties") $xml.WriteAttributeString("action",$action) $xml.WriteAttributeString("hive",$currentHive) $xml.WriteAttributeString("key",$currentKey) $xml.WriteattributeString("name",$valueName) $xml.WriteattributeString("default","0") $xml.WriteattributeString("type","REG_BINARY") $xml.WriteattributeString("displayDecimal","0") $xml.WriteAttributeString("value",$value) $xml.WriteEndElement() $xml.WriteEndElement() } # *** PROCESS REG_DWORD ([Microsoft.Win32.RegistryValueKind]::DWord) { $i = $line.IndexOf('"=dword:') $valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1) $value=$line.Substring($i+8).ToUpper() "Name = '$valueName' Value = '$value'" # build XML $xml.WriteStartElement("Registry") $xml.WriteAttributeString("clsid",$clsidRegistry) $xml.WriteAttributeString("name",$valueName) $xml.WriteAttributeString("descr",$descr) $xml.WriteAttributeString("image","17") $xml.WriteStartElement("Properties") $xml.WriteAttributeString("action",$action) $xml.WriteAttributeString("hive",$currentHive) $xml.WriteAttributeString("key",$currentKey) $xml.WriteattributeString("name",$valueName) $xml.WriteattributeString("default","0") $xml.WriteattributeString("type","REG_DWORD") $xml.WriteattributeString("displayDecimal","0") $xml.WriteAttributeString("value",$value) $xml.WriteEndElement() $xml.WriteEndElement() } # *** PROCESS REG_QWORD ([Microsoft.Win32.RegistryValueKind]::QWord) { $i = $line.IndexOf('"=hex(b):') $valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1) $tempValue=$line.Substring($i+9).Replace(",","").ToUpper() $value="" # unreverse QWORD for settings.xml format for ($i = $tempValue.Length -2;$i -gt 0;$i-=2) { $value+=$tempValue.Substring($i,2) } "Name = '$valueName' Value = '$value'" # build XML $xml.WriteStartElement("Registry") $xml.WriteAttributeString("clsid",$clsidRegistry) $xml.WriteAttributeString("name",$valueName) $xml.WriteAttributeString("descr",$descr) $xml.WriteAttributeString("image","17") $xml.WriteStartElement("Properties") $xml.WriteAttributeString("action",$action) $xml.WriteAttributeString("hive",$currentHive) $xml.WriteAttributeString("key",$currentKey) $xml.WriteattributeString("name",$valueName) $xml.WriteattributeString("default","0") $xml.WriteattributeString("type","REG_QWORD") $xml.WriteattributeString("displayDecimal","0") $xml.WriteAttributeString("value",$value) $xml.WriteEndElement() $xml.WriteEndElement() } # *** PROESS REG_MULTI_MZ ([Microsoft.Win32.RegistryValueKind]::MultiString) { # read binary key to end while ($line.EndsWith("\")) { $line=$line.Substring(0,$line.Length-1)+$sr.ReadLine().Trim() } # read hex codes $i = $line.IndexOf('"=hex(7):') $valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1) $value=$line.Substring($i+9).Replace(",","") # convert hex codes to binary array $byteLength=$value.Length/2 $byte = New-Object Byte[] $byteLength $x=0 for ($i=0;$i -lt $value.Length;$i+=2) { $byte[$x]="0x" + $value.Substring($i,2) $x++ } # convert binary array to unicode string $value=$unicoder.GetString($byte) # retrieve multi values $values=$value.Replace("`0`0","").Split("`0") "Name = '$valueName'" # build XML $xml.WriteStartElement("Registry") $xml.WriteAttributeString("clsid",$clsidRegistry) $xml.WriteAttributeString("name",$valueName) $xml.WriteAttributeString("descr",$descr) $xml.WriteAttributeString("image","7") $xml.WriteStartElement("Properties") $xml.WriteAttributeString("action",$action) $xml.WriteAttributeString("hive",$currentHive) $xml.WriteAttributeString("key",$currentKey) $xml.WriteattributeString("name",$valueName) $xml.WriteattributeString("default","0") $xml.WriteattributeString("type","REG_MULTI_SZ") $xml.WriteattributeString("displayDecimal","0") $xml.WriteAttributeString("value",$value.Replace("`0"," ")) $x=1 $xml.WriteStartElement("Values") ForEach ($value in $values) { $xml.WriteStartElement("Value") $xml.WriteString($value) "Value $x = '$value'" $xml.WriteEndElement() } $xml.WriteEndElement() $xml.WriteEndElement() $xml.WriteEndElement() } ([Microsoft.Win32.RegistryValueKind]::ExpandString) { # read binary key to end while ($line.EndsWith("\")) { $line=$line.Substring(0,$line.Length-1)+$sr.ReadLine().Trim() } # read hex codes $i = $line.IndexOf('"=hex(2):') $valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1) $value=$line.Substring($i+9).Replace(",","") # convert hex codes to binary array $byteLength=$value.Length/2 $byte = New-Object Byte[] $byteLength $x=0 for ($i=0;$i -lt $value.Length;$i+=2) { $byte[$x]="0x" + $value.Substring($i,2) $x++ } # convert binary array to unicode string $value=$unicoder.GetString($byte).Replace("`0","") "Name = '$valueName' Value = '$value'" $xml.WriteStartElement("Registry") $xml.WriteAttributeString("clsid",$clsidRegistry) $xml.WriteAttributeString("name",$valueName) $xml.WriteAttributeString("descr",$descr) $xml.WriteAttributeString("image","7") $xml.WriteStartElement("Properties") $xml.WriteAttributeString("action",$action) $xml.WriteAttributeString("hive",$currentHive) $xml.WriteAttributeString("key",$currentKey) $xml.WriteattributeString("name",$valueName) $xml.WriteattributeString("default",$default) $xml.WriteattributeString("type","REG_EXPAND_SZ") $xml.WriteattributeString("displayDecimal","0") $xml.WriteAttributeString("value",$value) $xml.WriteEndElement() $xml.WriteEndElement() } } } } } $sr.Close() while ($collectionCount -gt 0) { $xml.WriteEndElement() $collectionCount-- } $xml.Close() } Convert-Reg2Xml -regPath "C:\support\ReceiverCSTRegUpx64.reg" -xmlPath C:\support\Citrix.xmlfunction Convert-RegEscapeCodes { Param( [Parameter(Position=1)][string]$regstring) return $regstring.Replace("\\","\").Replace('\"','"') } function Convert-Reg2Xml { Param( [Parameter(Mandatory=$True)][string]$regPath, [Parameter(Mandatory=$True)][string]$xmlPath ) $clsidCollection = "{53B533F5-224C-47e3-B01B-CA3B3F3FF4BF}" $clsidRegistry = "{9CD4B2F4-923D-47f5-A062-E897DD1DAD50}" $settings = New-Object System.Xml.XmlWriterSettings $settings.Indent=$True $settings.Encoding = [System.Text.Encoding]::UTF8 $xml = [System.Xml.XmlWriter]::Create($xmlPath,$settings) $descr = "Imported Reg File" $action = "U" $unicoder = New-Object System.Text.UnicodeEncoding $lastHive=""; $lastKey=""; $sr=New-Object System.IO.StreamReader($regPath) $lastHive="" $lastKey="" $collectionCount=0 while (!$sr.EndOfStream) { $line = $sr.ReadLine() if ($line.StartsWith("[")) { $currentHive=$line.Substring(1,$line.IndexOf("\")-1) $currentKey=$line.Substring($line.IndexOf("\")+1,$line.Length-$line.IndexOf("\")-2) if ($lastHive -eq "") { $xml.WriteStartElement("Collection") $xml.WriteAttributeString("clsid",$clsidCollection) $xml.WriteAttributeString("name",$currentHive) $collectionCount++ ForEach ($key in $currentKey.Split('\')) { $xml.WriteStartElement("Collection") $xml.WriteAttributeString("clsid",$clsidCollection) $xml.WriteAttributeString("name",$key) $collectionCount++ } } else { # hives don't match - settings.xml doesn't support this! if ($currentHive -ne $lastHive) { # invalid - settings.xml only supports one HIVE type per file Throw "Reg file format is not supported by settings .XML. Please use only $currentHive or $lastHive per XML file" return } else { # going up a key if ($currentKey.StartsWith($lastKey + "\")) { $newKey=$currentKey.Substring($lastKey.Length+1) ForEach ($key in $newKey.Split('\')) { $xml.WriteStartElement("Collection") $xml.WriteAttributeString("clsid",$clsidCollection) $xml.WriteAttributeString("name",$key) $collectionCount++ } } else { # funky logic to handle change in key path # maybe this logic even works :) $currentKeySplit=$currentKey.Split('\') $lastKeySplit=$lastKey.Split('\') $match=$true $i=-1 while ($match) { $i++ if ($i -ge $currentKeySplit.Length -or $i -ge $lastKeySplit.Length) { $match=$false } else { if ($currentKeySplit[$i] -ne $lastKeySplit[$i]) { $match=$false } } } for ($x=$lastKeySplit.Length;$x -gt $i;$x--) { $xml.WriteEndElement() $collectionCount-- } for ($x=$i;$x -lt $currentKeySplit.Length;$x++) { $xml.WriteStartElement("Collection") $xml.WriteAttributeString("clsid",$clsidCollection) $xml.WriteAttributeString("name",$currentKeySplit[$x]) $collectionCount++ } } } } $lastHive=$currentHive $lastKey=$currentKey } else { if ($line.Contains("=")) { $regType=[Microsoft.Win32.RegistryValueKind]::Unknown # detect registry type if ($line.StartsWith("@=") -or $line.Contains('"="')) { $regType=[Microsoft.Win32.RegistryValueKind]::String } if ($line.Contains("=hex:")) { $regType=[Microsoft.Win32.RegistryValueKind]::Binary } if ($line.Contains("=dword:")) { $regType=[Microsoft.Win32.RegistryValueKind]::DWord } if ($line.Contains("=hex(7):")) { $regType=[Microsoft.Win32.RegistryValueKind]::MultiString } if ($line.Contains("=hex(2):")) { $regType=[Microsoft.Win32.RegistryValueKind]::ExpandString } if ($line.Contains("=hex(b):")) { $regType=[Microsoft.Win32.RegistryValueKind]::QWord } switch ($regType) { # *** PROCESS REG_SZ ([Microsoft.Win32.RegistryValueKind]::String) { $default="0" if ($line.StartsWith("@=")) { $valueName="" $value=$line.Substring(3,$line.Length-4) "Name = '$valueName' Value = '$value'" $default="1" } else { $i = $line.IndexOf('"="') $valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1) $value=Convert-RegEscapeCodes $line.Substring($i+3,$line.Length-$i-4) "Name = '$valueName' Value = '$value'" } $xml.WriteStartElement("Registry") $xml.WriteAttributeString("clsid",$clsidRegistry) $xml.WriteAttributeString("name",$valueName) $xml.WriteAttributeString("descr",$descr) $xml.WriteAttributeString("image","7") $xml.WriteStartElement("Properties") $xml.WriteAttributeString("action",$action) $xml.WriteAttributeString("hive",$currentHive) $xml.WriteAttributeString("key",$currentKey) $xml.WriteattributeString("name",$valueName) $xml.WriteattributeString("default",$default) $xml.WriteattributeString("type","REG_SZ") $xml.WriteattributeString("displayDecimal","0") $xml.WriteAttributeString("value",$value) $xml.WriteEndElement() $xml.WriteEndElement() } # *** PROCESS REG_BINARY ([Microsoft.Win32.RegistryValueKind]::Binary) { # read binary key to end while ($line.EndsWith("\")) { $line=$line.Substring(0,$line.Length-1)+$sr.ReadLine().Trim() } $i = $line.IndexOf('"=hex:') $valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1) $value=$line.Substring($i+6).Replace(",","") "Name = '$valueName' Value = '$value'" # build XML $xml.WriteStartElement("Registry") $xml.WriteAttributeString("clsid",$clsidRegistry) $xml.WriteAttributeString("name",$valueName) $xml.WriteAttributeString("descr",$descr) $xml.WriteAttributeString("image","17") $xml.WriteStartElement("Properties") $xml.WriteAttributeString("action",$action) $xml.WriteAttributeString("hive",$currentHive) $xml.WriteAttributeString("key",$currentKey) $xml.WriteattributeString("name",$valueName) $xml.WriteattributeString("default","0") $xml.WriteattributeString("type","REG_BINARY") $xml.WriteattributeString("displayDecimal","0") $xml.WriteAttributeString("value",$value) $xml.WriteEndElement() $xml.WriteEndElement() } # *** PROCESS REG_DWORD ([Microsoft.Win32.RegistryValueKind]::DWord) { $i = $line.IndexOf('"=dword:') $valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1) $value=$line.Substring($i+8).ToUpper() "Name = '$valueName' Value = '$value'" # build XML $xml.WriteStartElement("Registry") $xml.WriteAttributeString("clsid",$clsidRegistry) $xml.WriteAttributeString("name",$valueName) $xml.WriteAttributeString("descr",$descr) $xml.WriteAttributeString("image","17") $xml.WriteStartElement("Properties") $xml.WriteAttributeString("action",$action) $xml.WriteAttributeString("hive",$currentHive) $xml.WriteAttributeString("key",$currentKey) $xml.WriteattributeString("name",$valueName) $xml.WriteattributeString("default","0") $xml.WriteattributeString("type","REG_DWORD") $xml.WriteattributeString("displayDecimal","0") $xml.WriteAttributeString("value",$value) $xml.WriteEndElement() $xml.WriteEndElement() } # *** PROCESS REG_QWORD ([Microsoft.Win32.RegistryValueKind]::QWord) { $i = $line.IndexOf('"=hex(b):') $valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1) $tempValue=$line.Substring($i+9).Replace(",","").ToUpper() $value="" # unreverse QWORD for settings.xml format for ($i = $tempValue.Length -2;$i -gt 0;$i-=2) { $value+=$tempValue.Substring($i,2) } "Name = '$valueName' Value = '$value'" # build XML $xml.WriteStartElement("Registry") $xml.WriteAttributeString("clsid",$clsidRegistry) $xml.WriteAttributeString("name",$valueName) $xml.WriteAttributeString("descr",$descr) $xml.WriteAttributeString("image","17") $xml.WriteStartElement("Properties") $xml.WriteAttributeString("action",$action) $xml.WriteAttributeString("hive",$currentHive) $xml.WriteAttributeString("key",$currentKey) $xml.WriteattributeString("name",$valueName) $xml.WriteattributeString("default","0") $xml.WriteattributeString("type","REG_QWORD") $xml.WriteattributeString("displayDecimal","0") $xml.WriteAttributeString("value",$value) $xml.WriteEndElement() $xml.WriteEndElement() } # *** PROESS REG_MULTI_MZ ([Microsoft.Win32.RegistryValueKind]::MultiString) { # read binary key to end while ($line.EndsWith("\")) { $line=$line.Substring(0,$line.Length-1)+$sr.ReadLine().Trim() } # read hex codes $i = $line.IndexOf('"=hex(7):') $valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1) $value=$line.Substring($i+9).Replace(",","") # convert hex codes to binary array $byteLength=$value.Length/2 $byte = New-Object Byte[] $byteLength $x=0 for ($i=0;$i -lt $value.Length;$i+=2) { $byte[$x]="0x" + $value.Substring($i,2) $x++ } # convert binary array to unicode string $value=$unicoder.GetString($byte) # retrieve multi values $values=$value.Replace("`0`0","").Split("`0") "Name = '$valueName'" # build XML $xml.WriteStartElement("Registry") $xml.WriteAttributeString("clsid",$clsidRegistry) $xml.WriteAttributeString("name",$valueName) $xml.WriteAttributeString("descr",$descr) $xml.WriteAttributeString("image","7") $xml.WriteStartElement("Properties") $xml.WriteAttributeString("action",$action) $xml.WriteAttributeString("hive",$currentHive) $xml.WriteAttributeString("key",$currentKey) $xml.WriteattributeString("name",$valueName) $xml.WriteattributeString("default","0") $xml.WriteattributeString("type","REG_MULTI_SZ") $xml.WriteattributeString("displayDecimal","0") $xml.WriteAttributeString("value",$value.Replace("`0"," ")) $x=1 $xml.WriteStartElement("Values") ForEach ($value in $values) { $xml.WriteStartElement("Value") $xml.WriteString($value) "Value $x = '$value'" $xml.WriteEndElement() } $xml.WriteEndElement() $xml.WriteEndElement() $xml.WriteEndElement() } ([Microsoft.Win32.RegistryValueKind]::ExpandString) { # read binary key to end while ($line.EndsWith("\")) { $line=$line.Substring(0,$line.Length-1)+$sr.ReadLine().Trim() } # read hex codes $i = $line.IndexOf('"=hex(2):') $valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1) $value=$line.Substring($i+9).Replace(",","") # convert hex codes to binary array $byteLength=$value.Length/2 $byte = New-Object Byte[] $byteLength $x=0 for ($i=0;$i -lt $value.Length;$i+=2) { $byte[$x]="0x" + $value.Substring($i,2) $x++ } # convert binary array to unicode string $value=$unicoder.GetString($byte).Replace("`0","") "Name = '$valueName' Value = '$value'" $xml.WriteStartElement("Registry") $xml.WriteAttributeString("clsid",$clsidRegistry) $xml.WriteAttributeString("name",$valueName) $xml.WriteAttributeString("descr",$descr) $xml.WriteAttributeString("image","7") $xml.WriteStartElement("Properties") $xml.WriteAttributeString("action",$action) $xml.WriteAttributeString("hive",$currentHive) $xml.WriteAttributeString("key",$currentKey) $xml.WriteattributeString("name",$valueName) $xml.WriteattributeString("default",$default) $xml.WriteattributeString("type","REG_EXPAND_SZ") $xml.WriteattributeString("displayDecimal","0") $xml.WriteAttributeString("value",$value) $xml.WriteEndElement() $xml.WriteEndElement() } } } } } $sr.Close() while ($collectionCount -gt 0) { $xml.WriteEndElement() $collectionCount-- } $xml.Close() } Convert-Reg2Xml -regPath "input.reg" -xmlPath output.xml
doesn’t seem to work for me… tried on several machines including 2012r2 and just get:
You cannot call a method on a null-valued expression.
At C:\temp\ODBC\RegToXML.ps1:41 char:9
+ if ($line.StartsWith(“[“))
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
it suggests $line is null, the input file hasn’t loaded. possibly. or some other reason.
the script has a hard coded path for source reg & output xml files (see line 415).
There is a line that accidentally got in there Convert-Reg2Xml -regPath “C:\support\ReceiverCSTRegUpx64.reg” -xmlPath C:\support\Citrix.xmlfunction that should be removed
For info : It looks like line 415 through to line 827 is a repeat of lines 0 – 414
This is a really helpful script for both learning from and for converting the registry file to XML I have but one question, more for my own sanity.
Where are you getting the clsid from for the Registry keys and Values?
regards
I got this from analyzing GP Preference files created through Microsoft tool. I did this on multiple machines/server OS, and the same GUID was used in each case.
Thank you
Thank you for taking time to write this script. Having issues running and don’t understand why I get the following error below? Also if line 415 is removed from script the script no longer works? Any help would be appreciated.
You cannot call a method on a null-valued expression.
At C:\Temp\RegtoXml\RegToXML.ps1:40 char:5
+ $line = $sr.ReadLine()
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
You cannot call a method on a null-valued expression.
At C:\Temp\RegtoXml\RegToXML.ps1:41 char:9
+ if ($line.StartsWith(“[“))
+ ~~~~~~~~~~~~~~~~~~~~~
This suggests $sr has not opened the file. ($sr is equal to $null so can’t call $sr.ReadLine) The same error on $line.StartsWith suggests $line is $null as nothing was read into the file.
Awesome little script
I did have to remove the last line (415) and for any noobs – Open the script with PowerShell ISE and run it once (press the play button) then use the syntax Convert-Reg2Xml regPath\input.reg xmlPath\output.xml
e.g.
Convert-Reg2Xml D:\CoolPowerShell\input.reg D:\CoolPowerShell\output.xml
where input.reg is your exported registry key that you want to convert.
Thanks again….
Hello! Thanks a lot for your idea to write that script, it’s realy despairing with the wizard.
The link with the scirpt is no longer online. I saved the script text in a ps1 file and executed (Convert-Reg2Xml.ps1 D:\CoolPowerShell\input.reg D:\CoolPowerShell\output.xml). now i have a lots and a lots of errors. Can someone explain how to use the script correct and which line in the script must be changed?
I found out that the reg tree with all keys is in the xml, but the entries has no value and no name
Thanks Chentiangemalc for the work on this – it is a real timesaver! The link above to the download is broken, so I posted it (slightly revised with parameter prompts) here: http://www.veitch.ca/wp-content/uploads/2015/08/Convert_Reg_To_XML.zip . If you use the version above as noted by Roadie_UK it is duplicated after line 415 so copy and paste into your favourite text editor or the Powershell IDE and delete everything after line 415. Also remove the arguments on line 415 or revise them with your own correct paths pointing to your input and output file names. Eg. Convert-Reg2Xml -regPath “C:\temp\Exported_Settings.reg” -xmlPath “C:\temp\Converted_RegSettings.xml”.
Perfect script.
Any suggests how to import XML into GPMC thru powershell?
good idea, might put that up next.
Thanks chentiangemale, and Muskiier – just what I needed.
Awesome Script! Any way of removing the Collections, so when you import into Group Policy it doesn’t import the collections as folders?
Nice script sir. FYI a problem I ran into with a registry entry for a encrypted password with a number of extended ascii characters in it. Looks I’ll have to stick with scripting using regedit instead of doing this using group policy.
.\RegToXML.ps1 C:\temp\bmrpwdr.reg c:\temp\output.xml
C:\temp\BMrpwdr.reg
Name = ‘ConnectStringPWD’ Value = ‘¡¸à²Ï›Áç!å¬ÕL’
Exception calling “WriteAttributeString” with “2” argument(s): “”, hexadecimal value 0x1D, is an invalid character.”
At C:\temp\RegToXML.ps1:192 char:21
+ $xml.WriteAttributeString(“value”,$value)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentException
Exception calling “WriteEndElement” with “0” argument(s): “The Writer is closed or in error state.”
At C:\temp\RegToXML.ps1:193 char:21
+ $xml.WriteEndElement()
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : InvalidOperationException
You need to use XmlConvert.EncodeName to change the value to an XML safe string
Thanks for this, very helpful. Note that the original Onedrive copy is gone, there is a zip download someone made, or just copy the 2 first functions (not the whole text!) from the textbox above into a file e.g. reg2xml.ps1. Then run powershell, “dot” the file (as in . .\reg2xml.ps1). Should give no errors. Then use Convert-Reg2XML function with the correct parameters. And note that with standard UAC you cannot drag and drop in the direction of GPMC (although you can drag *out* settings), but it works perfectly with copy (the XML file) and paste (into the preferences registry).
Excellent script, thanks very much. FYI, I’ve run into some instances where a {default} value is actually a REG_MULTI_SZ or a REG_EXPAND_SZ, so I had to modify your code to account for that:
# read binary key to end
while ($line.EndsWith(“\”))
{
$line=$line.Substring(0,$line.Length-1)+$sr.ReadLine().Trim()
}
# Account for whether the REG_MULTI_SZ is a Default value
$default=”0″
if ($line.StartsWith(“@=”))
{
$valueName=””
$i = 0
$default=”1″
}
else
{
$i = $line.IndexOf(‘”=hex(7):’)
$valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1)
}
——————————————————————————————
# Account for whether the REG_EXPAND_SZ is a default value
$default=”0″
if ($line.StartsWith(“@=”))
{
$valueName=””
$i = 0
$default=”1″
}
else
{
$i = $line.IndexOf(‘”=hex(2):’)
$valueName=Convert-RegEscapeCodes $line.Substring(1,$i-1)
}
This creates keys with “Update” as action? So if one wants “Create”, do I just replace U with C? $action = “U”
It’s a while since I looked at this but I think so, you can always create a group policy preference manually first for a single item in group policy management console and just check the output XML it generates, that is pretty much how I built the tool.
Thanks, $action = “C” it is:)