Help us understand the problem. What is going on with this article?

Power BI API 経由で RDL ファイルを Power BI にアップロードする

同僚: プログラムで RDL ファイルを Power BI にあげたいけどどうしたらいい?
私: え、Power BI って RDL サポートしてるんだ。。まじか

というやり取りが今朝あり、調査したので結果を共有しておきます。

RDL on Power BI

そうなんです。Power BI は RDL を "ページ分割されたレポート" としてサポートしていたのです。とりあえず チュートリアル:ページ分割されたレポートを作成して Power BI サービスにアップロードする を一通りやって勉強しました。いいチュートリアルなので是非お試しください。

API 経由でのアップロード

本題の RDL ファイルを API 経由でアップロードする方法ですが、Power BI の API は Power BI REST APIs に詳細が公開されています。

ドキュメントを見た結果、以下の手順で行けることが分かりました。

  1. Post Import In Group API を使って RDL ファイルをインポートする。この過程でレポートが作成される。
  2. Get Import In Group を使ってインポートの情報と取得する。結果として作成されたレポートの情報も取得できる。

RDL ファイルのアップロードのみであればこれで終わりですが、データソースの資格情報を手動で入れたくないので、そのやり方も調べておきました。

  1. Reports - Get Datasources In Group API でレポートに紐づくデータソースの情報を取得する。ここでゲートウェイとデータソースの情報が取得できる。
  2. Gateways - Update Datasource API を使って資格情報を設定する。

これだけです。

PowerShell の例

以前紹介したとおり、オフィシャルの Power BI PowerShell モジュールがあり、今回もそちらを使いました。一部機能がまだサポートされていないため、そこは PowerShell の機能で書いてみました。PR 作らないとなぁ。

function Publish-ImportRDLFile 
{
    param
    (
        [string]$RdlFilePath,
        [string]$GroupId,
        [string]$nameConflict = "Abort"
    )

    # RDL ファイルから body を作る
    $fileName = [IO.Path]::GetFileName($RdlFilePath)
    $boundary = [guid]::NewGuid().ToString()
    $fileBody = Get-Content -Path $RdlFilePath -Encoding UTF8

    $body = @"
----FormBoundary$boundary
Content-Disposition: form-data; name="$filename"; filename="$filename"
Content-Type: application/rdl

$fileBody 
----FormBoundary$boundary--

"@

    # アクセストークンをヘッダーに設定
    $headers = Get-PowerBIAccessToken

    if ($GroupId) {
        $url = "https://api.powerbi.com/v1.0/myorg/groups/$GroupId/imports?datasetDisplayName=$fileName&nameConflict=$nameConflict"
    }
    else {
        $url = "https://api.powerbi.com/v1.0/myorg/imports?datasetDisplayName=$fileName&nameConflict=$nameConflict"
    }

    # インポート作成
    $report = Invoke-RestMethod -Uri $url -Method Post -Headers $headers -Body $body -ContentType "multipart/form-data"   
    $report.id
}

function Set-BasicPassword-To-RDL 
{
    param
    (
        [string]$Id,
        [string]$GroupId,
        [string]$UserName,
        [string]$Password
    )

    # アクセストークンをヘッダーに設定
    $headers = Get-PowerBIAccessToken

    # 作成したインポートからレポート情報を取得。時間かかる場合があるので取れるまで繰り返し。
    $reportId = $null
    while($reportId -eq $null)
    {
        if ($GroupId) {
            $url = "https://api.powerbi.com/v1.0/myorg/groups/$GroupId/imports/$Id"
        }
        else {
            $url = "https://api.powerbi.com/v1.0/myorg/imports/$Id"
        }

        $import = Invoke-RestMethod -Uri $url -Method Get -Headers $headers
        $reportId = $import.reports.id
    }

    # Datasource 情報を取得
    if ($GroupId) {
        $url = "https://api.powerbi.com/v1.0/myorg/groups/$GroupId/reports/$reportId/datasources"
    }
    else {
        $url = "https://api.powerbi.com/v1.0/myorg/reports/$reportId/datasources"
    }

    $datasources = Invoke-RestMethod -Uri $url -Method Get -Headers $headers
    $gatewayId = $datasources.value[0].gatewayId
    $datasourceId = $datasources.value[0].datasourceId

    # 最後に認証を設定。
    $url = "https://api.powerbi.com/v1.0/myorg/gateways/$gatewayId/datasources/$datasourceId"

    # ここは基本認証の例だが、他の例は https://docs.microsoft.com/en-us/rest/api/power-bi/gateways/updatedatasource#examples を参照
    $body = @"
{
  "credentialDetails": {
    "credentialType":"Basic",
    "credentials": "{\"credentialData\":[{\"name\":\"username\", \"value\":\"$UserName\"},{\"name\":\"password\", \"value\":\"$Password\"}]}",
    "encryptedConnection": "Encrypted",
    "encryptionAlgorithm": "None",
    "privacyLevel": "None"
    }
}
"@
    $datasources = Invoke-RestMethod -Uri $url -Method Patch -Headers $headers -ContentType "application/json" -Body $body
}

# Power BI に接続
Connect-PowerBIServiceAccount

$groupId = "<group id>"
# インポート作成
$id = Publish-ImportRDLFile -GroupId $groupId -RdlFilePath "<path to rdl file>"
# 資格情報を設定
Set-BasicPassword-To-RDL -Id $id -GroupId $groupId -UserName "<username>" -Password "<password>"

まとめ

Power BI は充実した API を公開しているので、自動化したい場合は色々試してください。

Reference

Power BI Community Get Help: REST import rdl files

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした