PSFabricTools.psm1

#Region './Private/Get-PSFabricUri.ps1' -1

<#
.SYNOPSIS
Internal function to connect to Fabric and setup the uri and headers for commands.

.DESCRIPTION
Internal function to connect to Fabric and setup the uri and headers for commands.

Requires the Workspace and DataWarehouse GUIDs to connect to.

.PARAMETER BaseUrl
Defaults to api.powerbi.com

.PARAMETER WorkspaceGUID
This is the workspace GUID in which the data warehouse resides.

.PARAMETER DataWarehouseGUID
The GUID for the data warehouse which we want to retrieve restore points for.

.PARAMETER BatchId
The BatchId to use for the request. If this is set then the batches endpoint will be used.

.EXAMPLE
Get-PSFabricUri -WorkspaceGUID 'GUID-GUID-GUID-GUID' -DataWarehouseGUID 'GUID-GUID-GUID-GUID'

Connects to the specified Fabric Data Warehouse and sets up the headers and uri for future commands.

.EXAMPLE
Get-PSFabricUri -WorkspaceGUID 'GUID-GUID-GUID-GUID' -DataWarehouseGUID 'GUID-GUID-GUID-GUID' -BatchId 'GUID-GUID-GUID-GUID'

Connects to the specified Fabric Data Warehouse and sets up the headers and uri for checking the progress of an operation with a specific batchId.

#>

function Get-PSFabricUri {
    param (
        $BaseUrl = 'api.powerbi.com',
        [parameter(Mandatory)]
        [String]$WorkspaceGUID,
        [parameter(Mandatory)]
        [String]$DataWarehouseGUID,

        [String]$BatchId
    )

    try {
        $headers = Get-PowerBIAccessToken
    } catch {
        try {
            Stop-PSFFunction -Message ('Not able to get a token - execute Connect-PowerBIServiceAccount manually first') -EnableException
            # Write-PSFMessage -Level Warning -Message ('Not able to get a token - will execute Connect-PowerBIServiceAccount')
            #TODO: This doesn't work the first time - is it waiting for response?
            # $conn = Connect-PowerBIServiceAccount
            # if($conn) {
            # Write-PSFMessage -Level Info -Message ('Successfully connected to PowerBI')
            # }
        } catch {
            throw 'Not able to get a token - manually try and run Connect-PowerBIServiceAccount'
        }
    }

    if($BatchId) {
        $Uri = ('https://{0}/v1.0/myorg/groups/{1}/datawarehouses/{2}/batches/{3}' -f $baseurl, $workspaceGUID, $dataWarehouseGUID, $BatchId)
        $method = 'Get'
    } else {
        $Uri = ('https://{0}/v1.0/myorg/groups/{1}/datawarehouses/{2}/' -f $baseurl, $workspaceGUID, $dataWarehouseGUID)
        $method = 'Post'
    }

    return @{
        Uri = $Uri
        Headers = $headers
        Method = $method
        ContentType = 'application/json'
    }
    #TODO: Change this to be a saved config property?
}
#EndRegion './Private/Get-PSFabricUri.ps1' 76
#Region './Public/Get-PSFabricConfig.ps1' -1

<#
.SYNOPSIS
Gets the configuration for use with all functions in the PSFabricTools module.

.DESCRIPTION
Gets the configuration for use with all functions in the PSFabricTools module.

.PARAMETER ConfigName
The name of the configuration to retrieve.

.EXAMPLE
PS> Get-PSFabricConfig

Gets all the configuration values for the PSFabricTools module and outputs them

.EXAMPLE
PS> Get-PSFabricConfig -ConfigName BaseUrl

Gets the BaseUrl configuration value for the PSFabricTools module.
#>


