Function to import .reg file

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
	}
}
3 Likes