Export registry information using PowerShell

At the end of another busy week, and after passing the AZ-801 exam two days ago, it’s time for a small blog post 🙂 I had to export a registry from a client on which regedit tools were blocked. Exporting with PowerShell is an option, but the default format isn’t great. In this blog post, I will show you how to export it in a more user-friendly format.

How the script works

After you start the PowerShell function, you can export a specific part of your registry by running Export-Registry and specifying the starting path with the -Path parameter. You can save the results with the -OutFile parameter by specifying a .csv or .xlsx filename; the results include the key, property, value, and value type (String, DWORD, etc.).

Example

In the example below, I specified HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall as the path and d:\temp\results.xlsx as the output file:

Export-Registry -Path 'HKLM:Software\microsoft\Windows\CurrentVersion\Uninstall' -Outfile d:\temp\results.csv

The output looks like this:

The script

The script is listed below; copy/paste it to c:\scripts\Export-Registry.ps1, for example, and run it in your session by using “. c:\scripts\Export-Registry.ps1”

function Export-Registry {
    param (
        [parameter(Mandatory = $true, HelpMessage = "Enter the path to start from, for example HKLM:SOFTWARE\Microsoft\Policies")][string]$Path,
        [parameter(Mandatory = $true)][string]$Outfile
    )
    
    #Test if $Path is accessible
    if (Test-Path $path -PathType Container -ErrorAction stop) {
        Write-Host ("Path {0} is valid, continuing..." -f $Path) -ForegroundColor Green
    }
    else {
        Write-Warning ("Could not access path {0}, check syntax and permissions. Exiting..." -f $path)
        return
    }

    #Check file extension, if it's not .csv or .xlsx exit
    if (-not ($Outfile.ToLower().EndsWith('.csv') -or $Outfile.ToLower().EndsWith('.xlsx'))) {
        Write-Warning ("The specified {0} output file should use the .csv or .xlsx extension, exiting..." -f $Outfile)
        return
    }


    #Set $keys variable
    Write-Host ("Retrieving keys from {0}" -f $Path) -ForegroundColor Green
    $keys = @(
        Get-Item -Path $Path -ErrorAction Stop
        Get-ChildItem -Path $Path -Recurse -ErrorAction SilentlyContinue
    )

    $total = foreach ($key in $keys) {
        foreach ($property in $key) {
            Write-Host ("Processing {0}" -f $property) -ForegroundColor Green
            foreach ($name in $key.Property) {
                try {   
                    [PSCustomObject]@{
                        Name     = $property.Name
                        Property = "$($name)"
                        Value    = Get-ItemPropertyValue -Path $key.PSPath -Name $name
                        Type     = $key.GetValueKind($name)
                    }
                }
                catch {
                    Write-Warning ("Error processing {0} in {1}" -f $property, $key.name)
                }
            }
        }
    }
    
    #Export results to either CSV of XLSX, install ImportExcel module if needed
    if ($Outfile.ToLower().EndsWith('.csv')) {
        try {
            New-Item -Path $Outfile -ItemType File -Force:$true -Confirm:$false -ErrorAction Stop | Out-Null
            $total | Sort-Object Name, Property | Export-Csv -Path $Outfile -Encoding UTF8 -Delimiter ';' -NoTypeInformation
            Write-Host ("`nExported results to {0}" -f $Outfile) -ForegroundColor Green
        }
        catch {
            Write-Warning ("`nCould not export results to {0}, check path and permissions" -f $Outfile)
            return
        }
    }
    
    if ($Outfile.ToLower().EndsWith('.xlsx')) {
        try {
            #Test path and remove empty file afterwards because xlsx is corrupted if not
            New-Item -Path $Outfile -ItemType File -Force:$true -Confirm:$false -ErrorAction Stop | Out-Null
            Remove-Item -Path $Outfile -Force:$true -Confirm:$false | Out-Null
            
            #Install ImportExcel module if needed
            Write-Host ("Checking if ImportExcel PowerShell module is installed...") -ForegroundColor Green
            if (-not (Get-Module -Name ImportExcel -ListAvailable)) {
                try {
                    Write-Warning ("`nImportExcel PowerShell Module was not found, installing...")
                    Install-Module ImportExcel -Scope CurrentUser -Force:$true -ErrorAction Stop
                    Import-Module ImportExcel -ErrorAction Stop
                }
                catch {
                    Write-Warning ("Error installing the ImportExcel module, exiting...")
                    return
                }
            }

            #Export results to path
            $total | Sort-Object name, Property | Export-Excel -AutoSize -BoldTopRow -FreezeTopRow -AutoFilter -Path $Outfile -ErrorAction Stop
            Write-Host ("`nExported results to {0}" -f $Outfile) -ForegroundColor Green
        }
        catch {
            Write-Warning ("`nCould not export results to {0}, check path and permissions" -f $Outfile)
            return
        }
    }
}

Download the script(s) from GitHub here

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.