Public/Get-CitrixPowerBIReport.ps1

<#
.SYNOPSIS
Generates a comprehensive monthly Power BI-ready Citrix report with infrastructure, application, session, license, and usage metrics.
 
.DESCRIPTION
This function automates the process of collecting Citrix Virtual Apps and Desktops usage data, licensing details, infrastructure inventory, and VDI information.
It retrieves and exports this data from multiple sources including Citrix Delivery Controllers, Active Directory domains, SharePoint, and Excel workbooks.
The report is consolidated and exported to CSV and JSON formats, and optionally updated in an Excel table and uploaded to SharePoint.
 
.PARAMETER MonthsBack
Specifies how many months back the report should be generated for. For example, use 1 to generate the report for last month, 2 for the month before that, and so on.
Valid range: 1 to 12.
 
.PARAMETER ExportFolder
Specifies the root folder path on the local system where all generated CSV and JSON reports will be saved before being uploaded to SharePoint.
 
.EXAMPLE
Get-CitrixPowerBIReport -MonthsBack 1 -ExportFolder "C:\Reports\Citrix" -Inifilepath "C:\temp\config.ini"
 
This example runs the function to generate and export the previous month’s report to the folder "C:\Reports\Citrix".
All artifacts such as server list, sessions, licensing, and application usage will be saved there and published to SharePoint.
#>



