Venafi / VenafiPS

Powershell module to fully automate your Venafi TLS Protect Datacenter and Cloud platforms!
https://venafips.readthedocs.io/
Apache License 2.0
18 stars 7 forks source link

Customer Fields Throw Errors using Get-TppAttribute on Device Objects #217

Closed jmeldrum76 closed 1 year ago

jmeldrum76 commented 1 year ago

Environment

Operating System: Windows 11
VenafiPS version: 5.7
PowerShell version: 5.1
TPP version (if applicable): 23.1

Steps to reproduce

Its pretty easy:

  1. Create a "list" custom field that applies to certificates
  2. Run "Get-TppAttribute -Path $devicepath -VenafiSession $session -All"

image

Expected behavior

I should not get an Exception.

Actual behavior

I am getting an exception on this custom field that is not even present on the device object:

Here is the custom Field configuration: image image

No Custom Field Present: image

Full Script

############### Source Server #######################
# Set your TPP server URL, credentials, client ID, and scope 
$TppServerUrl = "https://tpp.example.com"
$Username = "User"
$Password = "password"
$ClientId = "VenafiStandardIntegrations"
$PrivateKeyPassword = 'Passw0rd123#' | ConvertTo-SecureString -AsPlainText -Force
$CertificateFolderPath = "\VED\Policy\Demo\APIs\Test Export"
$ExportDestinationPath = "C:\Users\jeremy.meldrum\Downloads\Downloads\Scripts\Jeremy Meldrum\TPP\OAuth Scripts\Download all certificates from a specific folder\Certs"
$LogFilePath = "C:\Users\jeremy.meldrum\Downloads\Downloads\Scripts\Jeremy Meldrum\TPP\OAuth Scripts\Import Certs from a folder\file.txt"

$OAuthScope = @{
    Certificate = 'manage,discover,delete'
    Configuration = 'manage'
}

# Start transcript
Start-Transcript -Path $LogFilePath -Append -NoClobber

# Function to authenticate and obtain a session
function Get-VenafiSession {
    param (
        [string]$TppServerUrl,
        [string]$Username,
        [string]$Password,
        [string]$ClientId,
        [hashtable]$OAuthScope
    )

    $PSVersion = $PSVersionTable.PSVersion

    if ($PSVersion.Major -lt 5 -or ($PSVersion.Major -eq 5 -and $PSVersion.Minor -lt 1)) {
        "You need PowerShell 5.1 or above to run this script. Your version is $($PSVersion.Major).$($PSVersion.Minor)." | Write-Host
        exit
    }

    "Checking to see if the VenafiPS module is installed..." | Write-Host
    if (Get-InstalledModule -Name "VenafiPS") {
        "VenafiPS Module already installed..continuing..." | Write-Host
    }
    else {
        throw "In order to continue, please run the following command to install the VenafiPS module from the PSGallery: install-module VenafiPS -Force"
    }

    "Converting the credentials....." | Write-Host
    $pass = ConvertTo-SecureString $Password -AsPlainText -Force
    $cred = New-Object System.Management.Automation.PSCredential ($Username, $pass)

    "Creating Session....." | Write-Host
    try {
        $session = New-VenafiSession -Server $TppServerUrl -Credential $cred -ClientId $ClientId -Scope $OAuthScope -PassThru
        return $session
    }
    catch {
        throw "Connection Error: $_"
    }
}
# Function to get certificates using the session# 

