microsoft / powerbi-powershell

PowerShell community for Microsoft PowerBI. Here you will find resources and source for PowerShell modules targeting PowerBI.
MIT License
348 stars 121 forks source link

Connect-PowerBIServiceAccount fails when MFA is enabled for PowerBI #135

Open WatersJohn opened 5 years ago

WatersJohn commented 5 years ago

My organization has MFA enabled for PowerBI. When I execute the below script to login to powerBI as a user (not an SPN), AzureADWindowsAuthenticator displays an error, along with the following stack trace. The same script works fine on a test account in a different tenant where MFA is not required for PowerBI. We're going to try an SPN next as a workaround.

Lastly, this occurs right after our following ADFS endpoint is called: POST https://adfsserver.company.com//adfs/services/trust/2005/usernamemixed ; an HTTP 200 is returned but the body of the XML states failedAuthentication, reason MSIS7068: Access denied..

`$DebugPreference ='Continue';

$Username = 'user@company.com';

$Pwd = 'passwordgoeshere';

$p2 = ConvertTo-SecureString $Pwd -AsPlainText -Force

$cred = New-Object System.Management.Automation.PSCredential($UserName,$p2);

Connect-PowerBIServiceAccount -Credential $cred -Verbose`

DEBUG: 10:12:24 PM - Connect-PowerBIServiceAccount begin processing with ParameterSet UserAndCredential. DEBUG: 10:12:24 PM - Cmdlet version: 1.0.487.0 Connect-PowerBIServiceAccount : Failed to get ADAL token: Unhandled Exception: System.AggregateException: One or more errors occurred. ---> Microsoft.IdentityModel.Clients.ActiveDirectory.AdalException: Device Certificate was not found for Cert Authorities:OU=82dbaca4-3e81-46ca-9c73-0950c1eaca97,CN=MS-Organization-Access,DC=windows,DC=net
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Platform.DeviceAuthHelper.FindCertificateByCertAuthorities(IDictionary’2 challengeData, X509Certificate2Collection certCollection)
At Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Platform.DeviceAuthHelper.FindCertificate(IDictionary’2 challengeData)
At Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Platform.DeviceAuthHelper.d2.MoveNext() --- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Http.AdalHttpClient.d
25’1.MoveNext() --- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Http.AdalHttpClient.d22’1.MoveNext() --- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Http.AdalHttpClient.d
21’1.MoveNext() --- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.d72.MoveNext() --- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.d
69.MoveNext() --- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.d59.MoveNext() --- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase.d
57.MoveNext() --- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext.d37.MoveNext() --- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions.d
0.MoveNext() --- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at AzureADWindowsAuthenticator.Program.d__1.MoveNext() in C:\projects\powerbi-powershell\src\Common\AzureADWindowsAuthenticator\Program.cs:line 33 --- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task’1.GetResultCore(Boolean waitCompletionNotification)
at System.Threading.Tasks.Task’1.get_Result()
at AzureADWindowsAuthenticator.Program.Main(String[] args) in C:\projects\powerbi-powershell\src\Common\AzureADWindowsAuthenticator\Program.cs:line 18

cvillegashak commented 4 years ago

Is this still on the roadmap to be corrected?

joeywas commented 4 years ago

Receiving this error message when attempting to use Connect-PowerBIServiceAccount to authenticate to the USGov environment with an account that has MFA enabled:

Connect-PowerBIServiceAccount : Failed to get ADAL token: Unhandled Exception: System.AggregateException:
One or more errors occurred. --->
Microsoft.IdentityModel.Clients.ActiveDirectory.AdalClaimChallengeException: AADSTS50076: Due to a
configuration change made by your administrator, or because you moved to a new location, you must use
multi-factor authentication to access

This was working a couple of weeks (maybe a month?) ago, but is now not working.

ScriptPup commented 4 years ago

Bump, I have the same issue - Did you ever figure it out @WatersJohn?

ScriptPup commented 4 years ago

Update: I just found, for me at least, I was getting this error in a VERY specific situation. Everything worked perfectly fine when I ran through each step in the PowerShell script in a PowerShell console; but I began getting the above error as soon as I tried to run it through an automation system (tried SSIS and Task Manager scheduled jobs both). This lead me to try to launch the script using the exact same call from a PowerShell window. This also ran 100% correctly. I finally thought to try running it from a cmd prompt instead of a PowerShell console. When I did this I got the same message that the automation was returning.

So I beat my head against it and looked all over including finding this page which seemed to indicate there was a bug of some sort... However I kept messing with it. Finally, just for giggles I tried replacing my string encapsulation with double quotes instead of single. This finally worked through the cmd prompt the same way as through the PS console. Is there an eyeroll emoji somewhere?!

Here's my code for anyone who stumbles on this: Script to run a simple dataset refresh --

Param (
    [string]$Username,
    [string]$Password,
    [string]$dataset,
    [string]$workspaceGUID 
)
$ErrorActionPreference = "Stop";

# Verify paramaters are provided
if(!$Username) {
    throw "Username not provided, cannot proceed.";
    return
}
if(!$Password) {
    throw "Password not provided, cannot proceed.";
    return
}
if(!$Username) {
    throw "Dataset not provided, cannot proceed.";
    return
}

#Authentication
$pass = ConvertTo-SecureString -AsPlainText $Password -Force
$Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Username,$pass
Connect-PowerBIServiceAccount -Credential $Credentials
$token = Get-PowerBIAccessToken

#Request Object Definitions
$workspace  = Get-PowerBIWorkspace -WorkspaceId "d42c2d9b-17cb-4612-b8d3-df47c7f08466"
$datasetObj    = Get-PowerBIDataset -WorkspaceId $($workspace.id) | Where-Object Name -eq $dataset
$uri = "https://api.powerbi.com/v1.0/myorg/groups/$($workspace.id)/Datasets/$($datasetObj.id)/refreshes"

#Build the access token into the authentication header
$authHeader = @{
    'Content-Type'='application/json'
    'Authorization'= $token.Authorization
}
# Build JSON, convert back and forth as we're just defining it as a string.
$json = '{"notifyOption": "MailOnFailure"}' | ConvertFrom-Json
$body = $json | ConvertTo-Json

# Check refresh status
$Status = Invoke-RestMethod -Uri $uri -Headers $authHeader -Method GET

# Request Refresh 
Invoke-RestMethod -Uri $uri -Headers $authHeader -body $body -Method POST

# Revoke token, disconnect from service gracefully
Disconnect-PowerBiServiceAccount

Call it like this from my SSIS package:

PowerShell.exe -ExecutionPolicy Bypass -F .\PowerShell\RefreshDataset.ps1 -Username "<MyUser>" -Dataset "<MyDataset>" -Password "<MyPassword>"

Not sure if my issue was unrelated and just happened to have the exact same error message or if this will help others.