BLOG

PowerShell and Azure REST API

Azure Cloud Service 04/24/2017 by Ken Channon


List Blob Encryption Status

As you write PowerShell scripts to automate management of your Azure environment, you may find limitations with the Azure SDK cmdlets.    For example, I recently enabled encryption on a customer’s storage account.   Since it only encrypts new blobs written, I wanted to provide a list of which blobs were encrypted and which were not.     The cmdlets do not provide the blob encryption status even though it is available via the Azure Rest API (i.e. the ServerEncrypted property of the List Blobs operation).

I wrote a PowerShell script to make a request to list the blobs in a container and then display the blobs based upon encryption status (green for encrypted, red for not encrypted).

Here’s a breakdown of the script:

1. Set the Storage Account Name, Key and Container

$StorageAccount = <storage account name> 
$ContainerName = <container name> 
$Key = <access key>

2. Prepare the request

    a. Create the string to sign

$date = [System.DateTime]::UtcNow.ToString("R")
$stringToSign = "GET`n`n`n`n`n`n`n`n`n`n`n`nx-ms-date:$date`nx-ms-version:2016-051`n/$StorageAccount/$ContainerName`ncomp:list`nrestype:container"

This string is for a list blobs operation using shared key authorization.  The format of the string is described here.

    b. Create a hash object

 $sharedKey = [System.Convert]::FromBase64String($Key)
 $hasher = New-Object System.Security.Cryptography.HMACSHA256
 $hasher.Key = $sharedKey

    c. Sign the string

 $signedSignature = [System.Convert]::ToBase64String($hasher.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($stringToSign)))

    d. Create the headers

$authHeader = "SharedKey${StorageAccount}:$signedSignature" style="padding-left: 60px;">
$headers = @{"x-ms-date"=$date "x-ms-version"="2016-05-31" "Authorization"=$authHeader}

    e. Create the URI

 $URI = "https://$StorageAccount.blob.core.windows.net/" + $ContainerName + "?restype=container&comp=list" 

3. Make the request

 Invoke-RestMethod -method GET -Uri $URI -Headers $headers -OutFile $FileName

4. Parse output to display encryption status

 foreach ($blob in $BlobList.EnumerationResults.Blobs.Blob) {
 if ($blob.Properties.ServerEncrypted -eq $False) {
 write-host $blob.Name -ForegroundColor Red }
 else {
 write-host $blob.Name -ForegroundColor green}
 }

Example output from the script:

output