function Get-VenafiCertificates {
    param (
        [object]$Session,
        [string]$CertificateFolderPath
    )

    # Initialize counters
    $countWithPrivateKey = 0
    $countWithoutPrivateKey = 0
    $countInError = 0

    "Fetching certificates from $CertificateFolderPath....." | Write-Host -ForegroundColor Yellow
    try {
        # fetch certificates from a specific folder
        $CertDataPath = Find-VenafiCertificate -Path $CertificateFolderPath -VenafiSession $Session 

        foreach ($CertData in $CertDataPath)
        {
            "################## Processing Certificate: $($CertData.Name) ##################" | Write-Host -ForegroundColor Green
            if ($CertData.ProcessingDetails.InError -eq "True")
            {
                "Certificate is in error and was not exported: $($CertData.Name)" | Write-Host -ForegroundColor Red
                $countInError++
            }
            else {
                try {
                    $CertDownloaded = $CertData | Export-VenafiCertificate -Format 'Base64' -OutPath $ExportDestinationPath -VenafiSession $session -PrivateKeyPassword $PrivateKeyPassword 
                    "Downloaded certificate with private key: $($CertData.name)" | Write-Host
                    $countWithPrivateKey++

                    # Get and print detailed certificate information
                    $certificateDetails = Get-VenafiCertificate -CertificateId $CertData.Guid -VenafiSession $session
                    $certificateDetails | Format-List | Out-String | Write-Host

                    # Check the existence and get the details of the consumers
                    $ConsumerCounter = 1
                    foreach ($consumer in $certificateDetails.Consumers) {
                        try {
                            "Consumer (Application) Details #$($ConsumerCounter): " | Write-Host -ForegroundColor yellow
                            $consumerDetails = Get-TppObject -Path $consumer -VenafiSession $session                            
                            $consumerDetails | Format-List | Out-String | Write-Host

                            # Fetch and print consumer attributes
                            "Consumer (Application) Attributes #$($ConsumerCounter): " | Write-Host -ForegroundColor yellow
                            $consumerAttributes = Get-TppAttribute -Path $consumer -VenafiSession $session -All                            
                            $consumerAttributes | Format-List | Out-String | Write-Host

                            # Fetch and print ParentPath attributes
                            "ParentPath (Device) Attributes #$($ConsumerCounter): " | Write-Host -ForegroundColor yellow
                            $parentPathAttributes = Get-TppAttribute -Path $consumerDetails.ParentPath -VenafiSession $session -All
                            $parentPathAttributes | Format-List | Out-String | Write-Host
                            $ConsumerCounter++
                        }
                        catch {
                            "Error in fetching consumer details: $_" | Write-Host -ForegroundColor Yellow
                        }
                    }
                }
                catch {
                    "Error in exporting certificate with private key: $_" | Write-Host -ForegroundColor Yellow
                    $CertDownloaded = $CertData | Export-VenafiCertificate -Format 'Base64' -OutPath $ExportDestinationPath -VenafiSession $session 
                    "Downloaded certificate without private key: $($CertData.name)" | Write-Host
                    $countWithoutPrivateKey++

                    # Get and print detailed certificate information
                    $certificateDetails = Get-VenafiCertificate -CertificateId $CertData.Guid -VenafiSession $session
                    $certificateDetails | Format-List | Out-String | Write-Host

                    # Check the existence and get the details of the consumers
                    $ConsumerCounter = 1
                    foreach ($consumer in $certificateDetails.Consumers) {
                        try {
                            "Consumer (Application) Details #$($ConsumerCounter): " | Write-Host -ForegroundColor yellow
                            $consumerDetails = Get-TppObject -Path $consumer -VenafiSession $session                            
                            $consumerDetails | Format-List | Out-String | Write-Host

                            # Fetch and print consumer attributes
                            "Consumer (Application) Attributes #$($ConsumerCounter): " | Write-Host -ForegroundColor yellow
                            $consumerAttributes = Get-TppAttribute -Path $consumer -VenafiSession $session -All                             
                            $consumerAttributes | Format-List | Out-String | Write-Host

                            # Fetch and print ParentPath attributes
                            "ParentPath (Device) Attributes #$($ConsumerCounter): " | Write-Host -ForegroundColor yellow
                            $parentPathAttributes = Get-TppAttribute -Path $consumerDetails.ParentPath -VenafiSession $session -All #-Verbose
                            $parentPathAttributes | Format-List | Out-String | Write-Host
                            $ConsumerCounter++
                        }
                        catch {
                            "Error in fetching consumer details: $_" | Write-Host -ForegroundColor Yellow
                        }
                    }
                }
            }            
        }           
    }
    catch {
        throw "Error in fetching certificates: $_"
    }

    # Print final count of certificates
    "Final count of certificates with private key: $countWithPrivateKey" | Write-Host -ForegroundColor Green
    "Final count of certificates without private key: $countWithoutPrivateKey" | Write-Host -ForegroundColor Green
    "Final count of certificates in error: $countInError" | Write-Host -ForegroundColor Red
}
# Create session and fetch certificates
$session = Get-VenafiSession -TppServerUrl $TppServerUrl -Username $Username -Password $Password -ClientId $ClientId -OAuthScope $OAuthScope
Get-VenafiCertificates -Session $session -CertificateFolderPath $CertificateFolderPath

# Stop transcript
Stop-Transcript
gdbarron commented 1 year ago

Thanks for the detailed writeup @jmeldrum76. This is due to the custom field lookup for attributes not differentiating between certs and devices.

'Environment' is an attribute of 'Ssh Device Base' which 'Device' inherits. When listing all attributes of a device, it will come up to Environment and find a matching custom field and assume that's it which is incorrect. You can rename the custom field and it will work, but I'll look to enhance Get-TppAttribute to lookup custom fields by the classes they pertain to as well as name.

jmeldrum76 commented 1 year ago

I am not so sure that is the case. In the screenshot below, you can see my my custom field guid that applies only to certificates. somehow my screenshot is not in the original bug:

image

image

gdbarron commented 1 year ago

@jmeldrum76 you can also use the -NoLookup parameter which will bypass custom field lookups.

jmeldrum76 commented 1 year ago

That does not solve the problem.

image

jmeldrum76 commented 1 year ago

The -NoLookup parameter works for now.