powershellazure-blob-storageazure-powershellazure-sas

Using Only a SAS Token To Upload in PowerShell


I have a SAS Token in the form:

https://name.blob.core.windows.net/container?sv=2015-04-05&sr=b&sig=abc123&se=2017-03-07T12%3A58%3A52Z&sp=rw

I am attempting to use an Az Provided Cmdlet in Powershell to upload content to this blob. I am unable to find an API that simply takes the above SAS token and a file to upload.

Reading this reddit post it seems like my options are:

  1. Parse out the StorageAccountName (in the example name), Container (in the example container) and SASToken (in the example above sv=2015-04-05&sr=b&sig=abc123&se=2017-03-07T12%3A58%3A52Z&sp=rw) and then use New-AzStorageContext/Set-AzStorageBlobContent. This more or less is the answer in this StackOverflow Post (Connect to Azure Storage Account using only SAS token?)
  2. Use Invoke-WebRequest or its kin to basically perform the REST call myself.

I would like to use as many Az provided cmdlets possible so starting with option 1, there doesn't seem to be an API to parse this, the closest I can find is this StackOverflow Post (Using SAS token to upload Blob content) talking about using CloudBlockBlob, however it is unclear if this class is available to me in PowerShell.

To these ends I've created a Regex that appears to work, but is most likely brittle, is there a better way to do this?

$SASUri = https://name.blob.core.windows.net/container?sv=2015-04-05&sr=b&sig=abc123&se=2017-03-07T12%3A58%3A52Z&sp=rw
$fileToUpload = 'Test.json'

$regex = [System.Text.RegularExpressions.Regex]::Match($SASUri, '(?i)\/+(?<StorageAccountName>.*?)\..*\/(?<Container>.*)\?(?<SASToken>.*)')
$storageAccountName = $regex.Groups['StorageAccountName'].Value
$container = $regex.Groups['Container'].Value
$sasToken = $regex.Groups['SASToken'].Value

$storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -SasToken $sasToken
Set-AzStorageBlobContent -File $fileToUpload -Container $container -Context $storageContext -Force

To Restate The Questions

  1. Is there an Az Cmdlet that takes the SAS URI and SAS Token to allow upload?
  2. (If not) Is there an API to parse the SAS URI + SAS Token?

Solution

  • Considering $SASUri is a URI, you can get a System.Uri object using something like:

    $uri = [System.Uri] $SASUri
    

    Once you have that, you can get the container name and the SAS token using something like:

    $storageAccountName = $uri.DnsSafeHost.Split(".")[0]
    $container = $uri.LocalPath.Substring(1)
    $sasToken = $uri.Query
    
    

    After that your code should work just fine:

    $storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -SasToken $sasToken
    Set-AzStorageBlobContent -File $fileToUpload -Container $container -Context $storageContext -Force