Public/Set-PdqCustomVariable.ps1

<#
.SYNOPSIS
Creates or updates a Custom Variable in Deploy or Inventory.
 
.INPUTS
None.
 
.OUTPUTS
None.
 
.EXAMPLE
Set-PdqCustomVariable -Product 'Deploy' -Name 'UniverseAnswer' -Value 42
Creates or updates @(UniverseAnswer) in Deploy and sets its value to 42.
#>

function Set-PdqCustomVariable {

    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        # The name of the Variable you would like to create or update.
        [String]$Name,

        # The data you would like to store in the Variable.
        [String]$Value,

        [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
    )

    # The PDQ CLI EXEs must be run as an admin.
    $AdminState = $true
    try {

        $AdminState = [Security.Principal.WindowsPrincipal]::new([Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)

    } catch {

        throw 'Unable to determine elevation level. Please restart PowerShell as an administrator.'

    }

    if ( $AdminState -eq $false ) {

        throw 'This function must be run as an administrator.'

    }



    switch (Test-PdqVariableName -Name $Name) {
        'Bare' {
            $CustomName = Convert-PdqVariableType -Name $Name -Type 'Custom'
        }
        'Custom' {
            $CustomName = $Name
            # Strip the formatting characters out of the name.
            # The database doesn't store the names with the formatting characters.
            $Name = Convert-PdqVariableType -Name $Name -Type 'Bare'
        }
        'System' {
            throw 'This function cannot create System Variables.'
        }
    }

    $TimeStamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'

    $VariableExists = Get-PdqVariable -Name $CustomName -Product $Product -DatabasePath $DatabasePath -ErrorAction 'SilentlyContinue'
    if ( $VariableExists ) {

        $ExeName = "PDQ$Product.exe"
    
        try {

            $ExeOutput = & $ExeName UpdateCustomVariable -Name $Name -Value $Value 2>&1
            Write-Verbose $ExeOutput

        } catch [System.Management.Automation.CommandNotFoundException] {

            throw "Unable to find $ExeName. Please make sure PDQ $Product is installed."

        }
        
        # https://gitlab.com/ColbyBouma/pdqstuff/-/issues/87
        if ( $ExeOutput.GetType().FullName -eq 'System.Management.Automation.ErrorRecord' ) {

            throw $ExeOutput.Exception.Message

        }

        [PSCustomObject]@{
            'Product'         = $Product
            'Name'            = $Name
            'OldValue'        = $VariableExists.Value
            'NewValue'        = $Value
        }

    } else {

        $Query = "INSERT INTO CustomVariables (Name, Value, Created, Modified) VALUES ('$Name', '$Value', '$TimeStamp', '$TimeStamp');"
        Write-Verbose "Creating: $Name"

        $null = Invoke-PdqSqlQuery -Product $Product -DatabasePath $DatabasePath -Query $Query -QueryType 'Update'
    
        [PSCustomObject]@{
            'Product'         = $Product
            'Name'            = $Name
            'OldValue'        = $null
            'NewValue'        = $Value
        }

        Write-Warning "You must refresh the PDQ $Product console to see the new variable."

    }

}