function Get-PSFabricConfig {
    param (
        [String]$ConfigName
    )

    if ($ConfigName) {
        Get-PSFConfig -Module PSFabricTools -Name $ConfigName
    } else {
        Get-PSFConfig -Module PSFabricTools
    }
}
#EndRegion './Public/Get-PSFabricConfig.ps1' 33
#Region './Public/Get-PSFabricRecoveryPoint.ps1' -1

<#
.SYNOPSIS
Get a list of Fabric recovery points.

.DESCRIPTION
Get a list of Fabric recovery points. Results can be filter by date or type.

.PARAMETER BaseUrl
Defaults to api.powerbi.com

.PARAMETER WorkspaceGUID
This is the workspace GUID in which the data warehouse resides.

.PARAMETER DataWarehouseGUID
The GUID for the data warehouse which we want to retrieve restore points for.

.PARAMETER Since
Filter the results to only include restore points created after this date.

.PARAMETER Type
Filter the results to only include restore points of this type.

.PARAMETER CreateTime
The specific unique time of the restore point to remove. Get this from Get-PSFabricRecoveryPoint.

.EXAMPLE
PS> Get-PSFabricRecoveryPoint -WorkspaceGUID 'GUID-GUID-GUID-GUID' -DataWarehouseGUID 'GUID-GUID-GUID-GUID'

Gets all the available recovery points for the specified data warehouse, in the specified workspace.

.NOTES
Based on API calls from this blog post: https://blog.fabric.microsoft.com/en-US/blog/the-art-of-data-warehouse-recovery-within-microsoft-fabric/

#>


function Get-PSFabricRecoveryPoint {
    param (
        [String]$WorkspaceGUID,

        [String]$DataWarehouseGUID,

        [String]$BaseUrl = 'api.powerbi.com',

        [DateTime]$Since,

        [ValidateSet("automatic", "userDefined")]
        [string]$Type,
        #TODO: accept a list of times
        [string]$CreateTime

    )

    #region handle the config parameters
    if(-not $WorkspaceGUID) {
        $WorkspaceGUID = Get-PSFConfigValue -FullName PSFabricTools.WorkspaceGUID
    }

    if(-not $DataWarehouseGUID) {
        $DataWarehouseGUID = Get-PSFConfigValue -FullName PSFabricTools.DataWarehouseGUID
    }

    if(-not $BaseUrl) {
        $BaseUrl = Get-PSFConfigValue -FullName PSFabricTools.BaseUrl
    }

    if (-not $WorkspaceGUID -or -not $DataWarehouseGUID -or -not $BaseUrl) {
        Stop-PSFFunction -Message 'WorkspaceGUID, DataWarehouseGUID, and BaseUrl are required parameters. Either set them with Set-PSFabricConfig or pass them in as parameter values' -EnableException $true
    } else {
        Write-PSFMessage -Level Verbose -Message ('WorkspaceGUID: {0}; DataWarehouseGUID: {1}; BaseUrl: {2}' -f $WorkspaceGUID, $DataWarehouseGUID, $BaseUrl)
    }
    #endregion

    #region setting up the API call
    try {
        # Get token and setup the uri
        $getUriParam = @{
            BaseUrl = $BaseUrl
            WorkspaceGUID = $WorkspaceGUID
            DataWarehouseGUID = $DataWarehouseGUID
        }
        $iwr = Get-PSFabricUri @getUriParam
    } catch {
        Stop-PSFFunction -Message 'Failed to get Fabric URI - check authentication and parameters.' -ErrorRecord $_ -EnableException $true
    }
    #endregion

    #region call the API
    if (-not $iwr) {
        Stop-PSFFunction -Message 'No URI received from API - check authentication and parameters.' -ErrorRecord $_ -EnableException $true
    } else {

        # set the body to list restore points
        $command = [PSCustomObject]@{
            Commands = @(@{
                '$type' = 'WarehouseListRestorePointsCommand'
            })
        }

        try {
            # add the body and invoke
            $iwr.Add('Body', ($command | ConvertTo-Json -Compress))
            $content = Invoke-WebRequest @iwr

            if($content) {
                # change output to be a PowerShell object and view restore points
                $restorePoints = ($content.Content | ConvertFrom-Json).operationInformation.progressDetail.restorePoints

                if($CreateTime) {
                    $restorePoints = $restorePoints | Select-Object @{l='createTimeWhere';e={get-date($_.createTime) -Format 'yyyy-MM-ddTHH:mm:ssZ'}}, *  | Where-Object createTimeWhere -eq $createTime
                }

                if($Since) {
                    $restorePoints = $restorePoints | Where-Object { $_.createTime -gt $Since }
                }

                if($Type) {
                    $restorePoints = $restorePoints | Where-Object { $_.createMode -eq $Type }
                }

                $restorePoints | Select-Object @{l='createTime';e={get-date($_.createTime) -Format 'yyyy-MM-ddTHH:mm:ssZ'}}, @{l='friendlyCreateTime';e={$_.createTime}}, label, createMode, type, createdByUserObjectId | Sort-Object createTime
                #TODO: default view rather than select\sort?
            } else {
                Stop-PSFFunction -Message 'No Content received from API - check authentication and parameters.' -ErrorRecord $_ -EnableException $true
            }
        } catch {
            Stop-PSFFunction -Message 'Issue calling Invoke-WebRequest' -ErrorRecord $_ -EnableException $true
        }
    }
    #endregion
}
#EndRegion './Public/Get-PSFabricRecoveryPoint.ps1' 131
#Region './Public/New-PSFabricRecoveryPoint.ps1' -1

