无法使用 SQL Server Agent Powershell CmdExec 步骤处理 Power BI Premium 模型中的分区

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

我正在尝试使用 Analysis Services Cmdlets 在 Power BI Premium 模型上处理分区。当来自 ISE、命令行的 运行 以及使用 windows 任务调度程序进行调度时,我的 PowerShell 脚本工作正常;但是,当我尝试使用步骤类型为 SQL Server 2019 Agent 作业来安排 PowerShell 脚本时 操作系统(CmdExec)”遇到以下错误信息。

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.

我已按照 blog article 中的步骤设置作业。在所有三个 运行 场景中使用相同的 windows 用户。 SQL 服务器是我的本地开发 SQL 服务器,windows 用户是 SQL 服务器上的 SA 和 Windows 管理员。 SQL 实例所在的同一台机器被用于成功执行 运行 宁 PS 脚本的其他三种方式,(ISE、命令行和 Windows 任务调度程序)

如果我 运行 在与 SQL 服务器相同的机器上从命令行执行以下操作,我的本地主机,PowerShell 脚本 运行s 成功。

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

下面是我的 PowerShell 脚本,已修改为尽可能小,以演示问题,当然还有已编辑的敏感信息。在此先感谢您的帮助,我不知道如何进行。我真的需要它在 SQL 代理中工作,这样我就不必猜测处理所依赖的步骤何时完成。

$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"

我工作中的步骤代码是:

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

更新: 我发现如果我以本地 SSAS 服务器为目标,除了服务器变量之外,完全相同的代码确实可以使用 SQL Agent 方法工作,但当然切换到本地并不是什么我想要。

更新 2: 当我右键单击 SSMS 中的一个作业并单击“启动 PowerShell”时,这将打开 SQL Server PowerShell Window。如果我尝试以这种方式执行脚本,我会收到以下错误消息。正在使用的帐户未启用 MFA。

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.

如果我没有使用 SQL Server PowerShell window 将凭据传递给 Invoke-ProcessPartition 命令,系统会提示我输入凭据并且调用有效。当然,我不能将此用作解决方法,因为我需要它 运行 无人值守。

我还尝试打开 PowerShell ISE 作为用于在 PS 脚本中对工作区进行身份验证的帐户,它也给出了与 SQL 服务器代理作业相同的错误。

The connection string is not valid.

我找到了解决问题的方法。决议是双重的。

第一个问题是,当从 SQL 服务器代理 运行 获取 PowerShell 时,SqlServer 模块的版本是较旧的过时版本。我通过使用以下代码从 SQL 服务器代理作业执行 ps1 文件并查看作业历史记录结果发现了这一点。

Get-Command -module sqlserver invoke*

我试过了运行宁

Install-Module sqlserver -AllowClobber -Scope AllUsers  

作为管理员,但它没有更新 SQL 代理正在 运行ning 的 SqlServer 模块。相反,我创建了一个 ps1 文件,它只是 运行s

 Install-Module sqlserver -AllowClobber -Scope CurrentUser -Force 

并使用 SQL 代理 CMD 任务调用脚本,这更新了 SqlServer 模块版本。在此之后我开始收到更有用的错误消息:

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

有了这个新的错误消息,我决定尝试使用 Azure 服务主体提供凭据的替代方法。这种新方法导致所有 PowerShell 方法都成功,包括 SQL 服务器代理作业。 Power BI Documentation.

中概述了实施的步骤

最终的 PS 代码如下所示。

$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