Public/Get-PdqVariable.ps1

<#
.SYNOPSIS
Retrieves data for Variables from the database of Deploy or Inventory.
 
.INPUTS
None.
 
.OUTPUTS
System.Management.Automation.PSCustomObject
System.Object[]
 
.EXAMPLE
Get-PdqVariable -Product 'Deploy'
Outputs all Variables from Deploy.
 
.EXAMPLE
Get-PdqVariable -Product 'Deploy' -Name '$(Repository)'
Retrieves the System Variable named Repository.
 
.EXAMPLE
Get-PdqVariable -Product 'Inventory' -Name '@(DaveSSN)'
Retrieves the Custom Variable named DaveSSN.
 
.EXAMPLE
Get-PdqVariable -Product 'Inventory' -Name 'DaveSSN'
Retrieves the Variable named DaveSSN by searching both Custom and System Variables.
#>

function Get-PdqVariable {

    [CmdletBinding()]
    param (
        # The names of the Variables you would like to retrieve.
        # Make sure to use single quotes with System Variables, otherwise PowerShell will throw an error!
        # '$(Date)'
        [String[]]$Name,

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

        # The path to the currently active database will be retrieved by default.
        # You can use this parameter if you wish to run this function against a different database.
        [String]$DatabasePath
    )

    # Build a hashtable of data about the Variable names.
    $ConvertedNames = @{}
    foreach ( $DesiredName in $Name ) {

        $NameData = @{
            'FullName' = $DesiredName
            'Type'     = Test-PdqVariableName -Name $DesiredName
            'Count'    = 0
        }

        # Strip the formatting characters out of the name.
        # The database doesn't store the names with the formatting characters.
        if ( $NameData.Type -eq 'Bare' ) {

            $VariableName = $DesiredName

        } else {

            $VariableName = Convert-PdqVariableType -Name $DesiredName -Type 'Bare'
            
        }

        $ConvertedNames.Add($VariableName, $NameData)

    }

    # Retrieve all Variable data from the database.
    foreach ( $Prefix in 'Custom', 'System' ) {

        $Table = $Prefix + 'Variables'
        Write-Verbose "Querying the $Table table."
        $Query = "SELECT * FROM $Table ORDER BY Name COLLATE NOCASE;"
        Invoke-PdqSqlQuery -Product $Product -DatabasePath $DatabasePath -Query $Query -Stream | ForEach-Object {
    
            $VariableData = [PSCustomObject]@{
                'Name'     = $_.Name
                'FullName' = Convert-PdqVariableType -Name $_.Name -Type $Prefix
                'Value'    = $_.Value
                'Type'     = $Prefix
                'Created'  = [DateTime]$_.Created
                'Modified' = [DateTime]$_.Modified
                'Id'       = [Int32]$_."$($Prefix)VariableId"
            }

            if ( -not $Name ) {
            
                $VariableData

            } elseif ( $ConvertedNames.ContainsKey($VariableData.Name) ) {

                if ( $ConvertedNames[$VariableData.Name].Type -in 'Bare', $Prefix ) {

                    # Mark this entry as found.
                    $ConvertedNames[$VariableData.Name].Count ++

                    $VariableData

                } 

            }
    
        }

    }

    # Make sure each entry in $Name was found exactly once.
    foreach ( $ConvertedName in $ConvertedNames.GetEnumerator() ) {

        $ConvertedNameData = $ConvertedName.Value

        switch ($ConvertedNameData.Count) {
            0 {
                throw "'$($ConvertedNameData.FullName)' does not exist in this database."
            }
            2 {
                Write-Warning "'$($ConvertedNameData.FullName)' exists as both a Custom and System variable. Please use @() or `$() to specify which one you want."
            }
        }

    }

}