1263 字
6 分鐘
瀏覽次數
Azure SQL 怎麼一次備份全部 DB?PowerShell 自動匯出 bacpac
2026-04-08
2026-04-13

結論#

這支腳本透過 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 會用到。

Terminal window
# ===== 基本參數 =====
$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

2. 依 DatabaseName 決定要跑哪些 DB#

這一步只處理清單,不做匯出。若 DatabaseName 是空值,就抓整台 logical server 底下所有資料庫,並排除 master;若有值,就只建立單一 DB 清單。這樣後面的匯出流程可共用,不必寫兩份腳本。

Terminal window
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。這段是核心,也是最實用的一段。

Terminal window
# 建立結果紀錄
$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

4. 持續查詢狀態並整理結果#

匯出不是同步完成,所以要用 Get-AzSqlDatabaseImportExportStatus 輪詢狀態。完成後把每個 DB 的狀態、輸出位置與錯誤訊息收進結果表,最後統一輸出。這樣就不會只看到某個 DB 卡住,卻不知道其他 DB 的情況。

Terminal window
# 輪詢匯出狀態
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
Terminal window
# 安裝 Az PowerShell 模組
Install-Module -Name Az -Scope CurrentUser
# 匯入 Az 模組
Import-Module Az
# 登入 Azure
Connect-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;有值 = 單一 DB
if ([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 底下所有 DB
Get-AzSqlDatabase `
-ResourceGroupName "your-rg" `
-ServerName "your-sql-server"
# 查詢指定 DB
Get-AzSqlDatabase `
-ResourceGroupName "your-rg" `
-ServerName "your-sql-server" `
-DatabaseName "your-db-name"
# 查詢 Storage Account Key
Get-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 Container
New-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/
作者
JoyceOwO
發佈於
2026-04-08
許可協議
CC BY-NC-SA 4.0