Recursively Set Blob Content Types on Azure Storage Using PowerShell

  • Home
  • Azure
  • Recursively Set Blob Content Types on Azure Storage Using PowerShell
Azure Blob Storage Content Type

Recently I’ve needed to programmatically set Azure Blob content types with Powershell. I needed to set the content type on all blobs in all containers in Azure Storage. By default, if not provided when uploading through .NET, the file content type is set to application/octet-stream, whilst browsers are clever enough to still display an image if it’s a JPG, for example, some applications may not.

I came across this article as a starting point. Full credit to the author here for helping set the content types. https://liftcodeplay.com/2017/11/28/how-to-fix-azure-storage-blob-content-types/

To work for my scenario I needed the PowerShell script to both be recursive through all containers, and also be able to filter to only perform the update operation on certain containers. Here’s a script showing how to set Azure Blob Content-Types with PowerShell.

# Set the below storage account name and key to target the correct storage account.
# These can be found in the Azure Portal
$StorageAccountName = ""
$StorageAccountKey = ""

# Sets a search prefix on containers
# Examples:
# * - All containers
# website* - Containers starting with the name "website"
$ContainerSearchPrefix = "*"

########################################################################
# Do not modify anything below this line
########################################################################
Function SetContentType
{
    param(
        [Microsoft.WindowsAzure.Commands.Common.Storage.ResourceModel.AzureStorageBlob] $Blob, 
        [string] $ContentType
    )

    $CloudBlockBlob = [Microsoft.Azure.Storage.Blob.CloudBlockBlob] $Blob.ICloudBlob

    $CloudBlockBlob.Properties.ContentType = $ContentType
    $task = $CloudBlockBlob.SetPropertiesAsync()
    $task.Wait()
    
    Write-Host $task.Status
}

Function ProcessContainers
{
    param(
        [Microsoft.WindowsAzure.Commands.Common.Storage.ResourceModel.AzureStorageContainer[]] $Containers
    )

    foreach($Container in $Containers)
    {
        Write-Host "Processing Container:" $Container.Name -ForegroundColor white

        $Blobs = Get-AzStorageBlob -Context $Context -Container $Container.Name

        foreach($Blob in $Blobs)
        {
            Write-Host "Processing Blob:" $Blob.Name

            $Extn = [IO.Path]::GetExtension($Blob.Name)
            $ContentType = ""

            switch ($Extn) {
                ".jpg" { $ContentType = "image/jpeg" }
                ".jpeg" { $ContentType = "image/jpeg" }
                ".png" { $ContentType = "image/png" }
                Default { $ContentType = "" }
            }

            Write-Host "Blob file extension is" $Extn "- this will change the content type to" $ContentType


            if ($ContentType -ne "") {
                SetContentType $Blob $ContentType
            }      
        }

        Write-Host "Completed Processing Container" $Container.Name
    }
}

$Context = New-AzStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey
$Containers = Get-AzStorageContainer -Context $Context -Name $ContainerSearchPrefix

ProcessContainers $Containers

Set the following variables to setup the PowerShell script

$StorageAccountName = “” // You can get this from the Azure Portal, just the account name, you don’t need any windows.net suffix
$StorageAccountKey = “” // You can get this from the Azure Portal also, under the access keys blade

$ContainerSearchPrefix = “” // You can set a whole container name here, or use * for all containers. Alternatively, use a wildcard for the container to start with a search term such as website*

I intentionally kept the output of the script extremely detailed, alerting you to every content-type change. Feel free to comment out the Write-Host lines if you feel this is causing problems.

Tags:

    Dan Horrocks-Burgess

    Software Developer by day, Disney lover by night.