Skip to content

Commit f7b8705

Browse files
committed
Add a sample script to calculate storage account billable size.
1 parent 899f229 commit f7b8705

File tree

2 files changed

+159
-0
lines changed

2 files changed

+159
-0
lines changed

src/Storage/Commands.Storage.Test/Commands.Storage.Test.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@
134134
<None Include="app.config" />
135135
<None Include="MSSharedLibKey.snk" />
136136
<None Include="packages.config" />
137+
<None Include="Scripts\GetBillableSize.ps1" />
137138
</ItemGroup>
138139
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
139140
</Project>
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
# this script will show how to get the total size of the blobs in a container
2+
# before running this, you need to create a storage account, create a container,
3+
# and upload some blobs into the container
4+
# note: this retrieves all of the blobs in the container in one command.
5+
# connect Azure with Login-AzureRmAccount before you run the script.
6+
# command line usage: script.ps1 -ResourceGroup {YourResourceGroupName} -StorageAccountName {YourAccountName} -ContainerName {YourContainerName}
7+
#
8+
9+
param(
10+
[Parameter(Mandatory=$true)]
11+
[string]$ResourceGroup,
12+
13+
[Parameter(Mandatory=$true)]
14+
[string]$StorageAccountName,
15+
16+
[Parameter(Mandatory=$true)]
17+
[string]$ContainerName
18+
)
19+
20+
#Set-StrictMode will cause Get-AzureStorageBlob returns result in different data types when there is only one blob
21+
#Set-StrictMode -Version 2
22+
23+
$VerbosePreference = "Continue"
24+
25+
if((Get-Module -ListAvailable Azure) -eq $null)
26+
{
27+
throw "Azure Powershell not found! Please install from http://www.windowsazure.com/en-us/downloads/#cmd-line-tools"
28+
}
29+
30+
31+
32+
# function Get-BlobBytes
33+
34+
function Get-BlobBytes
35+
{
36+
param(
37+
[Parameter(Mandatory=$true)]
38+
$Blob)
39+
40+
# Base + blobname
41+
$blobSizeInBytes = 124 + $Blob.Name.Length * 2
42+
43+
# Get size of metadata
44+
$metadataEnumerator=$Blob.ICloudBlob.Metadata.GetEnumerator()
45+
while($metadataEnumerator.MoveNext())
46+
{
47+
$blobSizeInBytes += 3 + $metadataEnumerator.Current.Key.Length + $metadataEnumerator.Current.Value.Length
48+
}
49+
50+
if($Blob.BlobType -eq [Microsoft.WindowsAzure.Storage.Blob.BlobType]::BlockBlob)
51+
{
52+
$blobSizeInBytes += 8
53+
# Default is Microsoft.WindowsAzure.Storage.Blob.BlockListingFilter.Committed. Need All
54+
$Blob.ICloudBlob.DownloadBlockList([Microsoft.WindowsAzure.Storage.Blob.BlockListingFilter]::All) |
55+
ForEach-Object { $blobSizeInBytes += $_.Length + $_.Name.Length }
56+
}
57+
else
58+
{
59+
$Blob.ICloudBlob.GetPageRanges() |
60+
ForEach-Object { $blobSizeInBytes += 12 + $_.EndOffset - $_.StartOffset }
61+
}
62+
63+
return $blobSizeInBytes
64+
}
65+
66+
# function Get-ContainerBytes
67+
68+
function Get-ContainerBytes
69+
{
70+
param(
71+
[Parameter(Mandatory=$true)]
72+
[Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer]$Container)
73+
74+
# Base + name of container
75+
$containerSizeInBytes = 48 + $Container.Name.Length*2
76+
77+
# Get size of metadata
78+
$metadataEnumerator = $Container.Metadata.GetEnumerator()
79+
while($metadataEnumerator.MoveNext())
80+
{
81+
$containerSizeInBytes += 3 + $metadataEnumerator.Current.Key.Length + $metadataEnumerator.Current.Value.Length
82+
}
83+
84+
# Get size for SharedAccessPolicies
85+
$containerSizeInBytes += $Container.GetPermissions().SharedAccessPolicies.Count * 512
86+
87+
# Calculate size of all blobs.
88+
$blobCount = 0
89+
$Token = $Null
90+
$MaxReturn = 5000
91+
92+
do {
93+
$Blobs = Get-AzureStorageBlob -Context $storageContext -Container $Container.Name -MaxCount $MaxReturn -ContinuationToken $Token
94+
if($Blobs -eq $Null) { break }
95+
96+
#Set-StrictMode will cause Get-AzureStorageBlob returns result in different data types when there is only one blob
97+
if($Blobs.GetType().Name -eq "AzureStorageBlob")
98+
{
99+
$Token = $Null
100+
}
101+
else
102+
{
103+
$Token = $Blobs[$Blobs.Count - 1].ContinuationToken;
104+
}
105+
106+
$Blobs | ForEach-Object {
107+
$blobSize = Get-BlobBytes $_
108+
$containerSizeInBytes += $blobSize
109+
$blobCount++
110+
111+
if(($blobCount % 1000) -eq 0)
112+
{
113+
Write-Verbose("Counting {0} Sizing {1} " -f $blobCount, $containerSizeInBytes)
114+
}
115+
}
116+
}
117+
While ($Token -ne $Null)
118+
119+
return @{ "containerSize" = $containerSizeInBytes; "blobCount" = $blobCount }
120+
}
121+
122+
#Login-AzureRmAccount
123+
124+
$storageAccount = Get-AzureRmStorageAccount -ResourceGroupName $ResourceGroup -Name $StorageAccountName -ErrorAction SilentlyContinue
125+
if($storageAccount -eq $null)
126+
{
127+
throw "The storage account specified does not exist in this subscription."
128+
}
129+
130+
$storageContext = $storageAccount.Context
131+
132+
$containers = New-Object System.Collections.ArrayList
133+
if($ContainerName.Length -ne 0)
134+
{
135+
$container = Get-AzureStorageContainer -Context $storageContext -Name $ContainerName -ErrorAction SilentlyContinue |
136+
ForEach-Object { $containers.Add($_) } | Out-Null
137+
}
138+
else
139+
{
140+
Get-AzureStorageContainer -Context $storageContext | ForEach-Object { $containers.Add($_) } | Out-Null
141+
}
142+
143+
$sizeInBytes = 0
144+
145+
if($containers.Count -gt 0)
146+
{
147+
$containers | ForEach-Object {
148+
Write-Output("Calculating container {0} ..." -f $_.CloudBlobContainer.Name)
149+
$result = Get-ContainerBytes $_.CloudBlobContainer
150+
$sizeInBytes += $result.containerSize
151+
152+
Write-Output("Container '{0}' with {1} blobs has a sizeof {2:F2} MB." -f $_.CloudBlobContainer.Name,$result.blobCount,($result.containerSize/1MB))
153+
}
154+
}
155+
else
156+
{
157+
Write-Warning "No containers found to process in storage account '$StorageAccountName'."
158+
}

0 commit comments

Comments
 (0)