The correct json body for updating Refresh Schedule with REST API

414 Views Asked by At

When I using the REST API to update the Refresh Schedule:

https://learn.microsoft.com/en-us/rest/api/power-bi/datasets/update-refresh-schedule

I need the specify settings for the schedule like below:

enter image description here

But when I using below json body (Get it By F12):

{'value': {'notifyOption':'NoNotification', 'enabled': true, 'isDaily':true,'times': ['07:00'],'localTimeZoneId': 'UTC','refreshNotificationEnabled':false,'refreshContacts':[{'displayName':'xx Leoxx','objectId':'06211a47-86a2-48e7-8840-1984efbfb0d5','userPrincipalName':'My E-mail.com','isSecurityGroup':false,'objectType':1,'groupType':0,'aadAppId':null,'emailAddress':'My E-mail.com','relevanceScore':null,'creatorObjectId':null}]}}

It always prompts me that the json is not correct.

According to my understanding of the contact, it seems that it needs to display the name and object ID after verification during the input process, which seems to be impossible to obtain in advance? Or the objectId is bound to my personal account and will not be regenerated due to different deployment targets.

Anyway, I would like to have a correct json body. Please give me a json body that exactly matches my screenshot settings and verifies that it works, it has been driving me crazy for a day. thank you very much.

Note: I have already checked the body from the REST API, that is the old one, what I need is that:

  1. Daily instead of certain days(Sunday,Tuesday,Friday).
  2. Need include the contact person who will send the notification when it fails.
1

There are 1 best solutions below

5
DeLacey On

I don't think what you ask is possible with the official PowerBI REST API. There is no option to add the notification emailaddress in the MS Docs, or an option that is 'daily' withou listing every weekday. Link: https://learn.microsoft.com/en-us/rest/api/power-bi/datasets/update-refresh-schedule#schedulenotifyoption

In this forum post the answer from Microsoft also notes that adding a notification emailaddress is not possible. https://community.fabric.microsoft.com/t5/Service/power-bi-create-schedule-refresh-api-not-able-to-set-email-ID/m-p/1679990

Best you can now do is the following, which will email the dataset owner:

{
    "value": {
        "notifyOption": "MailOnFailure",
        "enabled": true,
        "days": [
        "Sunday",
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday",
        "Saturday"
        ],
        "times": [
        "07: 00",
        "06: 30"
        ],
        "localTimeZoneId": "UTC"
    }
}

EDIT Using the REST API that PowerBI uses from the webportal I have been able to change the refresh settings. Please note, Microsoft might change this API anytime, since it is not desgined for end-users.

First you will need to get an access token. I got mine by copying the first token request from the webportal (caught with browser development tools). When you use an Azure AD application you will easily be able to get a token. Microsoft has a lot of documentation about it. https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow

One setup could be this. See for details about the app settings in AzureAD: https://stackoverflow.com/a/63989297

$clientId = "YOUR_CLIENT_ID"
$clientSecret = "YOUR_CLIENT_SECRET"
$resource = "openid profile offline_access https://analysis.windows.net/powerbi/api/.default" 
$tokenEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/token"

$body = @{
    "grant_type"    = "client_credentials" 
    "client_id"     = $clientId
    "client_secret" = $clientSecret
    "scope"         = $resource
}

$getToken = Invoke-WebRequest -UseBasicParsing -Uri "https://login.microsoftonline.com/common/oauth2/v2.0/token" -Method Post -Body $body -ContentType "application/x-www-form-urlencoded" 

$bearer = "Bearer $(($getToken.Content | ConvertFrom-Json).access_token)"

When you have your bearer token you can start using the API. I have caught these endpoints using my browser. My base URI references north-europe. It might be different for you. When changing the refresh settings in the webportal you will see a request 'rehreshschedule', you can use details there to fill your automation script.

First we get the dataset:

# dataset details (example)
$workspaceName = "My Workspace"
$displayname = "Deployments"

$getdatasets = Invoke-WebRequest -UseBasicParsing -Uri "https://wabi-north-europe-k-primary-redirect.analysis.windows.net/metadata/gallery/SharedDatasets" -Headers @{ "authorization"= $bearer }
$datasets = ($getdatasets.Content | ConvertFrom-Json -AsHashtable)
$workspace = $datasets | Where-Object {$_.workspaceName -eq "$workspacename"}
$dataset = $workspace | Where-Object {$_.model.displayName -eq "$displayName"}
$modelId  = $dataset.modelId

Then we create the body for the refreshschedule request. I suggest following the details you catch once from the portal. Refresh body options: refresh

  • NotificationEnabled > true/false if true then the dataset owner is notified.
  • refreshContacts > if filled properly, then these contacts are notified.
  • objectId/UPN/DisplayName/emailAddress > the AzureAD/M365 details of the account to send the notification to. There are multiple ways to get this, i.e. AzureAD or MS Graph powershell modules. Or you can copy this once using the developers tools in you browser when making the refresh settings for the needed account. These identifiers and Types will stay the same. By copying you will get all the right values for objectType, groupType etc, if you do not use a regular user.
$body = @{
    importAndRefreshBehavior = 2
    refreshEnabled = $true
    isDaily = $true
    refreshFrequency = $null
    weekDays = 127
    executionTime = $null
    executionTimeHourly = "[`"7:00:00`",`"6:30:00`"]"
    localTimeZoneId = "China Standard Time" # replace with local timezone
    refreshNotificationEnabled = $false
    refreshContacts = @(
        @{
            displayName = "User Name"
            objectId = "657b56e4-c6c5-42e9-80e7-745180df3aeb"
            userPrincipalName = "[email protected]"
            isSecurityGroup = $false
            objectType = 1
            groupType = 0
            aadAppId = $null
            emailAddress = "[email protected]"
            relevanceScore = $null
            creatorObjectId = $nul
        }
    )
} | ConvertTo-Json  

Lastly we actually send the request.

$uri = "https://wabi-north-europe-k-primary-redirect.analysis.windows.net/powerbi/metadata/models/$modelId/refreshschedule"

$refresh = Invoke-WebRequest -UseBasicParsing -Uri $uri -Method "POST" -Headers @{"authorization" =  $bearer} -ContentType "application/json;charset=UTF-8" -Body $body

As for the requirement from your management.

The reason why we must implement it using the REST API is that in our Prod environment, we are not allowed to manually modify it, which is considered an unsafe behavior, and the company does not allow manual modification of the prod environment.

Using such a backend API is not safe either, since Microsoft is not at all required (and doesn't) inform users of change in backend APIs.

I hope this will help you get further on this project :).