Public/Invoke-IntuneBackupClientAppSP.ps1

function Invoke-IntuneBackupClientAppSP {
    <#
    .SYNOPSIS
    Backup Intune Client Apps
     
    .DESCRIPTION
    Backup Intune Client Apps as JSON files per Device Compliance Policy to the specified Path.
     
    .PARAMETER Path
    Path to store backup files
     
    .EXAMPLE
    Invoke-IntuneBackupClientApp -Path "C:\temp"
    #>

    
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [string]$Path,

        [Parameter(Mandatory = $false)]
        [ValidateSet("v1.0", "Beta")]
        [string]$ApiVersion = "Beta"
    )

     # Ensure the Microsoft Graph module is installed and imported
     if (-not (Get-Module -Name Microsoft.Graph -ListAvailable)) {
        Install-Module -Name Microsoft.Graph -Scope CurrentUser -Force
    }
    Import-Module Microsoft.Graph.DeviceManagement

    # Connect to Microsoft Graph if not already connected
    if (-not (Get-MgUser -UserId me -ErrorAction SilentlyContinue)) {
        Connect-MgGraph -Scopes "DeviceManagementApps.Read.All","DeviceManagementApps.ReadWrite.All","DeviceManagementConfiguration.Read.All","DeviceManagementConfiguration.ReadWrite.All","DeviceManagementServiceConfig.Read.All","DeviceManagementServiceConfig.ReadWrite.All"
        
    }

    # Create folder if not exists
    if (-not (Test-Path "$Path\Client Apps")) {
        $null = New-Item -Path "$Path\Client Apps" -ItemType Directory
    }

    # Function to get all pages of results
    function Get-AllPages {
        param (
            [Parameter(Mandatory = $true)]
            [string]$Uri
        )

        $results = @()
        $response = Invoke-MgGraphRequest -Method GET -Uri $Uri
        $results += $response.value

        while ($null -ne $response.'@odata.nextLink') {
            $response = Invoke-MgGraphRequest -Method GET -Uri $response.'@odata.nextLink'
            $results += $response.value
        }

        return $results
    }
    # Get all Client Apps
    $uri = "$ApiVersion"+'/deviceAppManagement/mobileApps?$filter=(microsoft.graph.managedApp/appAvailability%20eq%20null%20or%20microsoft.graph.managedApp/appAvailability%20eq%20%27lineOfBusiness%27%20or%20isAssigned%20eq%20true)'
    $clientApps =@()
    $clientApps = Get-AllPages -Uri $uri

    foreach ($clientApp in $clientApps) {
        $clientAppType = $clientApp.'@odata.type'.split('.')[-1]

        $fileName = ($clientApp.displayName).Split([IO.Path]::GetInvalidFileNameChars()) -join '_'
        $clientAppDetails = Invoke-MGGraphRequest -Method GET -Uri "$ApiVersion/deviceAppManagement/mobileApps/$($clientApp.id)"
        $clientAppDetails | ConvertTo-Json | Out-File -LiteralPath "$path\Client Apps\$($clientAppType)_$($fileName).json"

        [PSCustomObject]@{
            "Action" = "Backup"
            "Type"   = "Client App"
            "Name"   = $clientApp.displayName
            "Path"   = "Client Apps\$($clientAppType)_$($fileName).json"
        }
    }
}