1263 字
6 分鐘
Azure SQL 怎麼一次備份全部 DB?PowerShell 自動匯出 bacpac
結論
這支腳本透過 DatabaseName 參數控制匯出範圍:有填值時只匯出指定 DB,空值時自動匯出整台 Azure SQL Server 下所有使用者 DB。
適合用在哪裡
- 想先測試單一 DB 匯出是否正常
- 想一次備份整台 Azure SQL Server 的所有使用者 DB
- 想把備份流程做成可重複執行的 PowerShell 腳本
- 想保留每次匯出結果與錯誤訊息,方便後續追查
流程步驟
1. 先定義參數與登入資訊
先準備 Azure 資源名稱、Storage 位置、SQL Admin 帳號,並加入 DatabaseName 參數。這個參數是整篇重點:空值代表全部 DB,有值代表單一指定 DB。接著輸入 SQL Admin 密碼,並抓出 Storage Account Key,後面匯出 bacpac 會用到。
# ===== 基本參數 =====$ResourceGroupName = "your-rg"$ServerName = "your-sql-server"$DatabaseName = "" # 空值 = 全部 DB;有值 = 指定單一 DB$StorageAccountName = "yourstorageacct"$ContainerName = "sql-backup"$SqlAdminLogin = "your_sql_admin"
# 會跳出輸入框,請輸入 Azure SQL admin 密碼$SqlAdminPassword = Read-Host "Enter Azure SQL admin password" -AsSecureString
# 取得 Storage Account Key$StorageKey = (Get-AzStorageAccountKey ` -ResourceGroupName $ResourceGroupName ` -Name $StorageAccountName)[0].Value2. 依 DatabaseName 決定要跑哪些 DB
這一步只處理清單,不做匯出。若 DatabaseName 是空值,就抓整台 logical server 底下所有資料庫,並排除 master;若有值,就只建立單一 DB 清單。這樣後面的匯出流程可共用,不必寫兩份腳本。
if ([string]::IsNullOrWhiteSpace($DatabaseName)) { # 抓出此 logical server 底下的資料庫,排除 master $databases = Get-AzSqlDatabase ` -ResourceGroupName $ResourceGroupName ` -ServerName $ServerName | Where-Object { $_.DatabaseName -ne "master" }}else { # 若有指定 DB,則只建立單一清單 $databases = @( [PSCustomObject]@{ DatabaseName = $DatabaseName } )}3. 逐一匯出 bacpac 到 Blob Storage
每個 DB 都加上時間戳記,避免同名檔被覆蓋。接著呼叫 New-AzSqlDatabaseExport 送出匯出請求,把 bacpac 寫到指定的 Blob Container。這段是核心,也是最實用的一段。
# 建立結果紀錄$results = @()
foreach ($db in $databases) { $CurrentDatabaseName = $db.DatabaseName $TimeStamp = Get-Date -Format "yyyyMMdd-HHmmss" $BacpacFileName = "$CurrentDatabaseName-$TimeStamp.bacpac" $StorageUri = "<https://$StorageAccountName.blob.core.windows.net/$ContainerName/$BacpacFileName>"
Write-Host "Starting export for $CurrentDatabaseName ..."
try { $exportRequest = New-AzSqlDatabaseExport ` -ResourceGroupName $ResourceGroupName ` -ServerName $ServerName ` -DatabaseName $CurrentDatabaseName ` -StorageKeyType "StorageAccessKey" ` -StorageKey $StorageKey ` -StorageUri $StorageUri ` -AdministratorLogin $SqlAdminLogin ` -AdministratorLoginPassword $SqlAdminPassword4. 持續查詢狀態並整理結果
匯出不是同步完成,所以要用 Get-AzSqlDatabaseImportExportStatus 輪詢狀態。完成後把每個 DB 的狀態、輸出位置與錯誤訊息收進結果表,最後統一輸出。這樣就不會只看到某個 DB 卡住,卻不知道其他 DB 的情況。
# 輪詢匯出狀態 do { Start-Sleep -Seconds 15 $status = Get-AzSqlDatabaseImportExportStatus ` -OperationStatusLink $exportRequest.OperationStatusLink
Write-Host "$CurrentDatabaseName => $($status.Status)" } while ($status.Status -eq "InProgress")
$results += [PSCustomObject]@{ DatabaseName = $CurrentDatabaseName Status = $status.Status StorageUri = $StorageUri ErrorMessage = $status.ErrorMessage } } catch { $results += [PSCustomObject]@{ DatabaseName = $CurrentDatabaseName Status = "Failed" StorageUri = $StorageUri ErrorMessage = $_.Exception.Message } }}
$results | Format-Table -AutoSize補充
master建議直接排除,通常沒有備份成 bacpac 的實際價值- 建議用
$CurrentDatabaseName,不要在foreach裡覆蓋原始$DatabaseName參數,後續比較不會亂 - 若遇到 schema 不支援、跨 DB 參照、外部物件等問題,匯出失敗多半是 bacpac 限制,不是 PowerShell 語法錯
指令 / 範例整理
Click to expand
# 安裝 Az PowerShell 模組Install-Module -Name Az -Scope CurrentUser
# 匯入 Az 模組Import-Module Az
# 登入 AzureConnect-AzAccount
# ===== 基本參數 =====$ResourceGroupName = "your-rg"$ServerName = "your-sql-server"$DatabaseName = "" # 空值 = 全部 DB;有值 = 指定單一 DB$StorageAccountName = "yourstorageacct"$ContainerName = "sql-backup"$SqlAdminLogin = "your_sql_admin"
# 會跳出輸入框,請輸入 Azure SQL admin 密碼$SqlAdminPassword = Read-Host "Enter Azure SQL admin password" -AsSecureString
# 取得 Storage Account Key$StorageKey = (Get-AzStorageAccountKey ` -ResourceGroupName $ResourceGroupName ` -Name $StorageAccountName)[0].Value
# 抓取 DB 清單:空值 = 全部 DB;有值 = 單一 DBif ([string]::IsNullOrWhiteSpace($DatabaseName)) { $databases = Get-AzSqlDatabase ` -ResourceGroupName $ResourceGroupName ` -ServerName $ServerName | Where-Object { $_.DatabaseName -ne "master" }}else { $databases = @( [PSCustomObject]@{ DatabaseName = $DatabaseName } )}
# 建立結果紀錄$results = @()
foreach ($db in $databases) { $CurrentDatabaseName = $db.DatabaseName $TimeStamp = Get-Date -Format "yyyyMMdd-HHmmss" $BacpacFileName = "$CurrentDatabaseName-$TimeStamp.bacpac" $StorageUri = "<https://$StorageAccountName.blob.core.windows.net/$ContainerName/$BacpacFileName>"
Write-Host "Starting export for $CurrentDatabaseName ..."
try { $exportRequest = New-AzSqlDatabaseExport ` -ResourceGroupName $ResourceGroupName ` -ServerName $ServerName ` -DatabaseName $CurrentDatabaseName ` -StorageKeyType "StorageAccessKey" ` -StorageKey $StorageKey ` -StorageUri $StorageUri ` -AdministratorLogin $SqlAdminLogin ` -AdministratorLoginPassword $SqlAdminPassword
# 輪詢匯出狀態 do { Start-Sleep -Seconds 15 $status = Get-AzSqlDatabaseImportExportStatus ` -OperationStatusLink $exportRequest.OperationStatusLink
Write-Host "$CurrentDatabaseName => $($status.Status)" } while ($status.Status -eq "InProgress")
$results += [PSCustomObject]@{ DatabaseName = $CurrentDatabaseName Status = $status.Status StorageUri = $StorageUri ErrorMessage = $status.ErrorMessage } } catch { $results += [PSCustomObject]@{ DatabaseName = $CurrentDatabaseName Status = "Failed" StorageUri = $StorageUri ErrorMessage = $_.Exception.Message } }}
# 顯示結果$results | Format-Table -AutoSize
# ===== 補充查詢 / 驗證指令 =====
# 查詢某台 SQL Server 底下所有 DBGet-AzSqlDatabase ` -ResourceGroupName "your-rg" ` -ServerName "your-sql-server"
# 查詢指定 DBGet-AzSqlDatabase ` -ResourceGroupName "your-rg" ` -ServerName "your-sql-server" ` -DatabaseName "your-db-name"
# 查詢 Storage Account KeyGet-AzStorageAccountKey ` -ResourceGroupName "your-rg" ` -Name "yourstorageacct"
# 建立 Storage Context$ctx = New-AzStorageContext ` -StorageAccountName "yourstorageacct" ` -StorageAccountKey "your-storage-key"
# 查詢 Blob Container 是否存在Get-AzStorageContainer ` -Name "sql-backup" ` -Context $ctx
# 建立 Blob ContainerNew-AzStorageContainer ` -Name "sql-backup" ` -Context $ctx
# 手動測試單一 DB 匯出$DatabaseName = "appdb"
# 手動切換成匯出全部 DB$DatabaseName = ""
# 手動查某次匯出狀態Get-AzSqlDatabaseImportExportStatus ` -OperationStatusLink "貼上 OperationStatusLink"
# 查看匯出後的 bacpac 檔案Get-AzStorageBlob ` -Container "sql-backup" ` -Context $ctx收尾
這版不是多高深,就是把該放一起的指令一次收齊;之後你要單檔測試、全站備份、接排程,都比較不會再來回補洞。
Azure SQL 怎麼一次備份全部 DB?PowerShell 自動匯出 bacpac
https://joyceowo.github.io/posts/33ca78ea09fa80d9bce3ec7e370c08b7/