Azure VM 上的 BitLocker 開機錯誤
適用於:✔️ Windows VM
本文說明您在 Microsoft Azure 中啟動 Windows 虛擬機器 (VM) 時可能會遇到的 BitLocker 錯誤。
徵兆
Windows VM 不會啟動。 當您在開機診斷視窗中檢查螢幕快照時,您會看到下列其中一個錯誤訊息:
插入具有 BitLocker 金鑰的 USB 驅動程式
您已遭到鎖定! 輸入修復金鑰以再次執行 (鍵盤配置:US)。由於輸入錯誤登入資訊太多次,因此已將電腦鎖定以保護您的隱私權。 若要擷取修復金鑰,請從另一部電腦或行動裝置移至 https://windows.microsoft.com/recoverykeyfaq 。 如果您需要的話,金鑰標識碼為 XXXXXXXXX。 或者,您可以重設計算機。
輸入密碼以將此磁碟機 [ ] 解除鎖定。按 Insert 鍵可看到您輸入的密碼。
輸入修復金鑰。從 USB 裝置中載入修復金鑰。
原因
如果 VM 找不到 BitLocker 修復金鑰 (BEK) 檔案來解密加密的磁碟,就可能發生此問題。
解密加密的 OS 磁碟
提示
如果您有最近的 VM 備份,您可以嘗試 從備份 還原 VM,以修正開機問題。
若要解決此問題,請停止並解除分配 VM,然後加以啟動。 此作業會強制 VM 從 Azure 金鑰保存庫 擷取 BEK 檔案,然後將它放在加密的磁碟上。
如果此方法無法解決問題,請遵循下列步驟手動還原 BEK 檔案:
擷取受影響之 VM 的 OS 磁碟快照集作為備份。 如需詳細資訊,請參閱 快照集磁碟。
將 OS 磁碟連結至復原 VM。 當您鏈接受控磁碟時,您可能會收到「包含加密設定,因此無法做為數據磁碟」錯誤訊息。 在此情況下,請執行下列文稿以再試一次以連結磁碟:
$rgName = "myResourceGroup" $osDiskName = "ProblemOsDisk" # Set the EncryptionSettingsEnabled property to false, so you can attach the disk to the recovery VM. New-AzDiskUpdateConfig -EncryptionSettingsEnabled $false |Update-AzDisk -diskName $osDiskName -ResourceGroupName $rgName $recoveryVMName = "myRecoveryVM" $recoveryVMRG = "RecoveryVMRG" $OSDisk = Get-AzDisk -ResourceGroupName $rgName -DiskName $osDiskName; $vm = get-AzVM -ResourceGroupName $recoveryVMRG -Name $recoveryVMName Add-AzVMDataDisk -VM $vm -Name $osDiskName -ManagedDiskId $osDisk.Id -Caching None -Lun 3 -CreateOption Attach Update-AzVM -VM $vm -ResourceGroupName $recoveryVMRG
您無法將受控磁碟連結至從 Blob 映射還原的 VM。
連結磁碟之後,請建立與復原 VM 的遠端桌面連線。
開啟提升許可權的 Azure PowerShell 工作階段(以系統管理員身分執行)。 執行下列命令以登入 Azure 訂用帳戶:
Add-AzAccount -SubscriptionID [SubscriptionID]
執行下列腳本來檢查 BEK 檔案的名稱(秘密名稱):
$vmName = "myVM" $vault = "myKeyVault" Get-AzKeyVaultSecret -VaultName $vault | where {($_.Tags.MachineName -eq $vmName) -and ($_.ContentType -match 'BEK')} ` | Sort-Object -Property Created ` | ft Created, ` @{Label="Content Type";Expression={$_.ContentType}}, ` @{Label ="MachineName"; Expression = {$_.Tags.MachineName}}, ` @{Label ="Volume"; Expression = {$_.Tags.VolumeLetter}}, ` @{Label ="DiskEncryptionKeyFileName"; Expression = {$_.Tags.DiskEncryptionKeyFileName}}
以下是輸出的範例。 在此情況下,我們假設檔名為 EF7B2F5A-50C6-4637-0001-7F599C12F85C。BEK。
Created Content Type Volume MachineName DiskEncryptionKeyFileName ------- ------------ ------ ----------- ------------------------- 11/20/2020 7:41:56 AM BEK C:\ myVM EF7B2F5A-50C6-4637-0001-7F599C12F85C.BEK
如果您看到兩個重複的磁碟區,具有較新時間戳的磁碟區是復原 VM 所使用的目前 BEK 檔案。
如果內容類型值是包裝 BEK,請移至金鑰加密金鑰 (KEK) 案例。
既然您已擁有磁碟驅動器的 BEK 檔名,您必須建立 secret-file-name。要解除鎖定磁碟驅動器的 BEK 檔案。
將 BEK 檔案下載到復原磁碟。 下列範例會將 BEK 檔案儲存至 C:\BEK 資料夾。 執行文稿之前,
C:\BEK\
請確定路徑存在。$vault = "myKeyVault" $bek = "EF7B2F5A-50C6-4637-0001-7F599C12F85C" $keyVaultSecret = Get-AzKeyVaultSecret -VaultName $vault -Name $bek $bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($keyVaultSecret.SecretValue) $bekSecretBase64 = [Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr) $bekFileBytes = [Convert]::FromBase64String($bekSecretbase64) $path = "C:\BEK\DiskEncryptionKeyFileName.BEK" [System.IO.File]::WriteAllBytes($path,$bekFileBytes)
若要使用 BEK 檔案解除鎖定連結的磁碟,請執行下列命令。
manage-bde -unlock F: -RecoveryKey "C:\BEK\EF7B2F5A-50C6-4637-0001-7F599C12F85C.BEK"
在此範例中,連結的OS磁碟是磁碟驅動器 F。請確定您使用正確的驅動器號。
使用 BEK 金鑰成功解除鎖定磁碟之後,請從復原 VM 中斷連結磁碟,然後使用這個新的 OS 磁碟重新建立 VM。
注意
交換OS磁碟適用於任何使用單一傳遞 ADE 版本加密的 VM,但雙傳遞不支援。
如果新的 VM 仍然無法正常開機,請在解除鎖定磁碟驅動器之後,嘗試下列其中一個步驟:
- 執行下列命令,暫停保護以暫時關閉 BitLocker OFF:
manage-bde -protectors -disable F: -rc 0
- 完全解密磁碟驅動器。 若要這樣做,請執行下列命令:
manage-bde -off F:
金鑰加密金鑰案例 (包裝的 BEK)
針對金鑰加密金鑰案例,請遵循下列步驟:
請確定登入的用戶帳戶需要USER中 金鑰保存庫存取原則中的「解除包裝」許可權|密鑰限|密碼編譯作業|解除包裝金鑰。
將下列文稿儲存至 .PS1 檔案:
注意
此腳本中使用的ADAL元件(dll 檔案)僅適用於 Az.Account 1.9.4 和舊版。 若要安裝 Az.Account 模組,請參閱 安裝 Az PowerShell 模組。
#Set the Parameters for the script. If you have question about the Parameters, see the "KEK script parameters" section. param ( [Parameter(Mandatory=$true)] [string] $keyVaultName, [Parameter(Mandatory=$true)] [string] $kekName, [Parameter(Mandatory=$true)] [string] $secretName, [Parameter(Mandatory=$true)] [string] $bekFilePath, [Parameter(Mandatory=$true)] [string] $adTenant ) # Load ADAL Assemblies. If the ADAL Assemblies cannot be found, please see the "Install Az PowerShell module" section. $adal = "${env:ProgramFiles}\WindowsPowerShell\Modules\Az.Accounts\1.9.4\PreloadAssemblies\Microsoft.IdentityModel.Clients.ActiveDirectory.dll" $adalforms = "${env:ProgramFiles}\WindowsPowerShell\Modules\Az.Accounts\1.9.4\PreloadAssemblies\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" If ((Test-Path -Path $adal) -and (Test-Path -Path $adalforms)) { [System.Reflection.Assembly]::LoadFrom($adal) [System.Reflection.Assembly]::LoadFrom($adalforms) } else { Write-output "ADAL Assemblies files cannot be found. Please set the correct path for `$adal` and `$adalforms`, then run the script again." exit } # Set well-known client ID for AzurePowerShell $clientId = "1950a258-227b-4e31-a9cf-717495945fc2" # Set redirect URI for Azure PowerShell $redirectUri = "urn:ietf:wg:oauth:2.0:oob" # Set Resource URI to Azure Service Management API $resourceAppIdURI = "https://vault.azure.net" # Set Authority to Azure AD Tenant $authority = "https://login.windows.net/$adtenant" # Create Authentication Context tied to Azure AD Tenant $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority # Acquire token $platformParameters = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters" -ArgumentList "Auto" $authResult = $authContext.AcquireTokenAsync($resourceAppIdURI, $clientId, $redirectUri, $platformParameters).result # Generate auth header $authHeader = $authResult.CreateAuthorizationHeader() # Set HTTP request headers to include Authorization header $headers = @{'x-ms-version'='2014-08-01';"Authorization" = $authHeader} ######################################################################################################################## # 1. Retrieve wrapped BEK # 2. Make KeyVault REST API call to unwrap the BEK # 3. Convert the Base64Url string returned by KeyVault unwrap to Base64 string # 4. Convert Base64 string to bytes and write to the BEK file ######################################################################################################################## #Get wrapped BEK and place it in JSON object to send to KeyVault REST API $keyVaultSecret = Get-AzKeyVaultSecret -VaultName $keyVaultName -Name $secretName $bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($keyVaultSecret.SecretValue) $wrappedBekSecretBase64 = [Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr) $jsonObject = @" { "alg": "RSA-OAEP", "value" : "$wrappedBekSecretBase64" } "@ #Get KEK Url $kekUrl = (Get-AzKeyVaultKey -VaultName $keyVaultName -Name $kekName).Key.Kid; $unwrapKeyRequestUrl = $kekUrl+ "/unwrapkey?api-version=2015-06-01"; #Call KeyVault REST API to Unwrap $result = Invoke-RestMethod -Method POST -Uri $unwrapKeyRequestUrl -Headers $headers -Body $jsonObject -ContentType "application/json" -Debug #Convert Base64Url string returned by KeyVault unwrap to Base64 string $base64UrlBek = $result.value; $base64Bek = $base64UrlBek.Replace('-', '+'); $base64Bek = $base64Bek.Replace('_', '/'); if($base64Bek.Length %4 -eq 2) { $base64Bek+= '=='; } elseif($base64Bek.Length %4 -eq 3) { $base64Bek+= '='; } #Convert base64 string to bytes and write to BEK file $bekFileBytes = [System.Convert]::FromBase64String($base64Bek); [System.IO.File]::WriteAllBytes($bekFilePath,$bekFileBytes) #Delete the key from the memory [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr) clear-variable -name wrappedBekSecretBase64
設定參數。 腳本會處理 KEK 秘密以建立 BEK 金鑰,然後將它儲存至復原 VM 上的本機資料夾。 如果您在執行文稿時收到錯誤,請參閱 腳本疑難解答 一節。
文稿開始時,您會看到下列輸出:
GAC 版本位置
False v4.0.30319 C:\Program Files\WindowsPowerShell\Modules\Az.Accounts...False v4.0.30319 C:\Program Files\WindowsPowerShell\Modules\Az.Accounts...
當文稿完成時,您會看到下列輸出:
VERBOSE: POST https://myvault.vault.azure.net/keys/rondomkey/<KEY-ID>/unwrapkey?api- version=2015-06-01 with -1-byte payload VERBOSE: received 360-byte response of content type application/json; charset=utf-8
若要使用 BEK 檔案解除鎖定連結的磁碟,請執行下列命令:
manage-bde -unlock F: -RecoveryKey "C:\BEK\EF7B2F5A-50C6-4637-9F13-7F599C12F85C.BEK
在此範例中,連結的OS磁碟是磁碟驅動器 F。請確定您使用正確的驅動器號。
使用 BEK 金鑰成功解除鎖定磁碟之後,請從復原 VM 中斷連結磁碟,然後使用 交換 OS 磁碟功能,以此修復的磁碟 取代原始 VM 的 OS 磁碟。
如果新的 VM 仍然無法正常開機,請在解除鎖定磁碟驅動器之後,嘗試下列其中一個步驟:
- 執行下列命令暫停保護以暫時關閉 BitLocker OFF:
manage-bde -protectors -disable F: -rc 0
- 完全解密磁碟驅動器。 若要這樣做,請執行下列命令:
manage-bde -off F:
腳本疑難解答
錯誤:無法載入檔案或元件
之所以發生此錯誤,是因為ADAL元件的路徑錯誤。 您可以搜尋 Az.Accounts
資料夾以尋找正確的路徑。
錯誤:Get-AzKeyVaultSecret 或 Get-AzKeyVaultSecret 無法辨識為 Cmdlet 的名稱
如果您使用舊的 Az PowerShell 模組,則必須將兩個命令變更為 Get-AzureKeyVaultSecret
和 Get-AzureKeyVaultSecret
。
KEK 腳本參數
參數 | 範例 | 如何檢查 |
---|---|---|
$keyVaultName | myKeyVault2707 | 執行 Get-AzVM -ResourceGroupName $rgName -Name $vmName -DisplayHint Expand 並檢查 輸出中的 Settings 和 KeyEncryptionKeyURL 。 以下是範例:“KeyEncryptionKeyURL”: https://myKeyVault2707.vault.azure.net/keys/mykey/000072b987145a3b79b0ed415f0000 |
$kekName | mykey | 執行 Get-AzVM -ResourceGroupName $rgName -Name $vmName -DisplayHint expand 並檢查 輸出中的 Settings 和 KeyEncryptionKeyURL 。 以下是範例:“KeyEncryptionKeyURL”: https://myKeyVault2707.vault.azure.net/keys/mykey/000072b987145a3b79b0ed415f0000 |
$secretName | 7EB4F531-5FBA-4970-8E2D-C11FD6B0C69D | VM 金鑰的秘密名稱。 若要尋找正確的秘密名稱,請查看解密加密 OS 磁碟一節中的步驟 6。 |
$bekFilePath | c:\bek\7EB4F531-5FBA-4970-8E2D-C11FD6B0C69D。BEK | 您想要儲存 BEK 檔案的本機路徑。 在此範例中,您需要先建立 「bek」 資料夾,再執行腳本,否則將會發生錯誤。 |
$adTenant | contoso.onmicrosoft.com | 裝載金鑰保存庫之 Microsoft Entra 識別碼的 FQDN 或 GUID |
安裝 Az PowerShell 模組
若要安裝適用於復原 VM 的 Az PowerShell 模組,請遵循下列步驟:
以系統管理員身分開啟PowerShell工作階段,並將目前工作階段的 HTTP API 安全性通訊協定設定為 TLS 1.2。 關閉目前的會話之後,安全性通訊協定將會還原為預設值。
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
下載最新版的 Nuget 套件:
Install-PackageProvider -Name "Nuget" -Force
安裝最新版的 PowerShellGet 套件,然後重新啟動 PowerShell。
Install-Module -Name PowerShellGet -Force
執行下列命令以安裝最新版的 Azure Az 模組:
Install-Module -Name Az -Scope AllUsers -Repository PSGallery -Force
安裝 Az.Account 1.9.4 套件:
Install-Module -Name Az.Accounts -Scope AllUsers -RequiredVersion "1.9.4" -Repository PSGallery -Force
與我們連絡,以取得說明
如果您有問題或需要相關協助,請建立支援要求,或詢問 Azure community 支援。 您也可以向 Azure 意見反應社群提交產品意見反應。