如何在 Power BI 部署管道中添加“UAT”阶段?

Posted

技术标签:

【中文标题】如何在 Power BI 部署管道中添加“UAT”阶段?【英文标题】:How to add 'UAT' stage in PowerBI deployment pipeline? 【发布时间】:2021-11-03 08:01:38 【问题描述】:

当我在 PowerBI 中创建新的部署管道时,它默认显示 3 个阶段(开发 -> 测试 -> 生产)。有没有办法像 UAT(开发 -> 测试 -> UAT -> 生产)一样向管道添加新阶段?

编辑#1 error while patching credentials-Andrey

【问题讨论】:

据我所知,没有办法添加下一个阶段:(API 也是如此;部署管道阶段顺序。开发(0),测试(1),生产(2)。)更多信息:docs.microsoft.com/en-us/rest/api/power-bi/pipelines/… 【参考方案1】:

不,这是不可能的。正如documentation 中明确写的那样,Power BI 部署管道只有三个阶段:

该工具被设计为一个管道具有三个阶段

发展

此阶段用于与其他创作者一起设计、构建和上传新内容。这是部署管道的第一阶段。

测试

对内容进行所有必要的更改后,您就可以进入测试阶段了。您上传修改后的内容,以便将其移至此测试阶段。以下是可以在测试环境中完成的三个示例:

与测试人员和审阅者共享内容

使用大量数据加载和运行测试

测试您的应用,看看它在最终用户中的表现如何

生产

测试内容后,使用生产阶段与整个组织的业务用户共享内容的最终版本。

但这三个阶段的名称和目的并不一定意味着您必须以这种方式使用它们。您可以在第 0 阶段(也称为开发)中进行测试,并将第 1 阶段(也称为测试)用作 UAT,或者为此重新调整生产阶段的用途。您始终可以使用 API 通过自己复制和部署工件来自动化缺失的阶段。例如,这是一个 PowerShell 脚本,它将所有报告从一个工作区复制到另一个工作区,更改其数据源并修补凭据。该示例使用 SQL Server,但如果需要,您可以对其进行扩展以支持其他类型。此外,如果存在具有多个数据源的数据集,您也必须遍历它们。

Import-Module MicrosoftPowerBIMgmt

# Get from Azure AD -> Properties (https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/Properties)
$tenantId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# Get Application (client) ID from Azure AD -> App registrations (https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredApps)
$applictionId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# Create it from application's "Certificates & secrets" section
$applicationSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# The name of the workspace from which you will take all reports
$fromWorkspaceName = "Dev workspace"
# The name of the workspace where the reports will be copied
$toWorkspaceName = "Test workspace"

# Information about the datasources used
$fromServerName = "dev.database.windows.net"
$fromDatabaseName = "Sales"
$toServerName = "test.database.windows.net"
$toDatabaseName = "Sales"
$sqlUserName = "sa"
$sqlUserPassword = "P@ssw0rd"

# Functions

function DownloadReport

    Write-Host "Downloading $($fromReport.Name) from $($fromWorkspace.Name)..."
    $tempFolder = [System.IO.Path]::GetTempPath()
    $subFolder = [System.Guid]::NewGuid()
    $workingFolder = New-Item -ItemType Directory -Path (Join-Path $tempFolder $subFolder)
    $tempFile = Join-Path $workingFolder ([System.Guid]::NewGuid().ToString() + ".pbix")
    try
    
        Export-PowerBIReport -WorkspaceId $fromWorkspace.Id -Id $fromReport.Id -OutFile $tempFile
        return $tempFile    
    
    catch
    
        Resolve-PowerBIError -Last
    


function UploadReport

    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [String]$FileToUpload
    )
    Write-Host "Uploading $($fromReport.Name) to $($toWorkspace.Name)..."
    try
    
        $report = New-PowerBIReport -Path $fileToUpload -Name $fromReport.Name -Workspace $toWorkspace -ConflictAction CreateOrOverwrite
        return $report
    
    catch
    
        Resolve-PowerBIError -Last
    


