如何在 PowerBI 部署管道中添加“UAT"阶段? [英] How to add 'UAT' stage in PowerBI deployment pipeline?

查看:26
本文介绍了如何在 PowerBI 部署管道中添加“UAT"阶段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When I create new deployment pipeline in PowerBI, it shows 3 stages (Development -> Test -> Production) by default. Is there a way to add new stage to pipeline like UAT (Development -> Test -> UAT -> Production)?

编辑#1修补凭据时出错-Andrey

推荐答案

不,不可能.正如文档中明确写的,Power BI 部署管道只有三个阶段:

No, it is not possible. As clearly written in the documentation, Power BI Deployment Pipelines has only three stages:

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

The tool is designed as a pipeline with three stages:

  • 发展

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

This stage is used to design, build, and upload new content with fellow creators. This is the first stage in deployment pipelines.

  • 测试

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

You're ready to enter the test stage after you've made all the needed changes to your content. You upload the modified content so it can be moved to this test stage. Here are three examples of what can be done in the test environment:

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

  • Share content with testers and reviewers

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

Load and run tests with larger volumes of data

测试您的应用以了解最终用户的效果

Test your app to see how it will look for your end users

生产

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

After testing the content, use the production stage to share the final version of your content with business users across the organization.

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

But the names and the purpose of these three stages doesn't necessary means that you have to use them this way. You can test in stage 0 (a.k.a. Development) and use stage 1 (a.k.a. Test) as UAT, or repurpose Production stage for that. You can always use the API to automate the missing stage by copying and deploying the artifacts on your own. For example, here is a PowerShell script, which will copy all reports from one workspace to another, change their datasource and patch the credentials. The example uses SQL Server, but you can extend it to support other types if needed. Also, if there are datasets with multiple datasources, you will have to loop through them too.

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 部署管道中添加“UAT"阶段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