Forum Discussion

Anonymous's avatar
Anonymous
Not applicable
7 years ago

Power BI API via PowerShell fails in Azure DevOps

Hi all,

 

I'm trying to automate the deployment of Power BI (and other modern DWH components) via Azure DevOps releases. I've created a PowerShell script that looks at the contents of a setup file in my repository and then starts creating workspaces (if they don't exist) and publish reports to these workspaces. 

 

Everything works fine when I run the PowerShell script on my local laptop. It hangs when I run it in DevOps. I've narrowed the issue down to the authentication part of the script. 

 

I use an app registration to authenticate against Power BI. This works. The first time I ran the script I had to assign rights to the app, and now it just works. 

My script below (simplified to demo the issue)

$clientId = "xyz" -- clientId of app here
function GetAuthToken
{
    if(-not (Get-Module AzureRm.Profile)) {
      Import-Module AzureRm.Profile
    }

    $redirectUri = "urn:ietf:wg:oauth:2.0:oob"

    $resourceAppIdURI = "https://analysis.windows.net/powerbi/api"

    $authority = "https://login.microsoftonline.com/common/oauth2/authorize";

    $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority

    $authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId, $redirectUri, "Auto")

    return $authResult
}

$token = GetAuthToken

# Building Rest API header with authorization token
$auth_header = @{
   'Content-Type'='application/json'
   'Authorization'=$token.CreateAuthorizationHeader()
} 

$target_group_name = "ABC Test Workspace"
$uri = "https://api.powerbi.com/v1.0/myorg/groups"
$body = "{`"name`":`"$target_group_name`"}"
$response = Invoke-RestMethod -Uri $uri –Headers $auth_header –Method POST -Body $body
Write-Host $response.id

What happens is that on the AcquireToken function, a popup window (the authentication window) opens up and then immediately closes (because the app is already authenticated). 

However, in DevOps, the script seems to hang on this popup. When I run this in Windows the script continues past the popup and creates the Power BI workspace called "ABC Test Workspace". In DevOps, nothing happens and I have to cancel the operation manually. 

 

Does anybody have an idea how to solve this? It would be great to have a working DevOps pipeline to do CI/CD stuff with Power BI from your repositories. 

 

Thanks in advance.

 

Cheers! 

Bas

6 Replies

  • Hi Anonymous 

     

    Not sure that you aware of the Azure DevOps Extension called PowerBI Action. Using this you can do some operation easily with out having worry about powershell scripts.

     

    If you still want to do some additional things , you can see the source code of the extension, where the author is also using powershell to build this extension.

     

    The author put all the powershell cleanly in a function, as per that

     

    Function Get-AADToken {
        Param(
            [parameter(Mandatory = $true)][string]$Username,
            [parameter(Mandatory = $true)][SecureString]$Password,
            [parameter(Mandatory = $true)][guid]$ClientId,
            [parameter(Mandatory = $true)][string]$Resource
        )
    
        $authorityUrl = "https://login.microsoftonline.com/common/oauth2/authorize"
    
        ## load active directory client dll
        $typePath = $PSScriptRoot + "\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
        Add-Type -Path $typePath 
    
        Write-Verbose "Loaded the Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
    
        Write-Verbose "Using authority: $authorityUrl"
        $authContext = New-Object -TypeName Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext -ArgumentList ($authorityUrl)
        $credential = New-Object -TypeName Microsoft.IdentityModel.Clients.ActiveDirectory.UserCredential -ArgumentList ($UserName, $Password)
        
        Write-Verbose "Trying to aquire token for resource: $Resource"
        $authResult = $authContext.AcquireToken($Resource, $clientId, $credential)
    
        Write-Verbose "Authentication Result retrieved for: $($authResult.UserInfo.DisplayableId)"
        return $authResult.AccessToken
    }

     I'm also writing a detailed article for CICD for PowerBI using Azure DevOps, 

     

    https://social.technet.microsoft.com/wiki/contents/articles/53172.azuredevops-cicd-for-powerbi-reports.aspx

     

    But it's still in progress, I stil need some time to need these too :smileywink:

    • Anonymous's avatar
      Anonymous
      Not applicable

      The reason I can't use Power BI Actions (I tried!) is that it needs a username and password. This is not acceptible for our clients. Best practice is to use a client id. 

      Via PowerShell this is 100% possible. In fact the scripts work when I run them locally on my laptop. They seem to get stuck on the authentication part when I run them as part of a DevOps pipeline. 

       

      I'm interested in your blog article! 

      • Jayendran's avatar
        Jayendran
        Solution Sage

        Hi Anonymous 

        Ok could you please try my script below

         

        $applicationId = "xxxxxxxx";
        $securePassword = "xxxxxx" | ConvertTo-SecureString -AsPlainText -Force
        $credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $applicationId, $securePassword
        Connect-PowerBIServiceAccount -ServicePrincipal -Credential $credential -TenantId "xxxx"

        Which is using the Client ID autentication part.

         

        I've also provided this answer in SO

         

        By this way it will work in both your local and azure devops