Skip to content

Instantly share code, notes, and snippets.

@AndreasHassing
Created March 3, 2026 10:02
Show Gist options
  • Select an option

  • Save AndreasHassing/53bb78d72914868f1b2b0a8dd252a1a8 to your computer and use it in GitHub Desktop.

Select an option

Save AndreasHassing/53bb78d72914868f1b2b0a8dd252a1a8 to your computer and use it in GitHub Desktop.
Get Azure Blob Storage Emulator tree view with PowerShell
# Show-AzuriteStorageTree.ps1
# Tree-view for Azurite (devstoreaccount1) Blob/Queue/Table.
# Folders are virtual: derived from "/" in blob names. [1](https://stackoverflow.com/questions/76901822/how-to-use-tree-command-on-powershell-to-show-files-as-well-as-directories)
# AI-generated, but useful.
[CmdletBinding()]
param(
[ValidateSet('Blobs','Queues','Tables','All')]
[string]$Services = 'All',
# Optional: if you want to force explicit connection string instead of -Local
[string]$ConnectionString,
# Safety valve for huge containers
[int]$MaxBlobsPerContainer = 5000,
# If you prefer ASCII style (+---) rather than Unicode (├──)
[switch]$Ascii
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
# --------------------------
# Tree data structure helpers
# --------------------------
function New-Node {
param(
[Parameter(Mandatory)][string]$Name,
[bool]$IsFolder = $true
)
[pscustomobject]@{
Name = $Name
IsFolder = $IsFolder
# Children keyed by "D|name" or "F|name"
Children = @{}
}
}
function Get-OrAddChild {
param(
[Parameter(Mandatory)]$Parent,
[Parameter(Mandatory)][string]$Name,
[Parameter(Mandatory)][bool]$IsFolder
)
$key = ('{0}|{1}' -f ($(if($IsFolder){'D'}else{'F'})), $Name)
if (-not $Parent.Children.ContainsKey($key)) {
$Parent.Children[$key] = New-Node -Name $Name -IsFolder:$IsFolder
}
$Parent.Children[$key]
}
function Add-BlobToTree {
param(
[Parameter(Mandatory)]$ContainerNode,
[Parameter(Mandatory)][string]$BlobName
)
if ([string]::IsNullOrWhiteSpace($BlobName)) { return }
$isFolderMarker = $BlobName.EndsWith('/')
$segments = $BlobName -split '/' | Where-Object { $_.Trim().Length -gt 0 }
if ($segments.Count -eq 0) { return }
$node = $ContainerNode
# All but last segment are folders
for ($i = 0; $i -lt ($segments.Count - 1); $i++) {
$node = Get-OrAddChild -Parent $node -Name $segments[$i] -IsFolder:$true
}
# Last segment: folder if blob endswith '/', else file
$leafName = $segments[$segments.Count - 1]
[void](Get-OrAddChild -Parent $node -Name $leafName -IsFolder:$isFolderMarker)
}
# --------------------------
# Tree rendering
# --------------------------
function Get-SortedChildren {
param([Parameter(Mandatory)]$Node)
$Node.Children.Values |
Sort-Object @{Expression={$_.IsFolder};Descending=$true},
@{Expression={$_.Name};Ascending=$true}
}
function Write-TreeLines {
param(
[Parameter(Mandatory)]$Node,
[string]$Prefix = '',
[bool]$IsLast = $true,
[bool]$IsRoot = $false
)
if ($IsRoot) {
Write-Output $Node.Name
}
else {
if ($Ascii) {
$branch = if ($IsLast) { '\--- ' } else { '+--- ' }
} else {
$branch = if ($IsLast) { '└── ' } else { '├── ' }
}
Write-Output ($Prefix + $branch + $Node.Name)
}
$children = @(Get-SortedChildren -Node $Node)
if ($children.Count -eq 0) { return }
for ($i = 0; $i -lt $children.Count; $i++) {
$child = $children[$i]
$lastChild = ($i -eq ($children.Count - 1))
$nextPrefix =
if ($IsRoot) {
''
}
else {
if ($Ascii) {
$Prefix + $(if ($IsLast) { ' ' } else { '| ' })
} else {
$Prefix + $(if ($IsLast) { ' ' } else { '│ ' })
}
}
Write-TreeLines -Node $child -Prefix $nextPrefix -IsLast:$lastChild -IsRoot:$false
}
}
# --------------------------
# Connect to Azurite
# --------------------------
# New-AzStorageContext -Local is the emulator shortcut. [4](https://outlook.office365.com/owa/?ItemID=AAMkADI5ZWNkZjcyLTZlZTUtNGViMC04N2RmLWVjYWI5OTFjYTFmZgBGAAAAAAAE8r5GwEoaSbLsP%2fgKGGRkBwCbQY81HgjDT4do75kiiXF6AAAAAAEJAACbQY81HgjDT4do75kiiXF6AAOvZefvAAA%3d&exvsurl=1&viewmodel=ReadMessageItem)
$ctx =
if ($ConnectionString) {
New-AzStorageContext -ConnectionString $ConnectionString
}
else {
New-AzStorageContext -Local
}
$root = New-Node -Name 'Azurite (devstoreaccount1)' -IsFolder:$true
$wantBlobs = ($Services -eq 'All' -or $Services -eq 'Blobs')
$wantQueues = ($Services -eq 'All' -or $Services -eq 'Queues')
$wantTables = ($Services -eq 'All' -or $Services -eq 'Tables')
# --------------------------
# Blobs: containers -> folders -> files
# --------------------------
if ($wantBlobs) {
$blobsNode = Get-OrAddChild -Parent $root -Name 'Blobs' -IsFolder:$true
# List containers. [2](https://petri.com/powertree-powershell-visualize-file-structure/)
$containers = @(Get-AzStorageContainer -Context $ctx)
if ($containers.Count -eq 0) {
[void](Get-OrAddChild -Parent $blobsNode -Name '(no containers)' -IsFolder:$false)
}
else {
foreach ($c in $containers) {
$containerNode = Get-OrAddChild -Parent $blobsNode -Name $c.Name -IsFolder:$true
# List blobs for container. [3](https://learn.microsoft.com/en-gb/answers/questions/1428061/find-files-or-directory-using-powershell-in-both-f)
$blobs = @(Get-AzStorageBlob -Container $c.Name -Context $ctx | Select-Object -First $MaxBlobsPerContainer)
if ($blobs.Count -eq 0) {
[void](Get-OrAddChild -Parent $containerNode -Name '(empty)' -IsFolder:$false)
continue
}
foreach ($b in $blobs) {
Add-BlobToTree -ContainerNode $containerNode -BlobName ([string]$b.Name)
}
}
}
}
# --------------------------
# Queues (optional)
# --------------------------
if ($wantQueues) {
# Azurite supports queues. [5](https://stackoverflow.com/questions/59615330/connecting-to-azurite-using-a-hostname-fails)
$queuesNode = Get-OrAddChild -Parent $root -Name 'Queues' -IsFolder:$truequeues. [6](https://github.com/Azure/azure-powershell/blob/main/src/Storage/Storage.Management/help/Get-AzStorageQueue.md)
$queues = @(Get-AzStorageQueue -Context $ctx)
if ($queues.Count -eq 0) {
[void](Get-OrAddChild -Parent $queuesNode -Name '(no queues)' -IsFolder:$false)
}
else {
foreach ($q in $queues) {
[void](Get-OrAddChild -Parent $queuesNode -Name $q.Name -IsFolder:$false)
}
}
}
# --------------------------
# Tables (optional)
# --------------------------
if ($wantTables) {
# Azurite supports tables. [5](https://stackoverflow.com/questions/59615330/connecting-to-azurite-using-a-hostname-fails)
$tablesNode = Get-OrAddChild -Parent $root -Name 'Tables' -IsFolder:$true
# Get-AzStorageTable lists tables..powershellgallery.com/packages/Az.Storage/3.7.0)
$tables = @(Get-AzStorageTable -Context $ctx)
if ($tables.Count -eq 0) {
[void](Get-OrAddChild -Parent $tablesNode -Name '(no tables)' -IsFolder:$false)
}
else {
foreach ($t in $tables) {
[void](Get-OrAddChild -Parent $tablesNode -Name $t.Name -IsFolder:$false)
}
}
}
# Print
Write-TreeLines -Node $root -IsRoot:$true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment