Problemi di avvio di BitLocker in una macchina virtuale di Azure

Si applica a: ✔️ macchine virtuali di Windows

Questo articolo descrive i potenziali problemi di BitLocker che possono verificarsi all'avvio di una macchina virtuale Windows in Microsoft Azure.

Sintomo

La macchina virtuale Windows non si avvia. Quando si controllano gli screenshot nella finestra Diagnostica di avvio, viene visualizzato uno dei messaggi di errore seguenti:

  • Collegare l'unità USB contenente la chiave BitLocker

  • Il tuo account è bloccato. Immetti la chiave di ripristino per continuare (Layout di tastiera: US) Troppi tentativi di accesso con informazioni errate. Il PC è stato bloccato per proteggere la privacy dell'utente. Per recuperare la chiave di ripristino, visitare https://windows.microsoft.com/recoverykeyfaq da un altro PC o dispositivo mobile. Nel caso sia necessario, l'ID della chiave è XXXXXXX. In alternativa, è possibile ripristinare le impostazioni di fabbrica del PC.

  • Digitare la password per sbloccare l'unità [ ] Premere INS per visualizzare la password durante la digitazione.

  • Immetti la chiave di ripristino Carica la chiave di ripristino da un dispositivo USB.

Causa

Questo problema può verificarsi se la macchina virtuale non riesce a individuare il file della chiave di ripristino di BitLocker (BEK) per decrittografare il disco crittografato.

Decrittografare il disco del sistema operativo crittografato

Suggerimento

Se si dispone di un backup recente della macchina virtuale, è possibile provare a ripristinare la macchina virtuale dal backup per risolvere il problema di avvio.

Per risolvere questo problema, arrestare e deallocare la macchina virtuale e quindi avviarla. Questa operazione forza la macchina virtuale a recuperare il file con estensione BEK da Azure Key Vault e quindi lo inserisce nel disco crittografato.

Se questo metodo non risolve il problema, seguire questa procedura per ripristinare manualmente il file con estensione BEK:

  1. Eseguire un'istantanea del disco del sistema operativo della macchina virtuale interessata come backup. Per ulteriori informazioni, consultare Istantanea del disco.

  2. Collegare il disco del sistema operativo a una macchina virtuale di ripristino. Quando si collega un disco gestito, potrebbe essere visualizzato un messaggio di errore che indica la presenza di impostazioni di crittografia e l'impossibilità di usare il disco come disco dati. In questo caso, eseguire lo script seguente per provare nuovamente a collegare il disco:

    $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
    

    Non è possibile collegare un disco gestito a una macchina virtuale che è stata ripristinata dall'immagine di un BLOB.

  3. Dopo aver collegato il disco, stabilire una connessione Desktop remoto alla macchina virtuale di ripristino.

  4. Installare il modulo Az PowerShell e Az.Account 1.9.4 nella macchina virtuale di ripristino.

  5. Aprire una sessione di Azure PowerShell con privilegi elevati (Esegui come amministratore). Eseguire i comandi seguenti per accedere alla sottoscrizione di Azure:

    Add-AzAccount -SubscriptionID [SubscriptionID]
    
  6. Eseguire lo script seguente per controllare il nome del file BEK (nome segreto):

    $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}}
    

    Di seguito è riportato un esempio di output. In questo caso si presuppone che il nome del file sia 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
    

    Se vengono visualizzati due volumi duplicati, il volume con il timestamp più recente è il file con estensione BEK corrente usato dalla macchina virtuale di ripristino.

    Se il valore di Content Type è Wrapped BEK, passare agli scenari relativi alla chiave di crittografia della chiave (KEK).

    Dopo aver ottenuto il nome del file con estensione BEK dell'unità, per sbloccare l'unità è necessario creare il file secret-file-name.BEK.

  7. Scaricare il file con estensione BEK sul disco di ripristino. L'esempio seguente salva il file con estensione BEK nella cartella C:\BEK. Verificare che il percorso C:\BEK\ esista prima di eseguire gli script.

    $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. Per sbloccare il disco collegato usando il file BEK, eseguire il comando seguente.

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

    In questo esempio, il disco del sistema operativo collegato è l'unità F. Verificare di usare la lettera di unità corretta.

  9. Dopo che il disco è stato sbloccato correttamente usando la chiave BEK, scollegare il disco dalla macchina virtuale di ripristino e quindi ricreare la macchina virtuale usando questo nuovo disco del sistema operativo.

    Nota

    Lo scambio del disco del sistema operativo è disponibile per qualsiasi macchina virtuale crittografata con una sola versione di ADE pass, ma non è supportata per Dual Pass.

  10. Se la nuova macchina virtuale non è ancora in grado di avviarsi normalmente, provare uno dei passaggi seguenti dopo aver sbloccato l'unità:

    • Sospendere la protezione per disattivare temporaneamente BitLocker eseguendo quanto segue:
    manage-bde -protectors -disable F: -rc 0
    
    • Decrittografare completamente l'unità. A tale scopo, usare il comando seguente:
    manage-bde -off F:
    

Scenario della chiave di crittografia delle chiavi (BEK incapsulato)

