%3CLINGO-SUB%20id%3D%22lingo-sub-1273322%22%20slang%3D%22en-US%22%3EPowerShell%20Basics%3A%20How%20to%20Upload%20Files%20to%20Azure%20Storage%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1273322%22%20slang%3D%22en-US%22%3E%3CP%3EIn%20recent%20days%20there%20has%20been%20a%20push%20to%20move%20our%20team's%20in-person%20presentations%20online.%26nbsp%3B%20In%20some%20cases%20we've%20been%20asked%20to%20record%20our%20presentations.%26nbsp%3B%20Storage%20has%20quickly%20become%20an%20issue%20and%20so%20I%20have%20been%20investigating%20ways%20to%20transfer%20the%20recorded%20presentations%20to%20the%20cloud.%26nbsp%3B%20Now%20the%20transfer%20can%20take%20place%20via%20GUI%20however%20automating%20the%20transfer%20might%20be%20needed%20in%20future.%26nbsp%3B%20Luckily%20uploading%20files%20to%20Azure%20Storage%20via%20PowerShell%20is%20an%20option.%26nbsp%3B%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ELets%20get%20started%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3COL%3E%0A%3CLI%3ERun%20PowerShell%20as%20Administrator%3CBR%20%2F%3E%26nbsp%3B%3C%2FLI%3E%0A%3CLI%3EInstall%20the%20%3CSTRONG%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-ca%2Fpowershell%2Fazure%2Finstall-az-ps%3Fview%3Dazps-3.7.0%26amp%3BWT.mc_id%3DITOPSTALK-blog-abartolo%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EAzure%20PowerShell%20Module%3C%2FA%3E%3C%2FSTRONG%3E%20via%20the%20following%20command%3A%3CBR%20%2F%3E%3CPRE%3EInstall-Module%20-Name%20Az%20-AllowClobber%26nbsp%3B%3C%2FPRE%3E%0A%3C%2FLI%3E%0A%26nbsp%3B%0A%3CLI%3ERun%20the%20following%20script%20to%20transfer%20a%20specified%20file%20to%20Azure%20Storage%3A%3CBR%20%2F%3E%0A%3CPRE%3E%24StorageURL%20%3D%20%22https%3A%2F%2F%26lt%3Bstoragename%26gt%3B.blob.core.windows.net%2FSTORAGE_CONTINER%2F%22%0A%24FileName%20%3D%20%22%26lt%3Bfilename%26gt%3B%22%0A%24SASToken%20%3D%20%22st%3D2020-03-10T23%253A19%253A17Z%26amp%3Bse%3D2020-03-11T23%253A19%253A17Z%26amp%3Bsp%3Drl%26amp%3Bsv%3D2018-03-28%26amp%3Bsr%3Db%26amp%3Bsig%3DRANDOMCHARS%22%0A%0A%24blobUploadParams%20%3D%20%40%7B%0A%20%20%20%20URI%20%3D%20%22%7B0%7D%2F%7B1%7D%3F%7B2%7D%22%20-f%20%24StorageURL%2C%20%24FileName%2C%20%24SASToken%0A%20%20%20%20Method%20%3D%20%22PUT%22%0A%20%20%20%20Headers%20%3D%20%40%7B%0A%20%20%20%20%20%20%20%20'x-ms-blob-type'%20%3D%20%22BlockBlob%22%0A%20%20%20%20%20%20%20%20'x-ms-blob-content-disposition'%20%3D%20%22attachment%3B%20filename%3D%60%22%7B0%7D%60%22%22%20-f%20%24FileName%0A%20%20%20%20%20%20%20%20'x-ms-meta-m1'%20%3D%20'v1'%0A%20%20%20%20%20%20%20%20'x-ms-meta-m2'%20%3D%20'v2'%0A%20%20%20%20%7D%0A%20%20%20%20Body%20%3D%20%24Content%0A%20%20%20%20Infile%20%3D%20%24FileToUpload%0A%7D%3C%2FPRE%3E%0A%3CSTRONG%3ENOTE%3A%3C%2FSTRONG%3E%20Be%20sure%20to%20replace%20%3CSTRONG%3E%3CSTORAGENAME%3E%3C%2FSTORAGENAME%3E%3C%2FSTRONG%3E%20found%20in%20%3CEM%3Eline%201%3C%2FEM%3E%20and%20%3CSTRONG%3E%3CFILENAME%3E%3C%2FFILENAME%3E%3C%2FSTRONG%3E%20found%20in%20%3CEM%3Eline%202%3C%2FEM%3E.%3C%2FLI%3E%0A%3C%2FOL%3E%0A%3CP%3EAs%20always%2C%20please%20share%20your%20comments%20below%20on%20bettering%20the%20above%20script%20or%20any%20questions%20you%20may%20have.%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-1273322%22%20slang%3D%22en-US%22%3E%3CP%3EIn%20recent%20days%20there%20has%20been%20a%20push%20to%20move%20our%20team's%20in-person%20presentations%20online.%26nbsp%3B%20In%20some%20cases%20we've%20been%20asked%20to%20record%20our%20presentations.%26nbsp%3B%20Storage%20has%20quickly%20become%20an%20issue%20and%20so%20I%20have%20been%20investigating%20ways%20to%20transfer%20the%20recorded%20presentations%20to%20the%20cloud.%26nbsp%3B%20Now%20the%20transfer%20can%20take%20place%20via%20GUI%20however%20automating%20the%20transfer%20might%20be%20needed%20in%20future.%26nbsp%3B%20Luckily%20uploading%20files%20to%20Azure%20Storage%20via%20PowerShell%20is%20an%20option.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22PowerShell_Basics.jpg%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F134944iD72B3B0B8F4E0886%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%22PowerShell_Basics.jpg%22%20alt%3D%22PowerShell%20Basics%3A%20How%20to%20Upload%20Files%20to%20Azure%20Storage%22%20%2F%3E%3CSPAN%20class%3D%22lia-inline-image-caption%22%20onclick%3D%22event.preventDefault()%3B%22%3EPowerShell%20Basics%3A%20How%20to%20Upload%20Files%20to%20Azure%20Storage%3C%2FSPAN%3E%3C%2FSPAN%3E%3C%2FP%3E%3C%2FLINGO-TEASER%3E%3CLINGO-LABS%20id%3D%22lingo-labs-1273322%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3EAnthony%20Bartolo%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EAzure%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EPowerShell%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1275599%22%20slang%3D%22en-US%22%3ERe%3A%20PowerShell%20Basics%3A%20How%20to%20Upload%20Files%20to%20Azure%20Storage%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1275599%22%20slang%3D%22en-US%22%3E%3CP%3ENice.%20But%20don%E2%80%99t%20teach%20bud%20habits%20%3B).%20Passing%20a%20secret%20(%24SASToken)%20as%20an%20parameter%20in%20URI%20is%20insecure%20(URI%20is%20never%20encrypted).%26nbsp%3B%24SASToken%20should%20be%20provided%20as%20one%20of%20the%20headers.%20Headers%20are%20encrypted%20by%20TLS.%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1275605%22%20slang%3D%22en-US%22%3ERe%3A%20PowerShell%20Basics%3A%20How%20to%20Upload%20Files%20to%20Azure%20Storage%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1275605%22%20slang%3D%22en-US%22%3E%3CP%3EExcellent%20catch%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F134208%22%20target%3D%22_blank%22%3E%40Tomasz%20Ol%C4%99dzki%3C%2FA%3E.%20How%20would%20you%20modify%20the%20script%20to%20correct%20this%3F%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1277028%22%20slang%3D%22en-US%22%3ERe%3A%20PowerShell%20Basics%3A%20How%20to%20Upload%20Files%20to%20Azure%20Storage%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1277028%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F102838%22%20target%3D%22_blank%22%3E%40Anthony%20Bartolo%3C%2FA%3EOuch%2C%20docs%20don't%20mention%20a%20way%20how%20to%20put%20SAS%20Token%20in%20the%20headers%20of%20the%20request.%20Only%20Shared%20Key%20can%20be%20sent%20in%20the%20%22Authorization%22%20header.%20I've%20asked%20is%20this%20really%20secure%20approach%3A%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2FMicrosoftDocs%2Fazure-docs%2Fissues%2F51600%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%22%3Ehttps%3A%2F%2Fgithub.com%2FMicrosoftDocs%2Fazure-docs%2Fissues%2F51600%3C%2FA%3E.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3ERef%3A%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fstorage%2Fcommon%2Fstorage-sas-overview%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%22%3Ehttps%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fstorage%2Fcommon%2Fstorage-sas-overview%3C%2FA%3E.%3C%2FP%3E%3C%2FLINGO-BODY%3E
Microsoft

In recent days there has been a push to move our team's in-person presentations online.  In some cases we've been asked to record our presentations.  Storage has quickly become an issue and so I have been investigating ways to transfer the recorded presentations to the cloud.  Now the transfer can take place via GUI however automating the transfer might be needed in future.  Luckily uploading files to Azure Storage via PowerShell is an option.  

 

Lets get started:

 

  1. Run PowerShell as Administrator
     
  2. Install the Azure PowerShell Module via the following command:
    Install-Module -Name Az -AllowClobber 
  3.  
  4. Run the following script to transfer a specified file to Azure Storage:
    $StorageURL = "https://<storagename>.blob.core.windows.net/STORAGE_CONTINER/"
    $FileName = "<filename>"
    $SASToken = "st=2020-03-10T23%3A19%3A17Z&se=2020-03-11T23%3A19%3A17Z&sp=rl&sv=2018-03-28&sr=b&sig=RANDOMCHARS"
    
    $blobUploadParams = @{
        URI = "{0}/{1}?{2}" -f $StorageURL, $FileName, $SASToken
        Method = "PUT"
        Headers = @{
            'x-ms-blob-type' = "BlockBlob"
            'x-ms-blob-content-disposition' = "attachment; filename=`"{0}`"" -f $FileName
            'x-ms-meta-m1' = 'v1'
            'x-ms-meta-m2' = 'v2'
        }
        Body = $Content
        Infile = $FileToUpload
    }
    NOTE: Be sure to replace <storagename> found in line 1 and <filename> found in line 2.

As always, please share your comments below on bettering the above script or any questions you may have.

4 Comments
Senior Member

Nice. But don’t teach bud habits ;). Passing a secret ($SASToken) as an parameter in URI is insecure (URI is never encrypted). $SASToken should be provided as one of the headers. Headers are encrypted by TLS.

Microsoft

Excellent catch @Tomasz Olędzki. How would you modify the script to correct this?

Senior Member

@Anthony BartoloOuch, docs don't mention a way how to put SAS Token in the headers of the request. Only Shared Key can be sent in the "Authorization" header. I've asked is this really secure approach: https://github.com/MicrosoftDocs/azure-docs/issues/51600.

 

Ref: https://docs.microsoft.com/en-us/azure/storage/common/storage-sas-overview.

Senior Member

@Tomasz Olędzki, I don't believe it is a real concern.

The TLS connection is established first and at a lower layer than the HTTP protocol which is build on top. The only things that could be intercepted are IP and hostname via SNI I guess.

The only concerns are: URIs might be logged by the terminating endpoint (not the case as in this case it is the Azure Storage endpoint); URIs are kept in browser's history (not the case); and URIs can be shared (not the case).