function GetDataset

    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [Microsoft.PowerBI.Common.Api.Reports.Report]$Report
    )
    Write-Host "Finding the dataset..."
    if ($Report.DatasetId -ne $null) # Do we know the dataset Id?
    
        # Get the dataset by Id
        $dataset = Get-PowerBIDataset -WorkspaceId $toWorkspace.Id -Id $Report.DatasetId
    
    else
    
        # Get the dataset by the name of the report
        $dataset = Get-PowerBIDataset -WorkspaceId $toWorkspace.Id -Name $Report.Name
    
    return $dataset


function ChangeDataSource

    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [Microsoft.PowerBI.Common.Api.Datasets.Dataset]$Dataset
    )

    Write-Host "Checking the datasource..."

    # Construct url
    $datasetBaseUrl = "groups/$($toWorkspace.Id)/datasets/$($Dataset.Id)"
    $datasourceUrl = "$datasetBaseUrl/datasources"
    $datasourePatchUrl = "$datasetBaseUrl/Default.UpdateDatasources"

    # Call the REST API to get gateway Id, datasource Id and current connection details
    $datasourcesResult = Invoke-PowerBIRestMethod -Method Get -Url $datasourceUrl | ConvertFrom-Json

    # Parse the response
    $datasource = $datasourcesResult.value[0] # If your report has many, loop through them
    $gatewayId = $datasource.gatewayId
    $datasourceId = $datasource.datasourceId
    $sqlDatabaseServerCurrent = $datasource.connectionDetails.server
    $sqlDatabaseNameCurrent = $datasource.connectionDetails.database

    if (($sqlDatabaseServerCurrent -ieq $fromServerName) -and ($sqlDatabaseNameCurrent -ieq $fromDatabaseName))
    
        Write-Host "Updating the datasource..."
        # create HTTP request body to update datasource connection details
        $postBody = @
          "updateDetails" = @(
           @
            "connectionDetails" = @
              "server" = "$toServerName"
              "database" = "$toDatabaseName"
            
            "datasourceSelector" = @
              "datasourceType" = "Sql"
              "connectionDetails" = @
                "server" = "$sqlDatabaseServerCurrent"
                "database" = "$sqlDatabaseNameCurrent"
              
              "gatewayId" = "$gatewayId"
              "datasourceId" = "$datasourceId"
            
          )
        

        $postBodyJson = ConvertTo-Json -InputObject $postBody -Depth 6 -Compress

        try
        
            # Execute POST operation to update datasource connection details
            Invoke-PowerBIRestMethod -Method Post -Url $datasourePatchUrl -Body $postBodyJson
            return $true
        
        catch
        
            Resolve-PowerBIError -Last
        
        return $false
    


function PatchCredentials

    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [Microsoft.PowerBI.Common.Api.Datasets.Dataset]$Dataset
    )
    
    Write-Host "Patching the credentials..."

    # Construct url
    $datasetBaseUrl = "groups/$($toWorkspace.Id)/datasets/$($Dataset.Id)"
    $datasourceUrl = "$datasetBaseUrl/datasources"
    $datasourePatchUrl = "$datasetBaseUrl/Default.UpdateDatasources"

    # Call the REST API to get gateway Id, datasource Id and current connection details
    $datasourcesResult = Invoke-PowerBIRestMethod -Method Get -Url $datasourceUrl | ConvertFrom-Json

    # Parse the response
    $datasource = $datasourcesResult.value[0] # If your report has many, loop through them

    $gatewayId = $datasource.gatewayId
    $datasourceId = $datasource.datasourceId
    $datasourePatchUrl = "gateways/$gatewayId/datasources/$datasourceId"

    # HTTP request body to patch datasource credentials
    $userNameJson = """name"":""username"",""value"":""$sqlUserName"""
    $passwordJson = """name"":""password"",""value"":""$sqlUserPassword"""

    $patchBody = @
    "credentialDetails" = @
        "credentials" = """credentialData"":[ $userNameJson, $passwordJson ]"
        "credentialType" = "Basic"
        "encryptedConnection" =  "NotEncrypted"
        "encryptionAlgorithm" = "None"
        "privacyLevel" = "Organizational"
    
    

    # Convert body contents to JSON
    $patchBodyJson = ConvertTo-Json -InputObject $patchBody -Depth 6 -Compress

    # Execute PATCH operation to set datasource credentials
    Invoke-PowerBIRestMethod -Method Patch -Url $datasourePatchUrl -Body $patchBodyJson    


function RefreshDataset

    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [Microsoft.PowerBI.Common.Api.Datasets.Dataset]$Dataset
    )
    
    Write-Host "Refreshing the report..."

    # Construct url
    $datasetRefreshUrl = "groups/$($toWorkspace.Id)/datasets/$($Dataset.Id)/refreshes"

    # We will skip the request body (notifyOption), so it will give us "WARNING: The Body parameter was null, the request may be invalid when Method parameter is Post."
    Invoke-PowerBIRestMethod -Method Post -Url $datasetRefreshUrl -WarningAction SilentlyContinue


function Cleanup

    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [String]$FileToDelete
    )
    $folderToDelete = Split-Path -Path $FileToDelete
    Remove-Item -Path $FolderToDelete -Recurse


# Login into Power BI Service
$SecuredApplicationSecret = ConvertTo-SecureString -String $applicationSecret -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($applictionId, $SecuredApplicationSecret)
$sp = Connect-PowerBIServiceAccount -ServicePrincipal -Tenant $tenantId -Credential $credential
# Write-Host "Logged in as: $($sp.UserName), $($sp.LoginType)"

# Find source and target workspaces
$fromWorkspace = Get-PowerBIWorkspace -Name $fromWorkspaceName
$toWorkspace = Get-PowerBIWorkspace -Name $toWorkspaceName
#$fromWorkspace = Get-PowerBIWorkspace -Id $fromWorkspaceId
#$toWorkspace = Get-PowerBIWorkspace -Id $toWorkspaceId

# Get all reports in the source workspace and loop though them
$allReports = Get-PowerBIReport -WorkspaceId $fromWorkspace.Id
foreach ($fromReport in $allReports)

    $fileName = DownloadReport
    $newReport = UploadReport -FileToUpload $fileName
    $newDataset = GetDataset -Report $newReport
    if (ChangeDataSource -Dataset $newDataset)
    
        PatchCredentials -Dataset $newDataset
        RefreshDataset -Dataset $newDataset
    
    Cleanup -FileToDelete $fileName


# Be a nice guy and say goodbye
Disconnect-PowerBIServiceAccount

【讨论】:

如果我想部署到现有工作区,您的脚本是否可以用作 powerBI 部署管道的替代方案?很抱歉偏离了上下文,但我还有另一个问题正在处理中,我发布在***.com/questions/69046642/… 是的,可以。但是请确保您清楚地了解它的工作原理以及运行时的效果。您可能需要修改它以根据您选择的某些标准执行选择性部署。 嗨,Andrey,你的脚本非常有用。我能够更新数据源并修补其凭据。但是,当我再次运行该脚本时,通过删除“toWorkspace”中的所有数据集,它会在修补凭据时出现另一个错误(使用编辑#1 附加在原始问题中的屏幕截图)。 谢谢你,@AniketKarajgikar!我很乐意提供帮助 欢迎您!你能检查我更新的评论吗>

以上是关于如何在 Power BI 部署管道中添加“UAT”阶段?的主要内容,如果未能解决你的问题,请参考以下文章

power bi如何制作地图数据表?power bi如何在地图上标出数据啊?

使用power bi 部署到本地

如何在 Power BI 中动态获取列名?

如何在 power bi 中向现有数据添加小计行

power bi如何抓取连续的分秒

如何将颜色饱和度分布的图例添加到 power bi 填充地图图表中