In uno scenario con chiave di crittografia della chiave, seguire questa procedura:

  1. Verificare che l'account utente connesso richieda l'autorizzazione senza wrapping nei criteri di accesso dell'insieme di credenziali delle chiavi in UTENTE|Autorizzazioni chiave| Operazioni crittografiche|Annulla il wrapping della chiave.

  2. Salvare lo script seguente in un file PS1:

    Nota

    Gli assembly ADAL (file dll) usati in questo script sono disponibili solo in Az.Account 1.9.4 e nelle versioni precedenti. Per installare il modulo Az.Account, vedere Installare il modulo 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. Impostare i parametri. Lo script elabora il segreto della chiave KEK per creare la chiave BEK e quindi lo salva in una cartella locale nella macchina virtuale di ripristino. Se si ricevono errori durante l'esecuzione dello script, vedere la sezione relativa alla risoluzione dei problemi relativi allo script.

  4. All'avvio dello script viene visualizzato l'output seguente:

    Percorso versione GAC


    False v4.0.30319 C:\Programmi\WindowsPowerShell\Modules\Az.Accounts... False v4.0.30319 C:\Programmi\WindowsPowerShell\Modules\Az.Accounts...

    Al termine dell'esecuzione dello script viene visualizzato l'output seguente:

    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. Per sbloccare il disco collegato usando il file con estensione BEK, eseguire il comando seguente:

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

    In questo esempio, il disco del sistema operativo collegato è l'unità F. Verificare di usare la lettera di unità corretta.

  6. Dopo che il disco è stato sbloccato correttamente usando la chiave BEK, scollegare il disco dalla macchina virtuale di ripristino e quindi usare la funzionalità Scambia disco del sistema operativo per sostituire il disco del sistema operativo della macchina virtuale originale con questo disco ripristinato.

  7. Se la nuova macchina virtuale non è ancora in grado di avviarsi normalmente, provare uno dei passaggi seguenti dopo aver sbloccato l'unità:

    • Sospendere la protezione per disattivare temporaneamente BitLocker eseguendo il comando seguente:
    manage-bde -protectors -disable F: -rc 0
    
    • Decrittografare completamente l'unità. A tale scopo, usare il comando seguente:
    manage-bde -off F:
    

Risoluzione dei problemi relativi a script

Errore: Impossibile caricare il file o l'assembly

Questo errore si verifica perché i percorsi degli assembly ADAL non sono corretti. È possibile cercare Az.Accounts la cartella per trovare il percorso corretto.

Errore: Get-AzKeyVaultSecret o Get-AzKeyVaultSecret non viene riconosciuto come nome di un cmdlet

Se si usa il modulo Az PowerShell precedente, è necessario modificare i due comandi in Get-AzureKeyVaultSecret e Get-AzureKeyVaultSecret.

Parametri dello script KEK

Parametri Esempio Come controllare
$keyVaultName myKeyVault2707 Eseguire Get-AzVM -ResourceGroupName $rgName -Name $vmName -DisplayHint Expande controllare Impostazioni e KeyEncryptionKeyURL nell'output. Ecco un esempio:
"KeyEncryptionKeyURL":https://myKeyVault2707.vault.azure.net/keys/mykey/000072b987145a3b79b0ed415f0000
$kekName mykey Eseguire Get-AzVM -ResourceGroupName $rgName -Name $vmName -DisplayHint expand e controllare Impostazioni e KeyEncryptionKeyURL nell'output. Ecco un esempio:
"KeyEncryptionKeyURL":https://myKeyVault2707.vault.azure.net/keys/mykey/000072b987145a3b79b0ed415f0000
$secretName 7EB4F531-5FBA-4970-8E2D-C11FD6B0C69D Nome del segreto della chiave della macchina virtuale.
Per trovare il nome del segreto corretto, controllare il passaggio 6 nella sezione Decrittografare il disco del sistema operativo crittografato.
$bekFilePath c:\bek\7EB4F531-5FBA-4970-8E2D-C11FD6B0C69D. BEK Percorso locale in cui salvare il file BEK. Nell'esempio è necessario creare la cartella "bek" prima di eseguire lo script oppure si verifica un errore.
$adTenant contoso.onmicrosoft.com FQDN o GUID dell'ID Microsoft Entra che ospita l'insieme di credenziali delle chiavi

Installare il modulo Az PowerShell

Per installare il modulo Az PowerShell per la macchina virtuale di ripristino, seguire questa procedura:

  1. Aprire una sessione di PowerShell come amministratore e impostare il protocollo di sicurezza delle API HTTP su TLS 1.2 per la sessione corrente. Il protocollo di sicurezza verrà ripristinato al valore predefinito dopo la chiusura della sessione corrente.

    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    
  2. Scaricare la versione più recente del pacchetto Nuget:

     Install-PackageProvider -Name "Nuget" -Force
    
    
  3. Installare la versione più recente del pacchetto PowerShellGet e quindi riavviare PowerShell.

    Install-Module -Name PowerShellGet -Force
    
  4. Eseguire il comando seguente per installare la versione più recente del modulo Az di Azure:

    Install-Module -Name Az -Scope AllUsers -Repository PSGallery -Force
    
  5. Installare il pacchetto Az.Account 1.9.4:

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

Contattaci per ricevere assistenza

In caso di domande o bisogno di assistenza, creare una richiesta di supporto tecnico oppure formula una domanda nel Supporto della community di Azure. È possibile anche inviare un feedback sul prodotto al feedback della community di Azure.