sql-serverpowershellpowerbisql-agent

Unable to Process Partition in Power BI Premium Model Using SQL Server Agent Powershell CmdExec Step


I am trying to use Analysis Services Cmdlets to process partitions on a Power BI Premium Model. My PowerShell script works fine when run from ISE, the command line, and when scheduled using windows task scheduler; however, when I try to schedule the PowerShell script using a SQL Server 2019 Agent job using a step type of Operating System (CmdExec)" the following error message is encountered.

Message Executed as user: MyDomain\MyUser. Invoke-ProcessPartition : The connection string is not valid. At C:\Users\MyUser\Desktop\PS1\SSAS\wtf.ps1:15 char:11 + $asResult = Invoke-ProcessPartition -Credential $UserCredential -Server...+
CategoryInfo : NotSpecified: (:) [Invoke-ProcessPartition], ConnectionException + FullyQualifiedErrorId : Microsoft.AnalysisServices.ConnectionException,Microsoft.AnalysisServices.PowerShell.Cmd lets.ProcessPartition.

I have followed the steps in this blog article to setup the job. The same windows user is used in all three run scenarios. The SQL server is my local development SQL server of which the windows user is SA on the SQL Server and Windows Admin. The same machine the SQL Instance is on is being used for successfully executing the other three ways of running the PS scripts, (ISE, Command Line, & Windows Task Scheduler)

If I run the following from the command line on the same machine as the SQL server, my local host, the PowerShell script runs successfully.

PowerShell -File "C\Users\MyUser\Desktop\PS1\SSAS\wtf.ps1"

Below is my PowerShell script modified to be as small as possible to demonstrate issue and of course sensitive information redacted. Thanks in advance for any help, I'm at a loss at how to proceed. I really need this to work from the SQL agent so I don't have to guess when steps that the processing depends on have completed.

$ErrorActionPreference=”Stop”

Import-Module "SqlServer"

$User = "MyUser@MyDomain.com"
$PWord = ConvertTo-SecureString -String "MyPassword" -AsPlainText -Force
$UserCredential = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $User, $PWord

$server = "powerbi://api.powerbi.com/v1.0/myorg/MyWorkspace"
$db = "MyModel"

$asResult = Invoke-ProcessPartition -Credential $UserCredential -Server $server -PartitionName "DimDate" -TableName "DimDate" -Database $db  -RefreshType "Full"

The step code in my job is:

powershell -File "C:\Users\MyUser\Desktop\PS1\SSAS\wtf.ps1"

UPDATE: I have discovered that if I target an on-prem SSAS server, the exact same code, with the exception of the server variable, does work using the SQL Agent method, but of course switching to on-prem is not what I desire.

UPDATE 2: When I right click on a job within SSMS, and click "Start PowerShell" this opens up a SQL Server PowerShell Window. If I try executing the script this way I get the below error message. The account being used does not have MFA enabled.

Unable to obtain authentication token using the credentials provided. If your Active Directory tenant administrator has configured Multi-Factor Authentication or if your account is a Microsoft Account, please remove the user name and password from the connection string, and then retry. You should then be prompted to enter your credentials.

If I don't pass a credential to the Invoke-ProcessPartition command using the SQL Server PowerShell window, I get prompted for credentials and the call works. Of course I can't use this as a workaround because I need it to run unattended.

I also tried opening PowerShell ISE as the account being used for authentication to the Workspace in the PS script and it also gives the same error as the SQL Server Agent Job does.

The connection string is not valid.


Solution

  • I have found a solution to the issue. The resolution was twofold.

    First problem was that when PowerShell was being run from the SQL Server Agent, the Version of the SqlServer module was an older outdated version. I found this out by executing a ps1 file from the SQL Server Agent Job using the following code and looking in the job history results.

    Get-Command -module sqlserver invoke*
    

    I tried running

    Install-Module sqlserver -AllowClobber -Scope AllUsers  
    

    as an admin but it did not update the SqlServer module the SQL agent was running. Instead I created a ps1 file that simply runs

     Install-Module sqlserver -AllowClobber -Scope CurrentUser -Force 
    

    and called the script using a SQL Agent CMD task and this updated the SqlServer module version. After this I started getting a more useful error message:

    Unable to obtain authentication token using the credentials provided. If your Active Directory tenant administrator has configured Multi-Factor Authentication or if your account is a Microsoft Account, please remove the user name and password from the connection string, and then retry. You should then be prompted to enter your credentials

    With this new error message, I decided to try an alternate way of supplying credentials by utilizing Azure Service Principals. This new method resulted in success from all PowerShell methods including SQL Server Agent Job. The steps implemented are outlined in this Power BI Documentation.

    The final PS code looks like this.

    $ErrorActionPreference=”Stop”
    Import-Module "SqlServer"
    $AppId = "AAD_App_Registration_Application_Client_Id"
    $TenantId = "AAD_App_Registration_Directory_Tenant_Id"
    $AppSecret = "AAD_App_Registration_CertificatesAndSecrets_ClientSecret"
    $PWord = ConvertTo-SecureString -String $AppSecret -AsPlainText -Force
    $Credential = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $AppId, $PWord
    
    Invoke-ProcessPartition -Server "powerbi://api.powerbi.com/v1.0/myorg/MyModel" -PartitionName "DimDate" -TableName "DimDate" -Database "MyModel" -RefreshType "Full" -ServicePrincipal -ApplicationId $AppId -TenantId $TenantId -Credential $Credential