Download Files from Azure Blob Storage with PowerShell

Downloading files from an Azure Blob Storage Container with PowerShell is very simple. There is no need to install any additional modules, you can just use the Blob Service REST API to get the files.

This example is using a Shared Access Signature (SAS) as this gives a granular- and time limited access to the content. SAS tokens can be generated on the Azure-Web-Portal or by using the "Azure Storage Explorer" tool.

The first example is a PoweShell function to List all the files in a container

function Get-BlobItems{
    param (
        $URL
    )
    
    $uri = $URL.split('?')[0]
    $sas = $URL.split('?')[1]
    
    $newurl = $uri + "?restype=container&comp=list&" + $sas 
    
    #Invoke REST API
    $body = Invoke-RestMethod -uri $newurl

    #cleanup answer and convert body to XML
    $xml = [xml]$body.Substring($body.IndexOf('<'))

    #use only the relative Path from the returned objects
    $files = $xml.ChildNodes.Blobs.Blob.Name

    #regenerate the download URL incliding the SAS token
    $files | ForEach-Object { $uri + "/" + $_ + "?" + $sas }    
}

Example:

Get-BlobItems "https://myblob.blob.core.windows.net/mycontainer?st=2019-01-18T15%3A26%3A21Z&se=2019-01-19T15%3A26%3A21Z&sp=rl&sv=2018-03-28&sr=c&sig=5%2Bo48srqfNpPktDZUbBYFu0sEdu1aenraj2k%2BnMpjRc%3D"

Output:
https://myblob.blob.core.windows.net/mycontainer/subfolder1/file1.xml?st=2019-01-18T15%3A26%3A21Z&se=2019-01-19T15%3A26%3A21Z&sp=rl&sv=2018-03-28&sr=c&sig=5%2Bo48srqfNpPktDZUbBYFu0sEdu1aenraj2k%2BnMpjRc%3D
https://myblob.blob.core.windows.net/mycontainer/subfolder1/backup/file2.json?st=2019-01-18T15%3A26%3A21Z&se=2019-01-19T15%3A26%3A21Z&sp=rl&sv=2018-03-28&sr=c&sig=5%2Bo48srqfNpPktDZUbBYFu0sEdu1aenraj2k%2BnMpjRc%3D
https://myblob.blob.core.windows.net/mycontainer/subfolder2/file3.txt?st=2019-01-18T15%3A26%3A21Z&se=2019-01-19T15%3A26%3A21Z&sp=rl&sv=2018-03-28&sr=c&sig=5%2Bo48srqfNpPktDZUbBYFu0sEdu1aenraj2k%2BnMpjRc%3D

To download the files, we just need to make sure the target directory exists before downloading the files…

Here we are, a simple PowerShell function to download all files from an Azure Blob Storage container by using a Shared Access Signature (SAS).

function Invoke-BlobItems {
    param (
        [Parameter(Mandatory)]
        [string]$URL,
        [string]$Path = (Get-Location)
    )
    
    $uri = $URL.split('?')[0]
    $sas = $URL.split('?')[1]

    $newurl = $uri + "?restype=container&comp=list&" + $sas 
    
    #Invoke REST API
    $body = Invoke-RestMethod -uri $newurl

    #cleanup answer and convert body to XML
    $xml = [xml]$body.Substring($body.IndexOf('<'))

    #use only the relative Path from the returned objects
    $files = $xml.ChildNodes.Blobs.Blob.Name

    #create folder structure and download files
    $files | ForEach-Object { $_; New-Item (Join-Path $Path (Split-Path $_)) -ItemType Directory -ea SilentlyContinue | Out-Null
        (New-Object System.Net.WebClient).DownloadFile($uri + "/" + $_ + "?" + $sas, (Join-Path $Path $_))
     }
}