Public/Get-CopilotUsageDetail.ps1
function Get-CopilotUsageDetail { <# .SYNOPSIS Get the most recent activity data for enabled users of Microsoft 365 Copilot apps. .DESCRIPTION Get the most recent activity data for enabled users of Microsoft 365 Copilot app, output as a CSV or PowerShell object. .PARAMETER Period Specifies the time period for which to retrieve data. Accepted values: D7 (7 days), D30 (30 days), D90 (90 days), D180 (180 days), or ALL. .PARAMETER Format Specifies the format of the returned data. Accepted values: object or csv. .PARAMETER OutPath Specifies the file path where the CSV data should be saved. This parameter can only be used when Format is set to 'csv'. .EXAMPLE Get-CopilotUsageDetail -Period D30 -Format object Returns the Copilot usage details for the past 30 days in JSON format. .EXAMPLE Get-CopilotUsageDetail -Period D90 -Format csv -OutPath "C:\Reports\CopilotUsage.csv" Retrieves Copilot usage details for the past 90 days and saves them to the specified CSV file. .LINK https://learn.microsoft.com/en-us/graph/api/reportroot-getmicrosoft365copilotusageuserdetail .OUTPUTS PSCustomObject or csv file #> [CmdletBinding(DefaultParameterSetName = 'OBJECT')] [OutputType([PSCustomObject], [String])] param( [Parameter(Mandatory = $true, ParameterSetName = 'OBJECT')] [Parameter(Mandatory = $true, ParameterSetName = 'CSV')] [ValidateSet("D7", "D30", "D90", "D180", "ALL")] [string]$Period, [Parameter(Mandatory = $false, ParameterSetName = 'OBJECT')] [Parameter(Mandatory = $true, ParameterSetName = 'CSV')] [ValidateSet("object", "csv")] [string]$Format = "object", [Parameter(Mandatory = $true, ParameterSetName = 'CSV')] [ValidateScript({ # Check if the directory exists $directory = Split-Path -Path $_ -Parent if (-not (Test-Path -Path $directory -PathType Container)) { throw "Directory '$directory' does not exist." } # Check if file has .csv extension if (-not $_.EndsWith('.csv', [StringComparison]::OrdinalIgnoreCase)) { throw "The OutPath parameter must specify a file with a .csv extension." } return $true })] [string]$OutPath ) # Parameter set validation if ($Format -eq "csv" -and -not $PSBoundParameters.ContainsKey('OutPath')) { throw "When Format is set to 'csv', the OutPath parameter is required." } Write-Verbose "Attempting to get Copilot usage details for period: $Period in $Format format" try { if ($Format -eq "object") { $usageDetails = Invoke-MgGraphRequest -Uri "beta/reports/getMicrosoft365CopilotUsageUserDetail(period='$Period')?`$format=application/json" -OutputType PSObject | Select -Expand Value return $usageDetails } elseif ($Format -eq "csv") { Try { $usageDetails = Invoke-MgGraphRequest -Uri "beta/reports/getMicrosoft365CopilotUsageUserDetail(period='$Period')?`$format=text/csv" -OutputFilePath $OutPath Write-Progress -Completed Write-Host "Copilot usage details saved to: $OutPath" -foregroundcolor yellow } Catch { if ($_.Exception.Message -match "403" -or $_.Exception.Message -match "Forbidden") { Write-Error "Access Forbidden: The Graph API permission Reports.Read.All is required. Make sure you have the appropriate administrator role and permissions. Error: $($_.Exception.Message)" } else { Write-Error "Failed to retrieve Copilot usage detail report $($_.Exception.Message)" } return $null } } return $usageDetails } catch { if ($_.Exception.Message -match "403" -or $_.Exception.Message -match "Forbidden") { Write-Error "Access Forbidden: The Graph API permission Reports.Read.All is required. Make sure you have the appropriate administrator role and permissions. Error: $($_.Exception.Message)" } else { Write-Error "Failed to retrieve Copilot usage detail report $($_.Exception.Message)" } return $null } } |