Forum Discussion
Monitor dataset refresh
- 30 days ago
Hi sandlox
Since it's a Pro workspace, workspace monitoring is out — it requires "the workspace is assigned to a Power BI Premium or a Fabric capacity." Lakehouse/Warehouse, Semantic Link and Activator are Fabric capacity items too, so the REST API is the right route.Start here first (five minutes, no build): on each model, Settings → Refresh, keep the owner notification on and add your team to the failure-notification contacts box. Recipients must have accounts in your Entra tenant. Note that "refreshes triggered programmatically such as through Power Automate don't trigger email notifications" — worth knowing before you automate anything.
If you need history and trends:
- Register a service principal, enable Allow service principals to use Power BI APIs, and add it to the workspace as Member or Admin — the API requires it ("Caller must have Write permissions on the dataset").
- Call GET /v1.0/myorg/groups/{groupId}/datasets/{datasetId}/refreshes?$top=60.
- Run it daily. The API keeps "between 20-60 available refresh history entries… depending on the number of refreshes in the last 3 days" — roughly a 3-day window at Pro's 8 refreshes/day. Append-only; anything you miss is gone.
- Land it somewhere Pro-friendly: a SharePoint list (free with M365, supported Power BI source) or Azure SQL.
- Report on success rate, duration, hours since last success, and consecutive failures. Add a hand-maintained expected-schedule table — it's the only way to catch a refresh that never started, which no failure alert will tell you.
One caveat on Power Automate: the Power BI connector has no refresh-history action, so you'd need HTTP with Microsoft Entra ID, a Premium connector. A scheduled PowerShell or Python script avoids that licence.
- https://learn.microsoft.com/power-bi/connect-data/refresh-data
- https://learn.microsoft.com/rest/api/power-bi/datasets/get-refresh-history
- https://learn.microsoft.com/fabric/fundamentals/enable-workspace-monitoring
- https://learn.microsoft.com/power-bi/developer/embedded/embed-service-principal
Thanks,
C Srikanth
Community Support Team
Hi sandlox,
Since you asked for more detailed steps and your semantic models are in a Pro workspace (so no Fabric notebooks or workspace monitoring), here is a complete setup that works with Pro only.
Step 1: collect the refresh history with PowerShell. The Get Refresh History API returns the recent refreshes for each semantic model. This script loops over every workspace you can access and appends the results to a CSV:
# one-time: Install-Module MicrosoftPowerBIMgmt -Scope CurrentUser
Connect-PowerBIServiceAccount
$rows = @()
foreach ($ws in Get-PowerBIWorkspace -All) {
$datasets = (Invoke-PowerBIRestMethod -Method Get `
-Url "groups/$($ws.Id)/datasets" | ConvertFrom-Json).value
foreach ($ds in $datasets | Where-Object { $_.isRefreshable }) {
$refreshes = (Invoke-PowerBIRestMethod -Method Get `
-Url "groups/$($ws.Id)/datasets/$($ds.id)/refreshes?`$top=50" |
ConvertFrom-Json).value
foreach ($r in $refreshes) {
$rows += [pscustomobject]@{
RequestId = $r.requestId
Workspace = $ws.Name
Dataset = $ds.name
RefreshType = $r.refreshType
Status = $r.status
StartTime = $r.startTime
EndTime = $r.endTime
Error = $r.serviceExceptionJson
}
}
}
}
$rows | Export-Csv "C:\PBI\refresh_history.csv" -NoTypeInformation -AppendStep 2: schedule it. The API only keeps recent history, so run the script daily (Windows Task Scheduler is enough) and save the CSV to a OneDrive or SharePoint folder so the service can refresh from it.
Step 3: build the report. In Power BI Desktop, load the CSV, then in Power Query remove duplicates on RequestId (the append will repeat runs that are still in the API window) and add a duration column. Useful measures:
Refreshes = COUNTROWS ( Refresh )
Failed Refreshes =
CALCULATE ( [Refreshes], Refresh[Status] = "Failed" )
Success Rate =
DIVIDE ( [Refreshes] - [Failed Refreshes], [Refreshes] )
Avg Duration (min) =
AVERAGEX (
FILTER ( Refresh, NOT ISBLANK ( Refresh[EndTime] ) ),
DATEDIFF ( Refresh[StartTime], Refresh[EndTime], SECOND ) / 60
)
Last Status =
VAR LastStart = MAX ( Refresh[StartTime] )
RETURN
CALCULATE ( MAX ( Refresh[Status] ), Refresh[StartTime] = LastStart )Step 4: the dashboard layout I would use:
cards -> refreshes today, failed today, success rate
table -> dataset | last status | last end time | avg duration
line chart -> duration per dataset over time (spots slow growth)
table -> failed refreshes with the Error textFinally, add a data alert on the "failed today" card, or a subscription, so someone hears about failures without opening the report.
So my overall approach would be:
PowerShell + Refresh History API, appended daily
-> CSV in OneDrive / SharePoint
-> dedupe on RequestId, add duration
-> status, duration and error views + alert on failuresThat gives you a working monitor today on Pro, and you can later move the same logic to a notebook and lakehouse if you get Fabric capacity.
AI-assisted drafting: AI was used to help structure and phrase this response. I reviewed and validated the technical content before posting.