Public/Get-PdqDatabasePath.ps1

<#
.SYNOPSIS
Retrieves the path to the database of the specified product and tests it.
 
.DESCRIPTION
This function looks for a path in these locations in this order:
    1) -DatabasePath
    2) HKLM:\SOFTWARE\Admin Arsenal\PDQ $Product\Settings\Database\FileName
    3) $env:ProgramData\Admin Arsenal\PDQ $Product\Database.db
The first location that doesn't return null will be used.
No further locations are examined after this.
The discovered path is tested. If it is not accessible, this function will return an error.
 
.INPUTS
None.
 
.OUTPUTS
System.String
 
.EXAMPLE
Get-PdqDatabasePath -Product 'Deploy'
Retrieves the PDQ Deploy database path.
 
.EXAMPLE
Get-PdqDatabasePath -DatabasePath 'D:\My Fancy Database.db'
Test a manually specified database path.
#>

function Get-PdqDatabasePath {

    [CmdletBinding()]
    param (
        [Parameter(ParameterSetName = 'Product', Mandatory = $true)]
        [ValidateSet('Deploy', 'Inventory')]
        # The PDQ application you would like to execute this function against.
        [String]$Product,

        [Parameter(ParameterSetName = 'DatabasePath', Mandatory = $true)]
        [Parameter(ParameterSetName = 'Product')]
        [AllowEmptyString()]
        # You would most likely use this parameter for targeting an inactive database (such as a copy).
        [String]$DatabasePath
    )

    if ( -not $DatabasePath ) {
    
        Try {

            # If the database has been moved to a non-default location, use that path.
            # https://help.pdq.com/hc/en-us/community/posts/211685647/comments/216106567
            $RegPath = "HKLM:\SOFTWARE\Admin Arsenal\PDQ $Product\Settings\Database"
            $DatabasePath = Get-ItemPropertyValue -Path $RegPath -Name 'FileName' -ErrorAction 'Stop'

        } Catch {

            $DatabasePath = "$env:ProgramData\Admin Arsenal\PDQ $Product\Database.db"

        }

    }

    Write-Verbose "Database path: $DatabasePath"

    if ( -not (Test-Path $DatabasePath) ) {
    
        throw "Unable to access: $DatabasePath"
    
    }

    # This block cannot use Open-PdqSqlConnection or Invoke-PdqSqlQuery because it would create a recursion loop.
    try {

        Open-SQLiteConnection -DataSource $DatabasePath -ConnectionName 'DatabasePath'

        $ProductCodeQuery = 'SELECT ProductCode FROM DatabaseInfo;'
        $ProductCode = Invoke-SqlScalar -Query $ProductCodeQuery -ConnectionName 'DatabasePath'
        $ExpectedProductCode = "PDQ$Product"
        if ( $ProductCode -ne $ExpectedProductCode ) {

            throw "Incorrect database detected. Expected ProductCode: $ExpectedProductCode, found: $ProductCode"

        }

    } finally {

        Close-SqlConnection -ConnectionName 'DatabasePath'

    }

    $DatabasePath

}