All scripts
Microsoft 365 417
Power BI Dataset Refresh Failure Report
Pulls refresh history for every dataset across your Power BI workspaces and flags the ones that failed or ran long, so you find out about a broken refresh before someone opens a stale report and asks why the numbers look wrong.
Get-PowerBIDatasetRefreshReport.ps1
<#
.SYNOPSIS
Reports on Power BI dataset refresh history across workspaces, flagging failures and long running refreshes.
.DESCRIPTION
Connects to the Power BI service and loops through every workspace the signed in account can see, or a specific
list you pass in, pulling the recent refresh history for each dataset. Datasets with a failed refresh in the
lookback window, or a refresh that ran past a duration threshold, are flagged separately in the output and in an
optional CSV export, so you can catch problems before someone opens a stale report and asks why the numbers
look wrong.
.PARAMETER WorkspaceName
One or more workspace names to check. If you leave this out, the script checks every workspace the signed in
account has access to.
.PARAMETER DaysBack
How many days of refresh history to pull per dataset. Defaults to 7.
.PARAMETER LongRunningMinutes
A refresh that takes longer than this many minutes is flagged as long running even if it succeeded. Defaults to 30.
.PARAMETER ExportPath
Optional path to a CSV file. When supplied, the full result set is exported there in addition to the console output.
.EXAMPLE
.\Get-PowerBIDatasetRefreshReport.ps1 -DaysBack 14 -ExportPath C:\Reports\PBIRefreshes.csv
Checks the last 14 days of refresh history across all reachable workspaces and writes the results to a CSV file.
.EXAMPLE
.\Get-PowerBIDatasetRefreshReport.ps1 -WorkspaceName "Finance", "Ops Reporting" -LongRunningMinutes 20
.AUTHOR
Shehryar Hassan
#>
[CmdletBinding()]
param(
[string[]]$WorkspaceName,
[int]$DaysBack = 7,
[int]$LongRunningMinutes = 30,
[string]$ExportPath
)
if (-not (Get-Module -ListAvailable -Name MicrosoftPowerBIMgmt)) {
Write-Error "The MicrosoftPowerBIMgmt module is not installed. Run: Install-Module MicrosoftPowerBIMgmt -Scope CurrentUser"
return
}
Import-Module MicrosoftPowerBIMgmt -ErrorAction Stop
try {
Get-PowerBIAccessToken -ErrorAction Stop | Out-Null
}
catch {
Write-Host "Connecting to the Power BI service, sign in when prompted."
Connect-PowerBIServiceAccount | Out-Null
}
if ($WorkspaceName) {
$workspaces = foreach ($name in $WorkspaceName) {
Get-PowerBIWorkspace -Name $name -Scope Organization
}
}
else {
$workspaces = Get-PowerBIWorkspace -Scope Organization -All | Where-Object { $_.Type -eq "Workspace" -and -not $_.IsOrphaned }
}
if (-not $workspaces) {
Write-Warning "No matching workspaces found."
return
}
$cutoff = (Get-Date).AddDays(-$DaysBack)
$results = New-Object System.Collections.Generic.List[Object]
foreach ($workspace in $workspaces) {
$datasets = Get-PowerBIDataset -WorkspaceId $workspace.Id
foreach ($dataset in $datasets) {
if (-not $dataset.IsRefreshable) {
continue
}
try {
$history = Get-PowerBIDatasetRefreshHistory -WorkspaceId $workspace.Id -DatasetId $dataset.Id |
Where-Object { [datetime]$_.StartTime -ge $cutoff }
}
catch {
Write-Warning "Could not read refresh history for '$($dataset.Name)' in '$($workspace.Name)': $($_.Exception.Message)"
continue
}
foreach ($refresh in $history) {
$start = [datetime]$refresh.StartTime
$end = if ($refresh.EndTime) { [datetime]$refresh.EndTime } else { $null }
$durationMinutes = if ($end) { [math]::Round(($end - $start).TotalMinutes, 1) } else { $null }
$flag = if ($refresh.Status -eq "Failed") {
"Failed"
}
elseif ($durationMinutes -and $durationMinutes -gt $LongRunningMinutes) {
"Long running"
}
else {
"OK"
}
$results.Add([PSCustomObject]@{
Workspace = $workspace.Name
Dataset = $dataset.Name
Status = $refresh.Status
StartTime = $start
DurationMinutes = $durationMinutes
RefreshType = $refresh.RefreshType
Flag = $flag
ErrorMessage = $refresh.ServiceExceptionJson
})
}
}
}
if (-not $results.Count) {
Write-Host "No refresh history found in the last $DaysBack day(s)."
return
}
$flagged = $results | Where-Object { $_.Flag -ne "OK" }
Write-Host ""
Write-Host "Checked $($results.Count) refresh(es) across $($workspaces.Count) workspace(s)."
Write-Host "$($flagged.Count) refresh(es) flagged as failed or long running."
Write-Host ""
$results | Sort-Object Workspace, Dataset, StartTime -Descending | Format-Table Workspace, Dataset, Status, StartTime, DurationMinutes, Flag -AutoSize
if ($ExportPath) {
$results | Export-Csv -Path $ExportPath -NoTypeInformation
Write-Host "Full results exported to $ExportPath"
}
Read it before you run it, and test in a safe tenant first.