<#
.SYNOPSIS
Create a recovery point for a Fabric data warehouse

.DESCRIPTION
Create a recovery point for a Fabric data warehouse

.PARAMETER BaseUrl
Defaults to api.powerbi.com

.PARAMETER WorkspaceGUID
This is the workspace GUID in which the data warehouse resides.

.PARAMETER DataWarehouseGUID
The GUID for the data warehouse which we want to retrieve restore points for.

.EXAMPLE
PS> New-PSFabricRecoveryPoint

Create a new recovery point for the data warehouse specified in the configuration.

.EXAMPLE
PS> New-PSFabricRecoveryPoint -WorkspaceGUID 'GUID-GUID-GUID-GUID' -DataWarehouseGUID 'GUID-GUID-GUID-GUID'

Create a new recovery point for the specified data warehouse, in the specified workspace.

#>

function New-PSFabricRecoveryPoint {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [String]$WorkspaceGUID,

        [String]$DataWarehouseGUID,

        [String]$BaseUrl = 'api.powerbi.com'
    )

    #region handle the config parameters
    if(-not $WorkspaceGUID) {
        $WorkspaceGUID = Get-PSFConfigValue -FullName PSFabricTools.WorkspaceGUID
    }

    if(-not $DataWarehouseGUID) {
        $DataWarehouseGUID = Get-PSFConfigValue -FullName PSFabricTools.DataWarehouseGUID
    }

    if(-not $BaseUrl) {
        $BaseUrl = Get-PSFConfigValue -FullName PSFabricTools.BaseUrl
    }

    if (-not $WorkspaceGUID -or -not $DataWarehouseGUID -or -not $BaseUrl) {
        Stop-PSFFunction -Message 'WorkspaceGUID, DataWarehouseGUID, and BaseUrl are required parameters. Either set them with Set-PSFabricConfig or pass them in as parameter values' -EnableException $true
    } else {
        Write-PSFMessage -Level Verbose -Message ('WorkspaceGUID: {0}; DataWarehouseGUID: {1}; BaseUrl: {2}' -f $WorkspaceGUID, $DataWarehouseGUID, $BaseUrl)
    }
    #endregion

    if ($PSCmdlet.ShouldProcess("Create a recovery point for a Fabric Data Warehouse")) {
        #region setting up the API call
        try {
            # Get token and setup the uri
            $getUriParam = @{
                BaseUrl = $BaseUrl
                WorkspaceGUID = $WorkspaceGUID
                DataWarehouseGUID = $DataWarehouseGUID
            }
            $iwr = Get-PSFabricUri @getUriParam
        } catch {
            Stop-PSFFunction -Message 'Failed to get Fabric URI - check authentication and parameters.' -ErrorRecord $_ -EnableException $true
        }
        #endregion

        #region call the API
        if (-not $iwr) {
            Stop-PSFFunction -Message 'No URI received from API - check authentication and parameters.' -ErrorRecord $_ -EnableException $true
        } else {
            $command = [PSCustomObject]@{
                Commands = @(@{
                    '$type' = 'WarehouseCreateRestorePointCommand'
                })
            }

            try {
                # add the body and invoke
                $iwr.Add('Body', ($command | ConvertTo-Json -Compress))
                $content = Invoke-WebRequest @iwr

                if($content) {
                    # change output to be a PowerShell object and view new restore point
                    #TODO: output - select default view but return more?
                    ($content.Content | ConvertFrom-Json) | Select-Object progressState,@{l='type';e={$_.operationInformation.progressDetail.restorePoint.type}},@{l='createTime';e={get-date($_.operationInformation.progressDetail.restorePoint.createTime) -format 'yyyy-MM-ddTHH:mm:ssZ'}},@{l='friendlyCreateTime';e={$_.operationInformation.progressDetail.restorePoint.createTime}}, @{l='label';e={$_.operationInformation.progressDetail.restorePoint.label}}, @{l='createMode';e={$_.operationInformation.progressDetail.restorePoint.createMode}}, @{l='description';e={$_.operationInformation.progressDetail.restorePoint.description}}, @{l='createdByUserObjectId';e={$_.operationInformation.progressDetail.restorePoint.createdByUserObjectId}}, @{l='lastModifiedByUserObjectId';e={$_.operationInformation.progressDetail.restorePoint.lastModifiedByUserObjectId}}, @{l='lastModifiedTime';e={$_.operationInformation.progressDetail.restorePoint.lastModifiedTime}}
                } else {
                    Stop-PSFFunction -Message 'No Content received from API - check authentication and parameters.' -ErrorRecord $_ -EnableException $true
                }
            } catch {
                Stop-PSFFunction -Message 'Issue calling Invoke-WebRequest' -ErrorRecord $_ -EnableException $true
            }
        }
        #endregion
    }
}
#EndRegion './Public/New-PSFabricRecoveryPoint.ps1' 102
#Region './Public/Remove-PSFabricRecoveryPoint.ps1' -1

