#region Function Import-RegFile
Function Import-RegFile {
<#
.SYNOPSIS
Reads a .REG file and exports to a PsObject with the following properties: Key, Name, Value, Type
NEW: Applies the .REG file to the Registry
.DESCRIPTION
Reads a .REG file and exports to a PsObject with the following properties: Key, Name, Value, Type
Handles huge .REG files that aren't easily rewritable in your deployment script.
Generates a PS object collection of properties that can used by PSADT's Set-RegistryKey
.PARAMETER Path
Path of the .REG file to import
.PARAMETER ApplyRegFile
Applies the .REG file to the Registry
.EXAMPLE
Returns hash table only. (Does not import anything)
Import-RegFile -Path "C:\registry.reg"
.EXAMPLE
Import masive REG file *And* feeds it to Set-RegistryKey
$RegFileObject = Import-RegFile -Path "C:\Users\Username\Desktop\registry.reg"
ForEach ($RegFileRow in $RegFileObject) {
Set-RegistryKey -Key $RegFileRow.Key -Name $RegFileRow.Name -Type $RegFileRow.Type -Value $RegFileRow.Value
}
.EXAMPLE
Returns hash table *AND* imports at the same time (beta quality)
Import-RegFile -Path "C:\registry.reg" -ApplyRegFile $true
.NOTES
Authors:
rivardma ( 9 may 2019 )
-Modified to be more robust and PSADT-fied Script 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
Denis St-Pierre 21 Nov 2019 (Ottawa, Canada)
-Improved Error handling and logging
-Fixed handling of default @ values
-added support for NONE type
-Added comments section/header
Denis St-Pierre 25 Mar 2020 (Ottawa, Canada)
-Added -ApplyRegFile parameter
Limitations:
-Only tested on Windows 10.
-Cannot handle REG key deletion and REG value deletion via REG file. e.g [-hklm\remove\key]
-Cannot be used as a splat directly. Must treat as an array of HashTables and parse each line as per example.
#>
[CmdLetBinding()]
Param(
[Parameter(Mandatory=$true)]
[string]$Path,
[Parameter(Mandatory=$false)]
[Bool]$ApplyRegFile=$False
)
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
If (-not (Test-path -LiteralPath $Path)) {
Write-Log -Message "REG file [$Path] does not exist" -Source ${CmdletName} -Severity 3
Throw "REG file [$Path] does not exist"
}
}
Process {
Try {
$fi = Get-Item $Path
$file = $fi.OpenText()
Write-Log -Message "REG file successfully loaded: [$Path]" -Source ${CmdletName}
While (-not ($file.EndOfStream)){
Remove-Variable hash -ErrorAction SilentlyContinue #Needed to make error messages accurate
$line = $file.ReadLine()
If ($line.Length -gt 0) {
If ($line -match '^\[(.*)\]$' ) {
If ($emptyFolder) {
#$hash = @{Key=$key;Name="(Default)";Value=$null;Type="String"}
If (-not $ApplyRegFile) {
#Value cannot be $null when calling Set-Registry value, but seems ok when only building array
$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 #Set-RegistryKey cannot handle Value=$null
Write-Log -Message "Value is null, not including in output" -Source ${CmdletName}
}
$key = $matches[1]
$emptyFolder = $true
}
If ($line -match '=') {
$emptyFolder = $false
while (($line.Trim().Substring($line.Trim().Length -1,1) -eq "\") -or ($line.Trim().Split("=",2)[1].Substring(0,1) -eq """" -and $line.Trim().Substring($line.Trim().Length -1,1) -ne """")){
If ($line.Trim().Substring($line.Trim().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(0)"){
$type = "None"
$value=[byte[]]($b[1].Split(',') | ForEach-Object { "0x$_"})
} 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" #CAVEAT: this will make Set-RegistryKey throw an error
}
}
$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
}
}
If ($ApplyRegFile) {
ForEach ($RegFileRow in $hash) {
Write-log $("Applying [Key=$($hash.key);Name=$($hash.name);Value=$($hash.value);Type=$($hash.type)]") -Source ${CmdletName} -Severity 2
Set-RegistryKey -Key $RegFileRow.Key -Name $RegFileRow.Name -Type $RegFileRow.Type -Value $RegFileRow.Value
}
}
}
}
catch {
Write-Log -Message "Failed to parse the REG file [$Path]. `n$(Resolve-Error)" -Severity 3 -Source ${CmdletName}
Write-Log -Message "`$line=[$line] `$type=[$type]" -Source ${CmdletName}
}
}
End {
Write-FunctionHeaderOrFooter -CmdletName ${CmdletName} -Footer
}
}
#endregion Function Import-RegFile
2 Likes
Your function worked great for me! I ran into a single error, which was that I had to reduce the Severity level as Powershell didn’t recognize a severity of 5. I reduced it to 2 and all went well
Error:
[Installation] :: Failed to parse the REG file [C:\IEModeScript\SupportFiles\HKLM_EdgeIEModePolicy.reg].
Error Record:
-------------At C:\IEModeScript\AppDeployToolkit\AppDeployToolkitMain.ps1:1082 char:119
+ … .name);Value=$($hash.value);Type=$($hash.type)]") -Severity 5 -Source …
+ ~
Error Inner Exception(s):
Sorry about the -Severity 5
thing.
My modified write-log
is modified to add Grey(4) and Green(5) colors.
I’ll update the code to match yours.
Thank you!
2 Likes