Public/Get-CitrixMachineCatalogReport.ps1

<#
.SYNOPSIS
Generates a detailed report on Citrix Machine Catalogs, including delivery group associations, machine configurations, and provisioning details.
 
.DESCRIPTION
The Get-CitrixMachineCatalogReport function queries Citrix Delivery Controllers for information about machine catalogs. It collects properties such as catalog type, delivery group mappings, master image name, snapshot applied, machine count, and more. The data can be returned in the console or exported to a CSV file.
 
.PARAMETER AdminAddress
The FQDN or hostname of the Citrix Delivery Controller to query for machine catalog data.
 
.PARAMETER ExportToExcel
When specified as $true, exports the collected catalog information to a CSV file in the `C:\Temp` directory.
 
.EXAMPLE
# View Citrix machine catalog report in the console
Get-CitrixMachineCatalogReport -AdminAddress "ddc001"
 
.EXAMPLE
# Export the Citrix machine catalog report to a CSV file
Get-CitrixMachineCatalogReport -AdminAddress "ddc001" -ExportToExcel $true
 
.NOTES
This function requires Citrix PowerShell snap-ins (e.g., Citrix.Broker.Admin.V2, Citrix.Host.Admin.V2). Make sure they are installed and accessible on the system where the script is run.
#>


function Get-CitrixMachineCatalogReport {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]$AdminAddress,

        [Parameter()]
        [bool]$ExportToExcel = $false
    )

    process {
        # List of required Citrix snap-ins
        $snapins = @(
            "Citrix.Broker.Admin.V2",
            "Citrix.Host.Admin.V2",
            "Citrix.MachineCreation.Admin.V2",
            "Citrix.ConfigurationLogging.Admin.V2",
            "Citrix.Broker.Admin.*"
        )

        foreach ($snapin in $snapins) {
            if (-not (Get-PSSnapin -Registered | Where-Object { $_.Name -like $snapin })) {
                continue
            }

            if (-not (Get-PSSnapin -Name $snapin -ErrorAction SilentlyContinue)) {
                try {
                    Add-PSSnapin -Name $snapin -ErrorAction Stop
                } catch {
                    Write-Verbose "Snap-in $snapin already added or partially registered."
                }
            }
        }

        $catalogs = Get-BrokerCatalog -AdminAddress $AdminAddress
        $results = @()

        foreach ($catalog in $catalogs) {
            Try {
                $desktops = Get-BrokerDesktop -AdminAddress $AdminAddress -CatalogName $catalog.Name -MaxRecordCount 10000
                $desktopGroupNames = ($desktops.DesktopGroupName | Select-Object -Unique) -join ', '

                $acct = Get-AcctIdentityPool -AdminAddress $AdminAddress -IdentityPoolName $catalog.Name -ErrorAction SilentlyContinue
                $prov = Get-ProvScheme -AdminAddress $AdminAddress -ProvisioningSchemeName $catalog.Name -ErrorAction SilentlyContinue |
                        Select-Object -First 1 MasterImageVM, MemoryMB, CpuCount

                $masterImagePath = $prov.MasterImageVM
                $snapshot = if ($masterImagePath) { ($masterImagePath -split '\\')[3].Split('.')[0] } else { "N/A" }
                $masterImageName = if ($snapshot -like "*TMP*") { $snapshot.Substring(0, $snapshot.IndexOf('TMP')) + "TMP" } else { $snapshot }

                $tags = if ($desktops.Tags) { ($desktops.Tags | Select-Object -Unique) -join ', ' } else { "N/A" }

                $appCount = "N/A"
                if ($catalog.Name -like "VDURCX*") {
                    $dg = Get-BrokerDesktopGroup -AdminAddress $AdminAddress -Name $catalog.Name -ErrorAction SilentlyContinue
                    if ($dg) {
                        $apps = Get-BrokerApplication -AdminAddress $AdminAddress -DesktopGroupUid $dg.Uid -Filter { Enabled -eq $true }
                        $appCount = $apps.Count
                    }
                }

                $results += [PSCustomObject]@{
                    MachineCatalog     = $catalog.Name
                    DeliveryGroup      = $desktopGroupNames
                    AllocationType     = $catalog.AllocationType
                    SessionSupport     = $catalog.SessionSupport
                    PersistUserChanges = $catalog.PersistUserChanges
                    Tags               = $tags
                    TotalMachines      = $catalog.UsedCount
                    AppsPublished      = $appCount
                    MasterImage        = $masterImageName
                    SnapshotApplied    = $snapshot
                    MemoryMB           = $prov.MemoryMB
                    CPUCount           = $prov.CpuCount
                    OU                 = $acct.OU
                    NamingScheme       = $acct.NamingScheme
                }
            } catch {
                Write-LogEntry -Message "Failed to process catalog '$($catalog.Name)': $_"
            }
        }

        if ($ExportToExcel) {
            $path = "C:\Temp\CitrixCatalogReport_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
            $results | Export-Csv -Path $path -NoTypeInformation -Encoding UTF8
            Write-LogEntry -Message "Data exported to: $path"
        } else {
            return $results
        }
    }
}