Functions/Export-BsgPbiReport.ps1

<#
    .SYNOPSIS
        Save Power BI report to a directory.
         
    .DESCRIPTION
        The PBIX file of a report is saved to a directory.
 
    .PARAMETER Source_WorkspaceId
        The id of the workspace you would like to save the report.
        You can find it in the Power BI workspace URL.
 
    .PARAMETER Source_ReportId
        The id of the report you would like to save.
        You can find it in the Power BI report URL.
 
    .PARAMETER Path_Workspace
        The path to the folder, where the reports should be saved.
        Subfolder "reports" will be created automatically.
 
    .PARAMETER MetadataOnly
        Backup only Metadata excluding actual Dataset files (PBIX Files).
 
    .EXAMPLE
        # Export report
        Export-BsgPbiReport -Source_WorkspaceId 15ebfcd7-1aa9-4c3d-8963-46c3812a559a -Source_ReportId 4837389a-a104-4701-8039-1bb4645644d7 -Path_Workspace "C:\temp\BSG PBI Administration\Backup\Workspaces\BSGroup DA - Test Workspace"
         
    .INPUTS
 
    .OUTPUTS
        Returns $true if the report was exported and $false if it was skiped or an error occured.
    .NOTES
        This script uses the Power BI Management module for Windows PowerShell.
        If this module isn't installed, install it by using the command 'Install-Module -Name MicrosoftPowerBIMgmt -Scope CurrentUser'.
#>


function Export-BsgPbiReport{
    param(
        [Parameter(Mandatory=$true)][string]$Source_WorkspaceId, 
        [Parameter(Mandatory=$true)][guid]$Source_ReportId,
        [Parameter(Mandatory=$true)][string]$Path_Workspace,
        [Parameter(Mandatory=$false)][switch]$MetadataOnly = $false
    )
    
    try{

        # Info-Message
        Write-Host
        Write-PSFHostColor -Level Host -DefaultColor white -String "== Exporting Report..."

        # Prepare final path
        $Path_Reports = Join-Path -Path $Path_Workspace -ChildPath "Reports"


        # ===
        # Get report
        # =

        try{

            if ($Source_WorkspaceId -eq "me") { 
                $Source_Report = Get-PowerBIReport -Id $Source_ReportId
            } else { 
                $Source_Report = Get-PowerBIReport -Id $Source_ReportId -WorkspaceId $Source_WorkspaceId 
            }

        } catch{
            throw "Error after calling CMDLET Get-PowerBIReport with -Id `"$Source_ReportId`" and -WorkspaceId `"$Source_WorkspaceId`"."
        }


        # ===
        # Check if report exists
        # =

        if (!$Source_Report.id){
            throw "No report found with report id `"$Source_ReportId`" and workspace id `"$Source_WorkspaceId`"."
        }

        # Info-Message
        $Source_ReportName = $Source_Report.name
        Write-PSFHostColor -Level Host -DefaultColor gray -String " Name: <c='white'>$Source_ReportName</c>"

        # Skip report usage metrics reports
        if ($Source_ReportName -eq "Report Usage Metrics Report"){
            Write-PSFHostColor -Level Host -DefaultColor gray -String " Usage Metrics Report cannot be exported."
            Write-PSFHostColor -Level Host -DefaultColor green -String " Report skipped (expected behaviour)."
            return $false
        }

        # Create temporary directories
        if((Test-Path $Path_Reports) -eq $false){
            $FileCreatedResponse = New-Item -Path $Path_Reports -ItemType Directory -ErrorAction SilentlyContinue
            # Write-PSFMessage -Level Verbose -Message "Temp directory created: `"$Path_Reports`""
        }

        # Create filename
        $Filename = $Source_ReportName + "_" + $Source_ReportId + ".pbix"
        $Path_Report = Join-Path -Path $Path_Reports -ChildPath $Filename

        # ===
        # Save to JSON file
        # =

        if ($Source_Report){
            
            # Create filename
            $Filename_ReportMetadata = "Reports.json"
            $Path_ReportMetadata = Join-Path -Path $Path_Reports -ChildPath $Filename_ReportMetadata

            # Create object array
            if ((Test-Path $Path_ReportMetadata) -eq $true){
                # existing file
                $ReportMetadata = @()
                $ReportMetadata += Get-Content -Path $Path_ReportMetadata | ConvertFrom-Json
                if (($ReportMetadata.id -contains $Source_ReportId) -eq $false){
                    $ReportMetadata += $Source_Report
                } else{
                    # should not happen (if old backup was deleted)
                }
            } else{
                # new file
                $ReportMetadata = @()
                $ReportMetadata += $Source_Report
            }

            # Save file
            $ReportMetadata | ConvertTo-Json | Out-File $Path_ReportMetadata
            # Write-PSFMessage -Level Verbose -Message " Location: `"$Path_ReportMetadata`""

        } else{
            Write-Host
            Write-Warning "No data received from API-call."
            Write-Host
            Write-PSFHostColor -Level Host -DefaultColor yellow -String " Report skipped."
            return $false
        }


        # ===
        # Export pbix file
        # =
        if (!$MetadataOnly.IsPresent) {
            try {
    
                # Remove report if already exported
                if (Test-Path $Path_Report){
                    Remove-Item -Path $Path_Report -Force
                }

                # Export report
                if ($Source_WorkspaceId -eq "me") {
                    Export-PowerBIReport -Id $Source_ReportId -OutFile $Path_Report -ErrorAction Stop
                }
                else {
                    Export-PowerBIReport -Id $Source_ReportId -WorkspaceId $Source_WorkspaceId -OutFile $Path_Report -ErrorAction Stop
                }

            }
            catch {

                $Response = Resolve-PowerBIError -Last
                if ($Response.Response.Substring(0, 15) -eq "NOT FOUND (404)"){
                    Write-Host
                    Write-Warning "Report not found."
                    Write-Host
                    Write-PSFHostColor -Level Host -DefaultColor gray -String " <c='white'>Info</c>: Please make sure you are able to download the report manually via PBI Service portal."
                    Write-PSFHostColor -Level Host -DefaultColor yellow -String " Report skipped."
                    return $false
                } else {
                    throw "Error after calling Export-PowerBIReport with -Id `"$Source_ReportId`" and -WorkspaceId `"$Source_WorkspaceId`". Check whether the report exists and you have permissions to export the report. `n$_"
                }
            }
        }
    
        Write-PSFHostColor -Level Host -DefaultColor green -String ' Report exported.'
        # Write-PSFMessage -Level Verbose -Message " Location: $Path_Report"
        return $true

    }catch{
        if ($Source_ReportName){
            Write-Host
            Stop-PSFFunction -Message "Could not export Report `"$Source_ReportName`"." -EnableException $False -Errorrecord $_
            return $false
        } else{
            Write-Host
            Stop-PSFFunction -Message "Could not export Report." -EnableException $False -Errorrecord $_
            return $false
        }
    }
}