Azure VM での BitLocker ブート エラー

この記事では、Microsoft Azure で Windows 仮想マシン (VM) を開始するときに発生する可能性がある BitLocker エラーについて説明します。

現象

Windows VM が起動しません。 [ブート診断] ウィンドウでスクリーンショットを調べると、次のエラー メッセージのいずれかが表示されています。

  • BitLocker キーを含んだ USB ドライバーを接続してください

  • ロックアウトされました。 使用できる状態に戻すには回復キーを入力してください (キーボード レイアウト: US) 正しくないサインイン情報が何度も入力されたので、お使いの PC はプライバシーを保護するためにロックされました。 回復キーを取得するには、他の PC またはモバイル デバイスで https://windows.microsoft.com/recoverykeyfaq にアクセスしてください。 なお、キー ID は XXXXXXX です。 また、お使いの PC を初期状態に戻すこともできます。

  • このドライブのロックを解除するためにパスワードを入力してください [ ] 入力時にパスワードを表示するには、挿入キー (Insert) を押してください。

  • 回復キーの入力。USB デバイスから回復キーを読み込む。

原因

この問題は、暗号化されたディスクの暗号化を解除するための BitLocker 回復キー (BEK) ファイルを VM が見つけることができない場合に発生する可能性があります。

暗号化された OS ディスクの暗号化を解除する

ヒント

VM の最新のバックアップがある場合は、そのバックアップから VM の復元を試行して、起動の問題を修正することができます。

この問題を解決するには、VM を停止して割り当てを解除した後、これを起動します。 この操作によって、VM は、Azure Key Vault から BEK ファイルを取得した後、それを暗号化されたディスクに保存します。

この方法で問題が解決しない場合は、次の手順で BEK ファイルを手動で復元します。

  1. バックアップとして、影響を受ける VM の OS ディスクのスナップショットを取得します。 詳細については、ディスクのスナップショットに関する記事を参照してください。

  2. 復旧 VM に OS ディスクを接続します。 マネージド ディスクをアタッチすると、エラー メッセージ "contains encryption settings and therefore cannot be used as a data disk” が表示される場合があります。 この状況では、次のスクリプトを実行して、ディスクのアタッチを再試行します。

    $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 にマネージド ディスクをアタッチすることはできません。

  3. ディスクが接続されたら、リカバリ VM へのリモート デスクトップ接続を確立します。

  4. リカバリ VM に Az PowerShell モジュールと Az.Account 1.9.4 をインストールします

  5. 管理者特権の Azure PowerShell セッション (管理者として実行) を開きます。 次のコマンドを実行して、Azure サブスクリプションにサインインします。

    Add-AzAccount -SubscriptionID [SubscriptionID]
    
  6. 次のスクリプトを実行して、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
    

    2 つの重複するボリュームが表示されている場合は、タイムスタンプが新しいほうのボリュームが、復旧 VM で使用される現在の BEK ファイルになります。

    Content Type の値が Wrapped BEK の場合は、「Key Encryption Key (KEK) のシナリオ」に進んでください。

    これで、ドライブ用の BEK ファイルの名前がわかったので、secret-file-name.BEK ファイルを作成して、BEK ファイル ドライブのロックを解除する必要があります。

  7. 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)
    
  8. アタッチされたディスクのロックを BEK ファイルを使用して解除するには、次のコマンドを実行します。

    manage-bde -unlock F: -RecoveryKey "C:\BEK\EF7B2F5A-50C6-4637-0001-7F599C12F85C.BEK"
    

    この例では、アタッチされた OS ディスクはドライブ F です。適切なドライブ文字を使用していることを確認してください。

  9. BEK キーを使用してディスクが正常にロック解除された後、そのディスクを復旧 VM からデタッチし、この新しい OS ディスクを使用して VM を再作成します。

    注:

    OS ディスクの交換は、シングル パス ADE バージョンで暗号化されたすべての VM で使用できますが、デュアル パスではサポートされていません。

  10. それでも新しい VM が正常に起動しない場合は、ドライブのロックを解除した後、次のいずれかの手順を試してください。

    • 保護を中断して、次のように実行して BitLocker を一時的に無効にします。
    manage-bde -protectors -disable F: -rc 0
    
    • ドライブを完全に復号化します。 このためには、次のコマンドを実行します。
    manage-bde -off F:
    