<#
.SYNOPSIS
Remove a selected Fabric Recovery Point.

.DESCRIPTION
Remove a selected Fabric Recovery Point.

.PARAMETER CreateTime
The specific unique time of the restore point to remove. Get this from Get-PSFabricRecoveryPoint.

.PARAMETER BaseUrl
Defaults to api.powerbi.com

.PARAMETER WorkspaceGUID
This is the workspace GUID in which the data warehouse resides.

.PARAMETER DataWarehouseGUID
The GUID for the data warehouse which we want to retrieve restore points for.

.EXAMPLE
PS> Remove-PSFabricRecoveryPoint -CreateTime '2024-07-23T11:20:26Z'

Remove a specific restore point from a Fabric Data Warehouse that has been set using Set-PSFabricConfig.

.EXAMPLE
PS> Remove-PSFabricRecoveryPoint -CreateTime '2024-07-23T11:20:26Z' -WorkspaceGUID 'GUID-GUID-GUID-GUID' -DataWarehouseGUID 'GUID-GUID-GUID-GUID'

Remove a specific restore point from a Fabric Data Warehouse, specifying the workspace and data warehouse GUIDs.

.NOTES
General notes
#>

function Remove-PSFabricRecoveryPoint {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$CreateTime,

        [String]$WorkspaceGUID,

        [String]$DataWarehouseGUID,

        [String]$BaseUrl = 'api.powerbi.com'

        #TODO - implement piping from get? or a way of interactively choosing points to remove
        )

    #region handle the config parameters
    if(-not $WorkspaceGUID) {
        $WorkspaceGUID = Get-PSFConfigValue -FullName PSFabricTools.WorkspaceGUID
    }

    if(-not $DataWarehouseGUID) {
        $DataWarehouseGUID = Get-PSFConfigValue -FullName PSFabricTools.DataWarehouseGUID
    }

    if(-not $BaseUrl) {
        $BaseUrl = Get-PSFConfigValue -FullName PSFabricTools.BaseUrl
    }

    if (-not $WorkspaceGUID -or -not $DataWarehouseGUID -or -not $BaseUrl) {
        Stop-PSFFunction -Message 'WorkspaceGUID, DataWarehouseGUID, and BaseUrl are required parameters. Either set them with Set-PSFabricConfig or pass them in as parameter values' -EnableException $true
    } else {
        Write-PSFMessage -Level Verbose -Message ('WorkspaceGUID: {0}; DataWarehouseGUID: {1}; BaseUrl: {2}' -f $WorkspaceGUID, $DataWarehouseGUID, $BaseUrl)
    }
    #endregion

    if ($PSCmdlet.ShouldProcess("Remove recovery point for a Fabric Data Warehouse")) {
        #region setting up the API call
        try {
            # Get token and setup the uri
            $getUriParam = @{
                BaseUrl = $BaseUrl
                WorkspaceGUID = $WorkspaceGUID
                DataWarehouseGUID = $DataWarehouseGUID
            }
            $iwr = Get-PSFabricUri @getUriParam
        } catch {
            Stop-PSFFunction -Message 'Failed to get Fabric URI - check authentication and parameters.' -ErrorRecord $_ -EnableException $true
        }
        #endregion

        #region call the API
        if (-not $iwr) {
            Stop-PSFFunction -Message 'No URI received from API - check authentication and parameters.' -ErrorRecord $_ -EnableException $true
        } else {

            # for the API this needs to be an array, even if it's just one item
            [string[]]$CreateTimeObj = $CreateTime

            #region check restore point exists
            #Get the restore point to make sure it exists - the fabric API doesn't really confirm we deleted anything so we will manually check
            $getSplat = @{
                WorkspaceGUID = $WorkspaceGUID
                DataWarehouseGUID = $DataWarehouseGUID
                BaseUrl = $BaseUrl
                CreateTime = $CreateTimeObj
            }

            try {
                if(Get-PSFabricRecoveryPoint @getSplat) {
                    Write-PSFMessage -Level Verbose -Message ('WorkspaceGUID: {0}; DataWarehouseGUID: {1}; BaseUrl: {2}; CreateTime: {3} - restore point exists' -f $WorkspaceGUID, $DataWarehouseGUID, $BaseUrl, $CreateTime)
                } else {
                    Stop-PSFFunction -Message ('WorkspaceGUID: {0}; DataWarehouseGUID: {1}; BaseUrl: {2}; CreateTime: {3} - restore point not found!' -f $WorkspaceGUID, $DataWarehouseGUID, $BaseUrl, $CreateTime) -ErrorRecord $_ -EnableException $true
                }
            } catch {
                Stop-PSFFunction -Message 'Issue calling Get-PSFabricRecoveryPoint to check restore point exists before removal' -ErrorRecord $_ -EnableException $true
            }
            #endregion

            #region remove the restore point
            $command = [PSCustomObject]@{
                commands = @([ordered]@{
                    '$type' = 'WarehouseDeleteRestorePointsCommand'
                    'RestorePointsToDelete' = $CreateTimeObj
                })
            }

            try {
                # add the body and invoke
                $iwr.Add('Body', ($command | ConvertTo-Json -Compress -Depth 3))
                $content = Invoke-WebRequest @iwr

                if($content) {
                    # change output to be a PowerShell object and view new restore point
                    #TODO: output - select default view but return more?
                    $results = ($content.Content | ConvertFrom-Json)
                } else {
                    Stop-PSFFunction -Message 'No Content received from API - check authentication and parameters.' -ErrorRecord $_ -EnableException $true
                }
            } catch {
                Stop-PSFFunction -Message 'Issue calling Invoke-WebRequest' -ErrorRecord $_ -EnableException $true
            }
            #endregion

            #region check restore point exists
            try {
                #Get the restore point to make sure it exists - the fabric API doesn't really confirm we deleted anything so we will manually check
                if(Get-PSFabricRecoveryPoint @getSplat) {
                    Stop-PSFFunction -Message ('WorkspaceGUID: {0}; DataWarehouseGUID: {1}; BaseUrl: {2}; CreateTime: {3} - restore point not was not successfully removed!' -f $WorkspaceGUID, $DataWarehouseGUID, $BaseUrl, $CreateTime) -ErrorRecord $_ -EnableException $true
                } else {
                    Write-PSFMessage -Level Output -Message ('WorkspaceGUID: {0}; DataWarehouseGUID: {1}; BaseUrl: {2}; CreateTime: {3} - restore point successfully removed' -f $WorkspaceGUID, $DataWarehouseGUID, $BaseUrl, $CreateTime)
                    $results
                }
            } catch {
                Stop-PSFFunction -Message 'Issue calling Get-PSFabricRecoveryPoint to check restore point exists before removal' -ErrorRecord $_ -EnableException $true
            }
            #endregion
        }
        #endregion
    }
}
#EndRegion './Public/Remove-PSFabricRecoveryPoint.ps1' 152
#Region './Public/Restore-PSFabricRecoveryPoint.ps1' -1

