Publish-AzureBlob.ps1
# This script publishes blobs to Azure Storage and outputs a URL for read access. # It is used for publishing VM images and other "it is a big file" type of outputs. # # There are two types of possible inputs: files on local disk and other blobs already in Azure Storage. # The latter allows "labeling" - you publish some file at first and then publish the already-existing # blob as a "stable" version when you decide that your initial upload is a good result. # # Requires AzureRM PowerShell module. function Publish-AzureBlob { [CmdletBinding()] param( # Name of the blob to create. If it already exists, it is overwritten. [Parameter(Mandatory = $True)] [string]$blobName, # Name of the storage container to create the blob in. # Will be created if it does not already exist. [Parameter(Mandatory = $True)] [string]$containerName, # Azure Storage connection string. [Parameter(Mandatory = $True)] [string]$connectionString, # Azure CDN hostname. The hostname in the published URL will be replaced with this if provided. [Parameter()] [string]$cdn, # If you are going to overwrite the contents of this blob later, it may be desirable to disable caching. # Otherwise the changes may not show up right away when the blob is accessed through caches/CDN. [Parameter()] [switch]$noCache, # Path to the file to publish if the input is a file. [Parameter(ParameterSetName = "FromFile", Mandatory = $True)] [string]$path, # Name of an existing blob to publish under the new name. [Parameter(ParameterSetName = "FromBlob", Mandatory = $True)] [string]$sourceBlobName, # Name of the container that contains the existing blob. [Parameter(ParameterSetName = "FromBlob", Mandatory = $True)] [string]$sourceContainerName ) $azureContext = New-AzureStorageContext -ConnectionString $connectionString # Ensure the container exists. New-AzureStorageContainer $containerName -Context $azureContext -ErrorAction SilentlyContinue | Out-Null $properties = @{ "CacheControl" = "" } if ($noCache) { # Stick a lot of directives in there, as different caches seem to (mis)behave differently. $properties["CacheControl"] = "no-cache, no-store, must-revalidate, max-age=0" } if ($path) { Write-Host "Uploading $path to $containerName/$blobName" $blob = Set-AzureStorageBlobContent -File $path -Blob $blobName -Container $containerName -Force -Context $azureContext -Properties $properties } else { Write-Host "Copying $sourceContainerName/$sourceBlobName to $containerName/$blobName" $blob = Start-AzureStorageBlobCopy -SrcBlob $sourceBlobName -SrcContainer $sourceContainerName -DestBlob $blobName -DestContainer $containerName -Force -Context $azureContext Write-Verbose "Waiting for copy to finish." $blob | Get-AzureStorageBlobCopyState -WaitForComplete | Out-Null $blob.ICloudBlob.Properties.CacheControl = $properties["CacheControl"] $blob.ICloudBlob.SetProperties() } # It needs an expiration but we do not want it to expire. 10 years should be enough for everybody. $blobUrl = New-AzureStorageBlobSASToken -CloudBlob $blob.ICloudBlob -FullUri -Permission "r" -Context $azureContext -ExpiryTime (Get-Date).AddYears(10) if ($cdn) { # Replace hostname. Should cover most CDN scenarios nice and proper. Write-Host "Blog URL will target the CDN endpoint $cdn" $builder = New-Object UriBuilder -ArgumentList $blobUrl $builder.Host = $cdn $blobUrl = $builder.Uri.AbsoluteUri } Write-Host "Publishing blob public URL" Write-Output $blobUrl } |