Functions/Restore-BsgPbiWorkspace.ps1
<#
.SYNOPSIS Restore a Power BI workspace from a local directory. .DESCRIPTION The workspace must be stored in a local directory. .PARAMETER Source_WorkspaceName The name of the workspace you would like to restore. You can find it in the mapping file after using our export Module. .PARAMETER Path The path to the root folder, where the temporary files will be saved. Subfolders will be created automatically. .PARAMETER ImportTenantLevelReports Import reports, which are based on datasets from other workspaces. Warning: If you import tenant level reports, the dependant workspaces need to be restored beforehand. You can manually run this function after all workspaces have been restored using "Import-BsgPbiReportsTenantLevel ...". .PARAMETER PbiConnection The connection to the Power BI Tenant. .EXAMPLE # Restore Workspace Restore-BsgPbiWorkspace -Source_WorkspaceName "BSGroup DA - Test Workspace" -Path "C:\temp\BSG PBI Administration" .EXAMPLE # Restore workspace - My Workspace Restore-BsgPbiWorkspace -Source_WorkspaceName "My Workspace" -Path "C:\temp\BSG PBI Administration" .EXAMPLE # Restore a single Workspace having reports connected to other workspaces Restore-BsgPbiWorkspace -Source_WorkspaceName "BSGroup DA - Test Workspace" -Path "C:\temp\BSG PBI Administration" -ImportTenantLevelReports $true .INPUTS .OUTPUTS .NOTES This script uses the Power BI Management module for Windows PowerShell. If this module is not installed, install it by using the command 'Install-Module -Name MicrosoftPowerBIMgmt -Scope CurrentUser'. #> function Restore-BsgPbiWorkspace{ param ( [Parameter(Mandatory=$true)][string]$Source_WorkspaceName ,[Parameter(Mandatory=$true)][string]$Path ,[Parameter(Mandatory=$false)][bool]$ImportTenantLevelReports = $false ,[Parameter(Mandatory=$false)][Microsoft.PowerBI.Common.Abstractions.Interfaces.IPowerBIProfile] $PbiConnection = $null ) try { # Info message Write-Host Write-Host Write-PSFHostColor -Level Host -DefaultColor white -String "---------------------------------------------------------------------------------------------" Write-Host Write-PSFHostColor -Level Host -DefaultColor white -String " Restoring workspace... " Write-Host Write-PSFHostColor -Level Host -DefaultColor gray -String " Original name: <c='green'>$Source_WorkspaceName</c>" Write-Host Write-PSFHostColor -Level Host -DefaultColor white -String "---------------------------------------------------------------------------------------------" Write-Host # PBI connection if ($null -eq $PbiConnection){ Write-Host Write-PSFHostColor -Level Host -DefaultColor gray -String "Choose the tenant and user to start the restoration..." Write-PSFHostColor -Level Host -DefaultColor gray -String "You need to be a <c='white'>Power BI Administrator</c> to restore the tenant." try{ Logout-PowerBI $PbiLogin = Login-PowerBI -ErrorAction Stop } catch{ throw "Error trying to connect to Power BI tenant." } $TenantId = $PbiLogin.TenantId $UserName = $PbiLogin.UserName Write-Host Write-PSFHostColor -Level Host -DefaultColor gray -String "You are logged in with user <c='white'>$userName</c> in tenant <c='white'>$TenantId</c>." Write-PSFHostColor -Level Host -DefaultColor white -String "Would you like to start the restoration? [y/n]: " $confirmTenant = Read-Host Write-Host if ($confirmTenant -eq 'y'){ # continue... } else{ Write-PSFHostColor -Level Host -DefaultColor gray -String "Restoration stopped." Logout-PowerBI return } } # Define base path and filenames $Path_Backup = Join-Path -Path $Path -ChildPath "Backup" $Path_Workspaces = Join-Path -Path $Path_Backup -ChildPath "Workspaces" $Path_Workspace = Join-Path -Path $Path_Workspaces -ChildPath $Source_WorkspaceName $FileName_WorkspaceMapping = "Mapping_Workspace.json" $FileName_ReportDatasetMapping = "Mapping_ReportDataset.json" $Path_WorkspaceMapping = Join-Path -Path $Path_Workspace -ChildPath $FileName_WorkspaceMapping $Path_ReportDatasetMapping = Join-Path -Path $Path_Workspace -ChildPath $FileName_ReportDatasetMapping # === # Get Workspace mapping # = try{ # Check path if ((Test-Path $Path_Workspace) -eq $false){ throw "Path `"$Path_Workspace`" does not exist." } # Check metadata file if ((Test-Path $Path_WorkspaceMapping) -eq $false){ throw "File does not exist is folder `"$Path_Workspace`"." } # Get old workspace mapping $WorkspaceMapping = Get-Content -Path $Path_WorkspaceMapping | ConvertFrom-Json -ErrorAction Stop # Check if workspace already exists $WorkspaceExists = [bool]($WorkspaceMapping.PSobject.Properties.name -match "new_id"); } catch{ throw "Error while getting workspace metadata file `"$FileName_WorkspaceMapping`". `n$_" } # === # Import workspace # = if ($WorkspaceExists){ $Target_WorkspaceId = $WorkspaceMapping.new_id $Target_WorkspaceName = $WorkspaceMapping.new_name Write-Host Write-PSFHostColor -Level Host -DefaultColor gray -String "Workspace <c='white'>$Target_WorkspaceName</c> already exists. Skip workspace creation." } else { # Create new workspace, add new_id to mapping file Import-BsgPbiWorkspace -Path_Workspace $Path_Workspace # Get new workspace metadata from mapping file try{ $WorkspaceMapping = Get-Content -Path $Path_WorkspaceMapping | ConvertFrom-Json -ErrorAction Stop $Target_WorkspaceId = $WorkspaceMapping.new_id $Target_WorkspaceName = $WorkspaceMapping.new_name } catch { throw "Error while getting workspace metadata file `"$FileName_WorkspaceMapping`". `n$_" } } # === # Import User-Permissions of workspace (personal workspaces cannot be shared) # = if ($Target_WorkspaceId -ne 'me'){ try{ if ($null -ne $Target_WorkspaceId){ Import-BsgPbiWorkspaceUsers -Path_Workspace $Path_Workspace -Target_WorkspaceId $Target_WorkspaceId } } catch { throw "Error while getting workspace metadata file `"$FileName_WorkspaceMapping`". `n$_" } } # === # Get report and dataset metadata from file # = try{ # Check path if ((Test-Path $Path_Workspace) -eq $false){ throw "Path `"$Path_Workspace`" does not exist." } # Check mapping file if ((Test-Path $Path_ReportDatasetMapping) -eq $false){ throw "File does not exist is folder `"$Path_Workspace`"." } $DatasetReport_Mapping = Get-Content -Path $Path_ReportDatasetMapping | ConvertFrom-Json -ErrorAction Stop $NumberOfReportsWithSharedDataset = @($DatasetReport_Mapping | Where-Object {$_.restoreAction -eq 'Wait_UpdatePbiConnection'}).count } catch{ throw "Error while getting report-dataset mapping file `"$FileName_ReportDatasetMapping`". `n$_" } # === # 1. loop through reports, which own a dataset # = $DatasetReport_Mapping_WithDataset = $DatasetReport_Mapping | Where-Object {$_.isDatasetOwner -eq $true} Foreach ($mappingObject in $DatasetReport_Mapping_WithDataset) { # === # Import reports including datasets # = Import-BsgPbiReport -Target_WorkspaceId $Target_WorkspaceId -Source_ReportId $mappingObject.reportId -Path_Workspace $Path_Workspace -ErrorAction Stop } # === # 2. loop through reports, which do not have an own dataset # = $DatasetReport_Mapping_WithoutDataset = $DatasetReport_Mapping | Where-Object {$_.isDatasetOwner -eq $false} Foreach ($mappingObject in $DatasetReport_Mapping_WithoutDataset) { # === # Import reports # = Import-BsgPbiReport -Target_WorkspaceId $Target_WorkspaceId -Source_ReportId $mappingObject.reportId -Path_Workspace $Path_Workspace -ErrorAction Stop } # === # Loop through mapping file (again because new data was written in last step and better logging-readability) # = $DatasetReport_Mapping = Get-Content -Path $Path_ReportDatasetMapping | ConvertFrom-Json -ErrorAction Stop Foreach ($mappingObject in $DatasetReport_Mapping) { # === # Import DatasetMetadata # = if ($mappingObject.isDatasetOwner){ Import-BsgPbiDataset -Target_WorkspaceId $Target_WorkspaceId -Target_DatasetId $mappingObject.new_datasetId -Source_DatasetId $mappingObject.datasetId -Path_Workspace $Path_Workspace -ErrorAction Stop } } # === # TODO: Import Apps # ! Microsoft API does not exist at the moment. # = # === # Import Tenant Level Reports # = if ($ImportTenantLevelReports){ Import-BsgPbiReportsTenantLevel -Path $Path -PbiConnection $PbiLogin } else { if ($NumberOfReportsWithSharedDataset -eq 1){ Write-Host Write-Warning "$NumberOfReportsWithSharedDataset report need to wait for other workspaces to complete." Write-Host Write-PSFHostColor -Level Host -DefaultColor gray -String "<c='white'>Info</c>: The connection of the report is based on a dataset in another workspace." Write-PSFHostColor -Level Host -DefaultColor gray -String " The report is marked as <c='white'>restoreAction = 'Wait_UpdatePbiConnection'</c> in the mapping file." Write-PSFHostColor -Level Host -DefaultColor gray -String " Use '<c='white'>Import-BsgPbiReportsTenantLevel</c>...' to update this report after the restoration." } elseif ($NumberOfReportsWithSharedDataset -ge 2){ Write-Host Write-Warning "$NumberOfReportsWithSharedDataset reports need to wait for other workspaces to complete." Write-Host Write-PSFHostColor -Level Host -DefaultColor gray -String "<c='white'>Info</c>: The connections of these reports are based on datasets in other workspaces." Write-PSFHostColor -Level Host -DefaultColor gray -String " The reports are marked as <c='white'>restoreAction = 'Wait_UpdatePbiConnection'</c> in the mapping file." Write-PSFHostColor -Level Host -DefaultColor gray -String " Use '<c='white'>Import-BsgPbiReportsTenantLevel</c>...' to import these reports after all workspaces have been restored." } } # Info message Write-Host Write-PSFHostColor -Level Host -DefaultColor white -String "---------------------------------------------------------------------------------------------" Write-Host Write-PSFHostColor -Level Host -DefaultColor green -String " Workspace restored." Write-Host Write-PSFHostColor -Level Host -DefaultColor gray -String " Old name: <c='white'>$Source_WorkspaceName</c>" Write-PSFHostColor -Level Host -DefaultColor gray -String " New name: <c='white'>$Target_WorkspaceName</c>" Write-Host Write-PSFHostColor -Level Host -DefaultColor gray -String " Developed by <c='white'>BSGroup Data Analytics AG</c>" Write-PSFHostColor -Level Host -DefaultColor white -String "---------------------------------------------------------------------------------------------" Write-Host Write-Host } catch { Write-Host Stop-PSFFunction -Message "Could not completely restore workspace `"$Source_WorkspaceName`"." -EnableException $False -Errorrecord $_ return } } |