Public/Tasks/Invoke-SqlBackupWaitTask.ps1

#Requires -Modules SitecoreInstallFramework, SitecoreFundamentals, SqlServer

Set-StrictMode -Version Latest

Write-Verbose "Loading $($MyInvocation.MyCommand.Path)"

Function Invoke-SqlBackupWaitTask {
    [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")]
    [CmdletBinding(SupportsShouldProcess = $true)]
    param
    (
        [Parameter(Mandatory = $true)]
        [string]$SqlServer,
        [Parameter(Mandatory = $true)]
        [string[]]$SqlDatabases,
        [Parameter(Mandatory = $true)]
        [string]$SqlAdminUser,
        [Parameter(Mandatory = $true)]
        [string]$SqlAdminPassword,
        [int]$MaxWaitSeconds = 60,
        [string]$TaskName = "SqlBackupWait"
    )

    Set-PSDebug -Strict

    function Test-SqlDatabaseBackup {

        param
        (
            [Parameter(Mandatory = $true)]
            [string]$SqlServer,
            [Parameter(Mandatory = $true)]
            [string]$SqlDatabase,
            [Parameter(Mandatory = $true)]
            [string]$SqlAdminUser,
            [Parameter(Mandatory = $true)]
            [string]$SqlAdminPassword
        )

        $cmdCheckDb = @"
        IF EXISTS (SELECT * FROM master.dbo.sysprocesses WHERE dbid = db_id(N'$($SqlDatabase)')
        AND cmd LIKE 'BACKUP DATABASE%')
        BEGIN
            SELECT 1 as result
        END
        ELSE
        BEGIN
            SELECT 0 as result
        END
"@


        try {
            $cmdresult = Invoke-Sqlcmd -ServerInstance $SqlServer -Database master -Username $SqlAdminUser -Password $SqlAdminPassword -Query $cmdCheckDb -ErrorAction Stop
            $resultvalue = $false

            if ($cmdresult.result -eq 1) {
                $resultValue = $true
            }

            $result = New-Object PSCustomObject -Property @{
                "result" = $resultvalue
            }
        }
        catch {
            $result = New-Object PSCustomObject -Property @{
                "result" = $false
            }
        }

        return $result.result

    }

    function WaitSqlDatabaseBackup {
        [CmdletBinding(SupportsShouldProcess = $true)]
        param
        (
            [Parameter(Mandatory = $true)]
            [string]$SqlServer,
            [Parameter(Mandatory = $true)]
            [string]$SqlDatabase,
            [Parameter(Mandatory = $true)]
            [string]$SqlAdminUser,
            [Parameter(Mandatory = $true)]
            [string]$SqlAdminPassword,
            [int]$MaxWaitSeconds = 300
        )

        if ($PSCmdlet.ShouldProcess($SqlDatabase)) {

            $TimeStart = Get-Date
            $TimeEnd = $timeStart.AddSeconds($MaxWaitSeconds)

            $dbBackupRunning = Test-SqlDatabaseBackup -SqlServer $SqlServer -SqlDatabase $SqlDatabase -SqlAdminUser $SqlAdminUser -SqlAdminPassword $SqlAdminPassword

            if ($dbBackupRunning) {
                do {
                    $TimeRemaining = (New-TimeSpan -Start (Get-Date) -End $TimeEnd).Seconds
                    Write-TaskInfo "Backup running on database [$SqlDatabase]. Waiting for $TimeRemaining seconds." -Tag Wait -TaskName $TaskName

                    Start-Sleep -Seconds 3
                    $dbBackupRunning = Test-SqlDatabaseBackup -SqlServer $SqlServer -SqlDatabase $SqlDatabase -SqlAdminUser $SqlAdminUser -SqlAdminPassword $SqlAdminPassword

                } while ($dbBackupRunning -and ((Get-Date) -lt $TimeEnd))

            } else {
                Write-TaskInfo "Backup is not currently running on database [$SqlDatabase]." -Tag Wait -TaskName $TaskName
            }

        }
    }

    foreach ($SqlDatabase in $SqlDatabases) {
        WaitSqlDatabaseBackup $SqlServer $SqlDatabase $SqlAdminUser $SqlAdminPassword $MaxWaitSeconds
    }

}

Register-SitecoreInstallExtension -Command Invoke-SqlBackupWaitTask -As SqlBackupWait -Type Task #-Force

Write-Verbose "Loaded $($MyInvocation.MyCommand.Path)"