function Get-CitrixPowerBIReport {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [ValidateRange(1, 12)]
        [int]$MonthsBack,

        [Parameter(Mandatory = $true)]
        [string]$ExportFolder,

        [Parameter(Mandatory = $true)]
        [string]$Inifilepath
    )

    try {
        $targetDate = (Get-Date).AddMonths(-$MonthsBack)
        $Exportto = New-CitrixExportFolders -RootPath $ExportFolder
        Clear-CitrixExportFolders -RootExportFolder $ExportFolder
        
        # Folder paths
        $ServerList        = Join-Path $ExportFolder "ServerList\ServerList.csv"
        $CitrixResourceList= Join-Path $ExportFolder "CitrixResourceList\ListOfCitrixResources.csv"
        $CitrixDetails     = Join-Path $ExportFolder "CitrixDetails\CitrixDetails.csv"
        $Hypervisors       = Join-Path $ExportFolder "Hypervisors\Hypervisor.csv"
        $VDIListexport     = Join-Path $ExportFolder "VDIList\VDIList.csv"
        $licexport         = Join-Path $ExportFolder -ChildPath Licensing
        $CitrixSessions    = Join-Path $ExportFolder ("CitrixSessions\CitrixSessions_{0}.csv" -f $targetDate.ToString('yyyy_MM'))
        $jsonfolder        = Join-Path -Path $ExportFolder -ChildPath Json

        # Dates
        $startDateRaw       = Get-Date -Year $targetDate.Year -Month $targetDate.Month -Day 1 -Hour 0 -Minute 0 -Second 0
        $endDateRaw         = $startDateRaw.AddMonths(1).AddSeconds(-1)
        $formattedStartDate = $startDateRaw.ToString("yyyy-MM-dd")
        $formattedEndDate   = $endDateRaw.ToString("yyyy-MM-dd")

        # INI values
        $prodControllers    = Get-INISectionValues -IniPath $Inifilepath -Section "prod" -Key "DeliveryControllers"
        $drControllers      = Get-INISectionValues -IniPath $Inifilepath -Section "dr" -Key "DeliveryControllers"
        $sitepath           = Get-INISectionValues -IniPath $Inifilepath -Section "Site"
        $xlpath             = Get-INISectionValues -IniPath $Inifilepath -Section "Excel"
        $dnpath             = Get-INISectionValues -IniPath $Inifilepath -Section "path"
        $accountpath        = Get-INISectionValues -IniPath $Inifilepath -Section "Account"
        $domainDetails      = Get-INISectionValues -IniPath $Inifilepath -Section "Domains"

        $DNValue            = $dnpath["DN"]
        $Worksheet          = $xlpath["Worksheet"]
        $TableName          = $xlpath["TableName"]
        $Excelpath          = $dnpath["ExcelPath"]
        $SiteValue          = $sitepath["Sharepointsite"]
        $SPFileUrlPath      = $sitepath["SharepointFileUrlPath"]
        $spfilename         = $sitepath["SharepointFileName"]
        $username           = $accountpath["username"]
        $secret             = $accountpath["secret"]
        $licfolder          = $dnpath["LicenseFolder"]

        $sharePointPathForPnP = $SPFileUrlPath -replace '/', '\'
        $fullSharePointPath   = Join-Path -Path $sharePointPathForPnP -ChildPath $spfilename
        $localpath            = Join-Path -Path $Excelpath -ChildPath $spfilename

        # Servers
        $prodServer          = Get-RandomPingableServer -ServerList $prodControllers
        $drServer            = Get-RandomPingableServer -ServerList $drControllers
        $deliveryControllers = @($prodServer, $drServer)

        # Step 1: Infra inventory
        $InfraInventory = Get-InfraXA7Inventory -Type "Infra" -DN $DNValue -AdminAddress $prodServer -InfraType Static |
                          Where-Object { $_.OSType -notlike "*File*" }
        $InfraInventory | Export-Csv -Path $ServerList -NoTypeInformation -Append -Force

        $HypervisorList = @()

        foreach ($dc in $deliveryControllers) {
            Get-InfraXA7Inventory -Type "XA7" -InfraType "Dynamic" -AdminAddress $dc |
                Export-Csv -Path $ServerList -NoTypeInformation -Append -Force

            Get-CitrixXA7Applications -AdminAddress $dc |
                Export-Csv -Path $CitrixResourceList -NoTypeInformation -Append -Force

            Get-CitrixMachineCatalogReport -AdminAddress $dc |
                Export-Csv -Path $CitrixDetails -NoTypeInformation -Append -Force

            $HypervisorList += Get-CitrixHypervisorStatus -DeliveryController $dc
            $HypervisorList | Export-Csv -Path $Hypervisors -NoTypeInformation -Append -Force

            Get-CitrixAppUsagePeak -DeliveryController $dc -StartDate $formattedStartDate -EndDate $formattedEndDate |
                Export-Csv -Path $CitrixSessions -NoTypeInformation -Append -Force

            Export-CitrixUsageMetrics -DeliveryControllers $dc -StartDate $formattedStartDate -EndDate $formattedEndDate -ExportFolder $jsonfolder
        }

        # Step 8: Get Excel from SharePoint
        #Get-SharePointExcelDocument -SiteUrl $SiteValue -SharePointFileServerRelativeUrl $fullSharePointPath -LocalDownloadPath $Excelpath -Username $username -Passcode $secret

        # Step 9: Additional data collection
        $VDIList = Get-CitrixVDIDesktopGroups -ComputerName $prodServer
        $XA7Apps = Get-CitrixXA7Applications -AdminAddress $prodServer
        $ProdXA7 = Get-InfraXA7Inventory -Type "XA7" -InfraType "Dynamic" -AdminAddress $prodServer
        $XA7HypCount = ($HypervisorList | Where-Object { $_.Name -like "*XenApp*" }).Count
        $VDIHypCount = ($HypervisorList | Where-Object { $_.Name -like "*VDI*" }).Count
        $VDIList| Export-Csv -Path $VDIListexport -NoTypeInformation -Append -Force

        # Step 10: RDS License
        $totalRDSLicenses = 0
        foreach ($domain in $domainDetails.Keys) {
            $dn = $domainDetails[$domain]
            $domainLower = $domain.ToLower()
            $result = Get-ADRemoteDesktopLicenseReport -SearchBase $dn -DomainName $domainLower -ExportToCSV $true
            $totalRDSLicenses += $result.Count
        }

        # Step 11: License Excel
        $CtxLicenseData = Get-CitrixLicenseExcelData -ReportPath $licfolder -MonthsBack $MonthsBack

        # Step 12: Update Excel table
        $logData = @{
            Month                        = ([datetime]::Today).AddMonths(-1).AddDays(-(([datetime]::Today).Day - 1))
            "License_Available"          = $CtxLicenseData.LicensesAvailable
            "License_inuse"              = $CtxLicenseData.LicensesInUse
            "%utilised"                  = $CtxLicenseData.PercentageUsed
            "Total_Licenses"             = $CtxLicenseData.TotalLicenses
            "Total_Infra_Servers"        = $InfraInventory.Count
            "Total_Citrix_Applications"  = $XA7Apps.Count
            "Total_VDI_Published"        = $VDIList.Count
            "Total_XenApp7_Servers"      = $ProdXA7.Count
            "RDS_Licensing"              = $totalRDSLicenses
            "Nutanix_VDI_Clusters"       = $VDIHypCount
            "Nutanix_XA7_Clusters"       = $XA7HypCount
        }

        Update-ExcelTableDataOptimized -ExcelPath $localpath -WorksheetName $Worksheet -ValuesToUpdate $logData -TableName $TableName

        # Copy the file
        Copy-Item -Path $localpath -Destination $licexport -Force
        
        Write-Host "📁 File copied to: $licexport"

        # Step 13: Upload back to SharePoint
        #Send-ExcelToSharePointSecure -SiteUrl $SiteValue -SharePointFileServerRelativeUrl $fullSharePointPath -LocalExcelFilePath $localpath -Username $username -Passcode $secret

        #Step14: Upload the folders to sharepoint
        #Publish-FolderToSharePoint `
        # -LocalFolderPath $ExportFolder `
        # -SharePointSiteUrl $SiteValue `
        # -SharePointFolderRelativeUrl $SPFileUrlPath `
        # -Username $username `
        # -Passcode $secret

        Write-LogEntry -Message "The Monthly Report for $targetDate is Generated Successfully"
    }
    catch {
        Write-Error "❌ Failed to calculate date ranges or export data: $_"
    }
}