@@ -136,6 +136,7 @@ private bool IsExtensionInstalled(OSType currentOSType)
136
136
{
137
137
this . Name = this . Name ?? AzureDiskEncryptionExtensionContext . LinuxExtensionDefaultName ;
138
138
}
139
+
139
140
140
141
AzureOperationResponse < VirtualMachineExtension > extensionResult = this . VirtualMachineExtensionClient . GetWithInstanceView ( this . ResourceGroupName , this . VMName , this . Name ) ;
141
142
if ( extensionResult == null )
@@ -222,19 +223,14 @@ private string GetExtensionStatusMessage(OSType currentOSType, bool returnSubsta
222
223
if ( publisherMatch )
223
224
{
224
225
AzureDiskEncryptionExtensionContext context = new AzureDiskEncryptionExtensionContext ( returnedExtension ) ;
225
- if ( ( context == null ) ||
226
- ( context . Statuses == null ) ||
227
- ( context . Statuses . Count < 1 ) ||
228
- ( string . IsNullOrWhiteSpace ( context . Statuses [ 0 ] . Message ) ) )
226
+ if ( ( context == null ) || ( context . Statuses == null ) || ( context . Statuses . Count < 1 ) )
229
227
{
230
228
throw new KeyNotFoundException ( string . Format ( CultureInfo . CurrentUICulture , "Invalid extension status" ) ) ;
231
229
}
232
230
233
231
if ( returnSubstatusMessage )
234
232
{
235
- if ( ( context == null ) ||
236
- ( context . SubStatuses == null ) ||
237
- ( context . SubStatuses . Count < 1 ) )
233
+ if ( ( context == null ) || ( context . SubStatuses == null ) || ( context . SubStatuses . Count < 1 ) )
238
234
{
239
235
throw new KeyNotFoundException ( string . Format ( CultureInfo . CurrentUICulture , "Invalid extension substatus" ) ) ;
240
236
}
@@ -243,8 +239,18 @@ private string GetExtensionStatusMessage(OSType currentOSType, bool returnSubsta
243
239
return context . SubStatuses [ 0 ] . Message ;
244
240
}
245
241
}
246
-
247
- return context . Statuses [ 0 ] . Message ;
242
+ else
243
+ {
244
+ if ( ! string . IsNullOrWhiteSpace ( context . Statuses [ 0 ] . Message ) )
245
+ {
246
+ return context . Statuses [ 0 ] . Message ;
247
+ }
248
+ else
249
+ {
250
+ // if message is empty, fall back to display status
251
+ return context . Statuses [ 0 ] . DisplayStatus ;
252
+ }
253
+ }
248
254
}
249
255
else
250
256
{
@@ -299,6 +305,17 @@ private EncryptionStatus IsOsVolumeEncrypted(VirtualMachine vmParameters)
299
305
}
300
306
}
301
307
308
+ private string GetLastEncryptionStatus ( DiskInstanceView div )
309
+ {
310
+ string lastCode = "" ;
311
+ foreach ( InstanceViewStatus ivs in div . Statuses )
312
+ {
313
+ if ( ivs . Code . StartsWith ( "EncryptionState/" ) )
314
+ lastCode = ivs . Code ;
315
+ }
316
+ return lastCode ;
317
+ }
318
+
302
319
private DiskEncryptionSettings GetOsVolumeEncryptionSettings ( VirtualMachine vmParameters )
303
320
{
304
321
if ( ( vmParameters != null ) &&
@@ -307,6 +324,8 @@ private DiskEncryptionSettings GetOsVolumeEncryptionSettings(VirtualMachine vmPa
307
324
{
308
325
return vmParameters . StorageProfile . OsDisk . EncryptionSettings ;
309
326
}
327
+
328
+ // nothing found
310
329
return null ;
311
330
}
312
331
@@ -373,6 +392,18 @@ private bool ExtensionProvisioningSucceeded(AzureDiskEncryptionExtensionContext
373
392
374
393
private EncryptionStatus AreDataVolumesEncrypted ( VirtualMachine vmParameters )
375
394
{
395
+ // return true if any (non-OS) data volume attached to the VM reports an encrypted state
396
+ VirtualMachineInstanceView iv = this . ComputeClient . ComputeManagementClient . VirtualMachines . InstanceView ( this . ResourceGroupName , this . VMName ) ;
397
+ foreach ( DiskInstanceView div in iv . Disks )
398
+ {
399
+ if ( ! ( ( div . Name . Equals ( "osDisk" ) || div . Name . Contains ( "_OsDisk_" ) ) ) &&
400
+ GetLastEncryptionStatus ( div ) . Equals ( "EncryptionState/encrypted" ) )
401
+ {
402
+ return EncryptionStatus . Encrypted ;
403
+ }
404
+ }
405
+
406
+ // no encrypted status found in disk instance data, check vm model
376
407
if ( vmParameters == null || vmParameters . Resources == null )
377
408
{
378
409
return EncryptionStatus . Unknown ;
@@ -409,21 +440,91 @@ private EncryptionStatus AreDataVolumesEncrypted(VirtualMachine vmParameters)
409
440
return EncryptionStatus . NotEncrypted ;
410
441
}
411
442
443
+ private AzureDiskEncryptionStatusContext GetStatusFromInstanceView ( )
444
+ {
445
+ AzureDiskEncryptionStatusContext result = null ;
446
+
447
+ VirtualMachineInstanceView iv = this . ComputeClient . ComputeManagementClient . VirtualMachines . InstanceView ( this . ResourceGroupName , this . VMName ) ;
448
+ if ( iv != null )
449
+ {
450
+ result = new AzureDiskEncryptionStatusContext ( ) ;
451
+ result . OsVolumeEncrypted = EncryptionStatus . Unknown ;
452
+ result . DataVolumesEncrypted = EncryptionStatus . Unknown ;
453
+
454
+ foreach ( DiskInstanceView div in iv . Disks )
455
+ {
456
+ if ( result . OsVolumeEncrypted == EncryptionStatus . Unknown &&
457
+ ( div . Name . Equals ( "osDisk" ) || div . Name . Contains ( "_OsDisk_" ) ) )
458
+ {
459
+ // check os volume status
460
+ string status = GetLastEncryptionStatus ( div ) ;
461
+ switch ( status )
462
+ {
463
+ case "EncryptionState/encrypted" :
464
+ result . OsVolumeEncrypted = EncryptionStatus . Encrypted ;
465
+ break ;
466
+ case "EncryptionState/notEncrypted" :
467
+ result . OsVolumeEncrypted = EncryptionStatus . NotEncrypted ;
468
+ break ;
469
+ default :
470
+ break ;
471
+ }
472
+ result . OsVolumeEncryptionSettings = ( div . EncryptionSettings != null ) ? div . EncryptionSettings [ 0 ] : null ;
473
+ }
474
+ else if ( result . DataVolumesEncrypted == EncryptionStatus . Unknown )
475
+ {
476
+ // check data volume status
477
+ string status = GetLastEncryptionStatus ( div ) ;
478
+ if ( status . Equals ( "EncryptionState/encrypted" ) )
479
+ {
480
+ result . DataVolumesEncrypted = EncryptionStatus . Encrypted ;
481
+ }
482
+ else if ( status . Equals ( "EncryptionState/notEncrypted" ) )
483
+ {
484
+ result . DataVolumesEncrypted = EncryptionStatus . NotEncrypted ;
485
+ }
486
+ }
487
+ }
488
+ }
489
+
490
+ return result ;
491
+ }
492
+
412
493
public override void ExecuteCmdlet ( )
413
494
{
414
495
base . ExecuteCmdlet ( ) ;
415
496
416
497
ExecuteClientAction ( ( ) =>
417
498
{
499
+ // get current extension status progress message
418
500
VirtualMachine vmParameters = ( this . ComputeClient . ComputeManagementClient . VirtualMachines . Get ( this . ResourceGroupName , this . VMName ) ) ;
501
+ OSType osType = GetOSType ( vmParameters ) ;
502
+ string progressMessage = null ;
503
+ if ( IsExtensionInstalled ( osType ) )
504
+ {
505
+ try
506
+ {
507
+ progressMessage = GetExtensionStatusMessage ( osType ) ;
508
+ }
509
+ catch ( KeyNotFoundException )
510
+ {
511
+ progressMessage = string . Format ( CultureInfo . CurrentUICulture , "Extension status not available on the VM" ) ;
512
+ }
513
+ }
419
514
515
+ // retrieve encryption state using per-disk instance status and report if successful
516
+ AzureDiskEncryptionStatusContext encryptionStatus = GetStatusFromInstanceView ( ) ;
517
+ if ( encryptionStatus != null && ! ( encryptionStatus . OsVolumeEncrypted == EncryptionStatus . Unknown || encryptionStatus . DataVolumesEncrypted == EncryptionStatus . Unknown ) )
518
+ {
519
+ encryptionStatus . ProgressMessage = progressMessage ;
520
+ WriteObject ( encryptionStatus ) ;
521
+ return ;
522
+ }
523
+
524
+ // fall back to retrieval of encryption state using vm model extension status
420
525
EncryptionStatus osVolumeEncrypted = IsOsVolumeEncrypted ( vmParameters ) ;
421
526
DiskEncryptionSettings osVolumeEncryptionSettings = GetOsVolumeEncryptionSettings ( vmParameters ) ;
422
527
EncryptionStatus dataVolumesEncrypted = AreDataVolumesEncrypted ( vmParameters ) ;
423
- AzureDiskEncryptionStatusContext encryptionStatus = null ;
424
- string progressMessage = null ;
425
-
426
- OSType osType = GetOSType ( vmParameters ) ;
427
528
switch ( osType )
428
529
{
429
530
case OSType . Windows :
0 commit comments