If you are like me and sometimes have huge .reg files that aren’t easily rewritable in your deployment script, here is my function the read the file and generate ab object collection of properties that can then be directly used by Set-RegistryKey
Import-RegFile{
<#
.SYNOPSIS
Read the .reg file and exports the keys to a PsObject with the following properties: Key, Name, Value, Type
.DESCRIPTION
Read the .reg file and exports the keys to a PsObject with the following properties: Key, Name, Value, Type
.PARAMETER Path
Path of the .reg file to import
.EXAMPLE
Import-RegFile -File "C:\registry.reg"
.NOTES
Script idea taken from: https://social.technet.microsoft.com/Forums/scriptcenter/en-US/a623f698-4364-40bf-84a1-1fbae3852c1d/powershell-how-to-parse-a-registry-text-file?forum=ITCG
Modified to be more robust
#>
[CmdLetBinding()]
Param(
[Parameter(Mandatory=$true)]
[string]$Path
)
Begin {
## Get the name of this function and write header
[string]${CmdletName} = $PSCmdlet.MyInvocation.MyCommand.Name
Write-FunctionHeaderOrFooter -CmdletName ${CmdletName} -CmdletBoundParameters $PSBoundParameters -Header
#Set the special character used in .reg file to define end of string
$endOfString = [char]0x0000
}
Process {
Try{
$fi = Get-Item $Path
$file=$fi.OpenText()
Write-Log -Message "File succesfully loaded: $Path" -Source ${CmdletName}
While(!($file.EndOfStream)){
$line=$file.ReadLine()
if($line.Length -gt 0){
if($line -match '^\[(.*)\]$' ){
if($emptyFolder){
$hash=@{Key=$key;Name="(Default)";Value=$null;Type="String"}
Write-Log -Message "Empty registry key found: Key=$key" -Source ${CmdletName}
New-Object PSObject -Property $hash
}
$key=$matches[1]
$emptyFolder = $true
}
if($line -match '='){
$emptyFolder = $false
while(($line.Trim().Substring($line.Length -1,1) -eq "\") -or ($line.Split("=",2)[1].Substring(0,1) -eq """" -and $line.Trim().Substring($line.Length -1,1) -ne """")){
if($line.Trim().Substring($line.Length -1,1) -eq "\"){
#Not finished hex value
$line = $line.Replace("\","").Trim() + $file.ReadLine().Trim()
}else{
#String not finished, return carriage causes a new line in the file
$line = $line.Trim() + "`r`n" + $file.ReadLine().Trim()
}
}
$a=$line.Split("=",2)
$name=$a[0].Replace('"','')
if($name -eq "@"){$name = "(Default)"}
if($a[1].Substring(0,1) -eq """"){
$value=$a[1].Substring(1,$a[1].Length-2).Replace("\\","\").Replace("\""","""")
$type='String'
}else{
$b=$a[1].Split(':',2)
if($b[0] -eq "dword"){
$type = "Dword"
$value = [convert]::toint32($b[1],16)
}elseif($b[0] -eq "hex"){
$type = "Binary"
$value=[byte[]]($b[1].Split(',') | ForEach-Object { "0x$_"})
}elseif($b[0] -eq "hex(b)"){
$type = "QWord"
$value = [BitConverter]::ToInt64([byte[]]($b[1].Split(',') | ForEach-Object { "0x$_"}),0)
}elseif($b[0] -eq "hex(2)"){
$type = "ExpandString"
$value = [System.Text.Encoding]::Unicode.GetString([byte[]]($b[1].Split(',') | ForEach-Object { "0x$_"})).Trim($endOfString)
}elseif($b[0] -eq "hex(7)"){
$type = "MultiString"
$value = [System.Text.Encoding]::Unicode.GetString([byte[]]($b[1].Split(',') | ForEach-Object { "0x$_"})).Trim($endOfString).Split($endOfString)
}else{
$type = "Unknown"
}
}
$hash=@{Key=$key;Name=$name;Value=$value;Type=$type}
Write-Log -Message "Registry key found with the following properties: Key=$key, Name=$name, Value=$value, Type=$type" -Source ${CmdletName}
New-Object PSObject -Property $hash
}
}
}
}
catch{
Write-Log -Message "Failed to parse the reg file ($Path). `n$(Resolve-Error)" -Severity 3 -Source ${CmdletName}
}
}
End {
Write-FunctionHeaderOrFooter -CmdletName ${CmdletName} -Footer
}
}