<#
.SYNOPSIS
Restore a Fabric data warehouse to a specified restore pont.

.DESCRIPTION
Restore a Fabric data warehouse to a specified restore pont.

.PARAMETER CreateTime
The specific unique time of the restore point to remove. Get this from Get-PSFabricRecoveryPoint.

.PARAMETER BaseUrl
Defaults to api.powerbi.com

.PARAMETER WorkspaceGUID
This is the workspace GUID in which the data warehouse resides.

.PARAMETER DataWarehouseGUID
The GUID for the data warehouse which we want to retrieve restore points for.

.PARAMETER Wait
Wait for the restore to complete before returning.

.EXAMPLE
PS> Restore-PSFabricRecoveryPoint -CreateTime '2024-07-23T11:20:26Z'

Restore a Fabric Data Warehouse to a specific restore point that has been set using Set-PSFabricConfig.

.EXAMPLE
PS> Restore-PSFabricRecoveryPoint -CreateTime '2024-07-23T11:20:26Z' -WorkspaceGUID 'GUID-GUID-GUID-GUID' -DataWarehouseGUID 'GUID-GUID-GUID-GUID'

Restore a Fabric Data Warehouse to a specific restore point, specifying the workspace and data warehouse GUIDs.

#>

function Restore-PSFabricRecoveryPoint {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [string]$CreateTime,

        [String]$WorkspaceGUID,

        [String]$DataWarehouseGUID,

        [String]$BaseUrl = 'api.powerbi.com',

        [switch]$Wait

    )

    #region handle the config parameters
    if(-not $WorkspaceGUID) {
        $WorkspaceGUID = Get-PSFConfigValue -FullName PSFabricTools.WorkspaceGUID
    }

    if(-not $DataWarehouseGUID) {
        $DataWarehouseGUID = Get-PSFConfigValue -FullName PSFabricTools.DataWarehouseGUID
    }

    if(-not $BaseUrl) {
        $BaseUrl = Get-PSFConfigValue -FullName PSFabricTools.BaseUrl
    }

    if (-not $WorkspaceGUID -or -not $DataWarehouseGUID -or -not $BaseUrl) {
        Stop-PSFFunction -Message 'WorkspaceGUID, DataWarehouseGUID, and BaseUrl are required parameters. Either set them with Set-PSFabricConfig or pass them in as parameter values' -EnableException $true
    } else {
        Write-PSFMessage -Level Verbose -Message ('WorkspaceGUID: {0}; DataWarehouseGUID: {1}; BaseUrl: {2}' -f $WorkspaceGUID, $DataWarehouseGUID, $BaseUrl)
    }
    #endregion

    if ($PSCmdlet.ShouldProcess("Recover a Fabric Data Warehouse to a restore point")) {
        #region setting up the API call
        try {
            # Get token and setup the uri
            $getUriParam = @{
                BaseUrl = $BaseUrl
                WorkspaceGUID = $WorkspaceGUID
                DataWarehouseGUID = $DataWarehouseGUID
            }
            $iwr = Get-PSFabricUri @getUriParam
        } catch {
            Stop-PSFFunction -Message 'Failed to get Fabric URI - check authentication and parameters.' -ErrorRecord $_ -EnableException $true
        }
        #endregion

        #region call the API
        if (-not $iwr) {
            Stop-PSFFunction -Message 'No URI received from API - check authentication and parameters.' -ErrorRecord $_ -EnableException $true
        } else {

            #region check restore point exists
            #Get the restore point to make sure it exists before we try and restore to it
            $getSplat = @{
                WorkspaceGUID = $WorkspaceGUID
                DataWarehouseGUID = $DataWarehouseGUID
                BaseUrl = $BaseUrl
                CreateTime = $CreateTime
            }

            try {
                if(Get-PSFabricRecoveryPoint @getSplat) {
                    Write-PSFMessage -Level Verbose -Message ('WorkspaceGUID: {0}; DataWarehouseGUID: {1}; BaseUrl: {2}; CreateTime: {3} - restore point exists' -f $WorkspaceGUID, $DataWarehouseGUID, $BaseUrl, $CreateTime)
                } else {
                    Stop-PSFFunction -Message ('WorkspaceGUID: {0}; DataWarehouseGUID: {1}; BaseUrl: {2}; CreateTime: {3} - restore point not found!' -f $WorkspaceGUID, $DataWarehouseGUID, $BaseUrl, $CreateTime) -ErrorRecord $_ -EnableException $true
                }
            } catch {
                Stop-PSFFunction -Message 'Issue calling Get-PSFabricRecoveryPoint to check restore point exists before attempting recovery' -ErrorRecord $_ -EnableException $true
            }
            #endregion

            #region recover to the restore point
            # command is now WarehouseRestoreInPlaceCommand and the RestorePoint is the create time of the specific restore point to use
            $command = [PSCustomObject]@{
                commands = @([ordered]@{
                    '$type' = 'WarehouseRestoreInPlaceCommand'
                    'RestorePoint' = $CreateTime
                })
            }

            try {
                # add the body and invoke
                $iwr.Add('Body', ($command | ConvertTo-Json -Compress))
                $content = Invoke-WebRequest @iwr

                if($content) {
                    #TODO: output - select default view but return more?
                    $content = ($content.Content | ConvertFrom-Json)
                } else {
                    Stop-PSFFunction -Message 'No Content received from API - check authentication and parameters.' -ErrorRecord $_ -EnableException $true
                }
            } catch {
                Stop-PSFFunction -Message 'Issue calling Invoke-WebRequest' -ErrorRecord $_ -EnableException $true
            }
            #endregion

            #region check the progress of the restore
            if ($Wait) {
                # we need to append batches to the uri
                try {

                    while($Wait) {
                        # Get token and setup the uri
                        $getUriParam = @{
                            BaseUrl = $BaseUrl
                            WorkspaceGUID = $WorkspaceGUID
                            DataWarehouseGUID = $DataWarehouseGUID
                            BatchId = $content.batchId
                        }
                        $iwr = Get-PSFabricUri @getUriParam

                        $restoreProgress = ((Invoke-WebRequest @iwr).Content | ConvertFrom-Json)

                        if($restoreProgress.progressState -eq 'inProgress') {
                            Write-PSFMessage -Level Output -Message 'Restore in progress'
                        } elseif ($restoreProgress.progressState -eq 'success') {
                            Write-PSFMessage -Level Output -Message 'Restore completed successfully'
                            $restoreProgress | Select-Object progressState, @{l='startDateTimeUtc';e={$_.startTimeStamp }}, @{l='RestorePointCreateTime';e={$CreateTime }}
                            $wait = $false
                            break
                        } else {
                            Write-PSFMessage -Level Output -Message 'Restore failed'
                            $restoreProgress | Select-Object progressState, @{l='startDateTimeUtc';e={$_.startTimeStamp }}
                            $wait = $false
                            break
                        }

                        # wait a few seconds
                        Start-Sleep -Seconds 3
                    }
                } catch {
                    Stop-PSFFunction -Message 'Failed to get Fabric URI for the batchId - check authentication and parameters.' -ErrorRecord $_ -EnableException $true
                }

            } else {
                Write-PSFMessage -Level Output -Message 'Restore in progress - use the -Wait parameter to wait for restore to complete'
                $content
            }
        }
        #endregion
    }
}
#EndRegion './Public/Restore-PSFabricRecoveryPoint.ps1' 180
#Region './Public/Set-PSFabricConfig.ps1' -1