キー暗号化キーのシナリオ (ラップされた BEK)

Key Encryption Key のシナリオでは、次の手順に従います。

  1. [ユーザー] > [キーのアクセス許可] > [暗号化操作] > [Unwrap Key]\(キーのラップ解除\) で、ログインするユーザー アカウントでは、Key Vault アクセス ポリシーの "ラップ解除" アクセス許可が必要であることを確認します。

  2. 次のスクリプトを .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
    
  3. パラメーターを設定します。 このスクリプトは、KEK シークレットを処理して BEK キーを作成した後、それを復旧 VM 上のローカル フォルダーに保存します。 スクリプトの実行時にエラーが発生した場合は、「スクリプトのトラブルシューティング」セクションを参照してください。

  4. スクリプトが開始されると、次の出力が表示されます。

    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
    
  5. アタッチされたディスクのロックを BEK ファイルを使用して解除するには、次のコマンドを実行します。

    manage-bde -unlock F: -RecoveryKey "C:\BEK\EF7B2F5A-50C6-4637-9F13-7F599C12F85C.BEK
    

    この例では、アタッチされた OS ディスクはドライブ F です。適切なドライブ文字を使用していることを確認してください。

  6. BEK キーを使用してディスクのロックが正常に解除されたら、ディスクをリカバリ VM からデタッチし、[OS ディスクのスワップ] 機能を使用して、元の VM の OS ディスクをこの修復されたディスクと交換します。

  7. それでも新しい VM が正常に起動しない場合は、ドライブのロックを解除した後、次のいずれかの手順を試してください。

    • 保護を中断して、次のコマンドを実行して BitLocker を一時的に無効にします。
    manage-bde -protectors -disable F: -rc 0
    
    • ドライブを完全に復号化します。 このためには、次のコマンドを実行します。
    manage-bde -off F:
    

スクリプトのトラブルシューティング

エラー: ファイルまたはアセンブリを読み込むことができませんでした

このエラーは、ADAL アセンブリのパスが間違っているために発生します。 Az.Accounts フォルダーを検索して正しいパスを検索することができます。

エラー: Get-AzKeyVaultSecret または Get-AzKeyVaultSecret はコマンドレットの名前として認識されません

以前の AZ PowerShell モジュールを使用している場合、2 つのコマンドを Get-AzureKeyVaultSecretGet-AzureKeyVaultSecret に変更する必要があります。

KEK スクリプト パラメーター

パラメーター 確認方法
$keyVaultName myKeyVault2707 Get-AzVM -ResourceGroupName $rgName -Name $vmName -DisplayHint Expand を実行し、出力の [設定] と KeyEncryptionKeyURL を確認します。 "KeyEncryptionKeyURL"の例を次に示
します。https://myKeyVault2707.vault.azure.net/keys/mykey/000072b987145a3b79b0ed415f0000
$kekName mykey Get-AzVM -ResourceGroupName $rgName -Name $vmName -DisplayHint expand を実行し、出力の [設定] と 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 IDの FQDN または GUID

Az PowerShell モジュールのインストール

リカバリ VM 用の Az PowerShell モジュールをインストールするには、次の手順を実行します。

  1. 管理者として PowerShell セッションを開き、現在のセッションの HTTP API セキュリティ プロトコルを TLS 1.2 に設定します。 現在のセッションを閉じると、セキュリティ プロトコルは既定値に戻ります。

    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    
  2. Nuget パッケージの最新バージョンをダウンロードします。

     Install-PackageProvider -Name "Nuget" -Force
    
    
  3. PowerShellGet パッケージの最新バージョンをインストールしてから、PowerShell を再起動します。

    Install-Module -Name PowerShellGet -Force
    
  4. 次のコマンドを実行して、Azure Az モジュールの最新バージョンをインストールします。

    Install-Module -Name Az -Scope AllUsers -Repository PSGallery -Force
    
  5. Az.Account 1.9.4 パッケージをインストールします。

    Install-Module -Name Az.Accounts -Scope AllUsers -RequiredVersion "1.9.4" -Repository PSGallery -Force
    

お問い合わせはこちらから

質問がある場合やヘルプが必要な場合は、サポート要求を作成するか、Azure コミュニティ サポートにお問い合わせください。 Azure フィードバック コミュニティに製品フィードバックを送信することもできます。