<#
.SYNOPSIS
Register the configuration for use with all functions in the PSFabricTools module.

.DESCRIPTION
Register the configuration for use with all functions in the PSFabricTools module.

.PARAMETER WorkspaceGUID
This is the workspace GUID in which the Data Warehouse resides.

.PARAMETER DataWarehouseGUID
The GUID for the Data Warehouse which we want to retrieve restore points for.

.PARAMETER BaseUrl
Defaults to api.powerbi.com

.PARAMETER SkipPersist
If set, the configuration will not be persisted to the registry.

.EXAMPLE
PS> Set-PSFabricConfig -WorkspaceGUID 'GUID-GUID-GUID-GUID' -DataWarehouseGUID 'GUID-GUID-GUID-GUID'

Registers the specified Fabric Data Warehouse configuration for use with all functions in the PSFabricTools module.

.EXAMPLE
PS> Set-PSFabricConfig -WorkspaceGUID 'GUID-GUID-GUID-GUID' -DataWarehouseGUID 'GUID-GUID-GUID-GUID' -SkipPersist

Registers the specified Fabric Data Warehouse configuration for use with all functions in the PSFabricTools module - but does not persist the values, only uses them for the current session.

#>


function Set-PSFabricConfig {
    [CmdletBinding(SupportsShouldProcess)]
    param (
        [String]$WorkspaceGUID,

        [String]$DataWarehouseGUID,

        $BaseUrl = 'api.powerbi.com',

        [switch]$SkipPersist
    )

    if ($PSCmdlet.ShouldProcess("Setting Fabric Configuration")) {

        if ($BaseUrl) {
            Set-PSFConfig -Module PSFabricTools -Name BaseUrl -Value $BaseUrl
        }
        if ($WorkspaceGUID) {
            Set-PSFConfig -Module PSFabricTools -Name WorkspaceGUID -Value $WorkspaceGUID
        }
        if ($DataWarehouseGUID) {
            Set-PSFConfig -Module PSFabricTools -Name DataWarehouseGUID -Value $DataWarehouseGUID
        }

        # Register the config values in the registry if skip persist is not set
        if (-not $SkipPersist) {
            Register-PSFConfig -Module PSFabricTools -Scope SystemMandatory
        }
    }
}
#EndRegion './Public/Set-PSFabricConfig.ps1' 62