I have an Azure Storage (StorageV2), and I want to connect and upload files via Powershell.
However, I want to use the Connection String (which contains a long secret key). So people without a Microsoft account should be able to use the script.
There is the command Connect-AzAccount, but for this, it seems you need to have a Microsoft account.
So how is it possible to connect and upload just with the Connection String and without having a Microsoft account?
Each Cmdlet in Az.Storage module expects a -Context parameter. You can use New-AzStorageContext Cmdlet to set that context and pass that context to the Cmdlet (e.g. for uploading blob).
If you have the connection string for your storage account, you would create a context like:
$ctx = New-AzStorageContext -ConnectionString "your-storage-account-connection-string"
and use it like the following:
Set-AzStorageBlobContent -Context $ctx ...rest of the parameters
Related
Requirement is to store the file in Storage account through Azure functions in PowerShell using Az module. Please help.
$todaydate = Get-Date -Format MM-dd-yy
$LogFull = "AzureScan-$todaydate.log"
$LogItem = New-Item -ItemType File -Name $LogFull
" Text to write" | Out-File -FilePath $LogFull -Append
First of all, what you need to figure out is the input of your function and how you're handling that. If you're just wanting to write a file to blob storage everytime an HTTP triggered Azure function is executed then that is simple enough.
There are a number of elements that come into play when working with blob storage with Azure Functions however that you will need to understand to develop a working solution.
Managed Identities
Azure Funtions are able to be assigned an identity so that you can grant access to the FunctionApp itself rather than having to authenticate as a user. This means you don't have to handle the authentication aspect of your function to access the storage account content and you just need to grant your FunctionApp the relevant permissions to read/write/delete blob or storage content.
There are a number of built in RBAC roles in AzureAD which you can grant to access storage accounts and blobs etc.
You can find the documentation on the RBAC permissions for that here: https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#storage
and the documentation on how to activate a managed identity on your functionApp can be found here: https://learn.microsoft.com/en-us/azure/app-service/overview-managed-identity?tabs=dotnet#add-a-system-assigned-identity
Storage Account(s)
Programmatically accessing storage account contents depends on the permissions but you can use the access keys associated to the storage account which provide access to at the storage account level
You can read about the access keys here: https://learn.microsoft.com/en-us/azure/storage/common/storage-account-keys-manage?tabs=azure-portal#view-account-access-keys
Just remember that least-privilege access should be adopted and if you leak your keys then someone could access your data.
PowerShell Commands
The PowerShell commands required for programmatically accessing storage accounts and writing blob data can be summarised below
# Variables required - Fill these out
$storageAccountName = '<Insert Storage Account Here'
$containerName = '<Insert StorageContainer Name Here>'
# Set the context to the subscription you want to use
# If your functionApp has access to more than one subscription it will load the first subscription by default.
# Possibly a good habit to be explicit about context.
Set-AzContext -Subscription $subscription
# Get the Storage Account Key to authenticate
$storAccKeys = Get-AzStorageAccountKey -ResourceGroupName 'Storage-ResourceGroup' -Name $storageAccountName
$primaryKey = $storAccKeys | Where-Object keyname -eq 'key1' | Select-Object -ExpandProperty value
# Create a Storage Context which will be used in the subsequent commands
$storageContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $primaryKey
# Attempt to create a container in the storage account. Handle Error appropriately.
try {
New-AzStorageContainer -Name $containerName -Context $storageContext -ErrorAction Stop
}
catch [Microsoft.WindowsAzure.Commands.Storage.Common.ResourceAlreadyExistException] {
Write-Output ('Container {0} already exists in Storage Account {1}' -f $containerName, $storageAccountName)
# Throw Here if you want it to fail instead.
}
catch {
throw $_
}
# Upload your file here. This may vary depending on your function input and how you plan to have your functionApp work.
Set-AzStorageBlobContent -Container $containerName -File ".\PlanningData" -Blob "Planning2015"
You can see the documentation on Set-AzStorageBlobContent for examples on that here:
https://learn.microsoft.com/en-us/powershell/module/az.storage/set-azstorageblobcontent?view=azps-6.2.1#examples
Generally though you will need a file to upload to blob storage and you can't just write directly to a file in blob storage.
If you need to read more on the Azure Functions side of things then there is the quickstart guide:
https://learn.microsoft.com/en-us/azure/azure-functions/create-first-function-vs-code-powershell
Or the Developer Reference on MS docs is really detailed:
https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-powershell?tabs=portal
I'm not proficient in Powershell yet, so please bear with me if I use the incorrect terminology.(And please correct me if I do.)
I have installed the Az and Azure.Storage modules.
I have also connected to my account using Connect-AZAccount (Is this the best way? Since you need to copy the URL and login via a browser)
Then I was just trying to view the files, to test the connection. Using Get-AzureStorageFile
This prompts me for a sharename - I used the name of the folder under File Shares in Azure Storage Explorer. But this failed, see failure below
cmdlet Get-AzureStorageFile at command pipeline position 1 Supply
values for the following parameters: (Type !? for Help.) ShareName:
bss get-azurestoragefile : Could not get the storage context. Please
pass in a storage context or set the current storage context.
Additional information to note, I do not have access to the Account Key, only the SAS Token.
Any help would be appreciated.
If you use Connect-AzAccount, you will use the Az module powershell Get-AzStorageFile instead of Get-AzureStorageFile. Before running the Get-AzStorageFile command, you need to pass the storage context with New-AzStorageContext to fix the error.
Sample:
$context = New-AzStorageContext -StorageAccountName "<StorageAccountName>" -StorageAccountKey "<StorageAccountKey>"
Get-AzStorageFile -ShareName "<ShareName>" -Path "<ContosoWorkingFolder>" -Context $context
I am working on developing a Automated QA script for my project for my organisation. My goal is to execute pester scripts through custom script extension feature of azure vms. I got the Pester executed and result exported as a nunit xml. I would like to fetch the xml back from VM to my local machine. One way of doing that is by uploading the xml into blob storage from VMs. but since it requires azure connection to be established in VM using SP account. I dont prefer this method.
I would like to know the best way to retrive pester results and get it outside VM.
Any help is much appreciated. Thanks .
I'd use a shared access signature token for that (link). that way your script doesnt really need SP, it just needs the token. that token would limit permissions to only upload file to specific container (or even blob).
$sascontext = New-AzureStorageContext -StorageAccountName accountname -SasToken '?tokenvalue'
Set-AzureStorageBlobContent -File path -Container name -Context $sascontext -Force
You can create new token with New-AzureStorageBlobSASToken or New-AzureStorageContainerSASToken
Your only requirement would be to install Azure.Storage module before hand.
When creating a SASToken via powershell it retunrs the created SAS token url from New-AzureStorageContainerSASToken comdlet.
$Context = New-AzureStorageContext -StorageAccountName $StorageAccount -StorageAccountKey $StorageAccountKey
$now = Get-Date
$sasUrl = New-AzureStorageContainerSASToken -Name mycontainer -Permission rwdl -StartTime $now.AddHours(-1) -ExpiryTime $now.AddMonths(1) -Context $context -FullUri
echo $sasUrl
But now in case I lost it, how can I list the exiting SASTokens? You may have few on the same container.
Tried Get-AzureStorageContainer but this information is unavailable.
Played with other Get-AzureStorage* and failed to find it.
Is this operation supported via powershell?
It is not possible to get the list of SAS URLs because they are not stored anywhere in Azure Storage.
Probably a bit late.... but on this page:
https://learn.microsoft.com/en-us/azure/storage/storage-dotnet-shared-access-signature-part-1
It says:
"The SAS token generated by the storage client library is not tracked by Azure Storage in any way. You can create an unlimited number of SAS tokens on the client side."
HTH!
Paul
With Powershell perhaps not, but Perhaps possible with the REST API: https://learn.microsoft.com/en-us/rest/api/storagerp/storageaccounts/listaccountsas
For the POST request, some of the request body parameters are REQUIRED to be filled which will need trial and error as you may not remember for what duration the SAS was allowed for. But provided all the values at https://learn.microsoft.com/en-us/rest/api/storagerp/storageaccounts/listaccountsas#request-body are somehow documented , then it should be programmatically possible to get the SAS token itself.
I think you don't understand how SAS token works: Generated SAS tokens are not stored anywhere because when you generate a SAS token, no call is made to the Azure Storage server. This is just a local calculation based on the secret key (like an asymetrical encryption with public and private key)
I have just started using Azure and I am facing issues using the PowerShell cmdlets to work with my storage account.
I have created a Storage account and a container in that storage account. Next I installed the Azure Powershell SDK and command lets etc. and imported the publishsettings file. When I do the Get-AzureSubscription or Get-AzureStorageAccount command it correctly shows my subscription in the PowerShell console along with various storage end points.
However if I do a Get-AzureStorageBlob call or a Set-AzureStorageBlobContent I get the following error
Get-AzureStorageBlob : Can not find your azure storage credential. Please set current storage account using
"Set-AzureSubscription" or set the "AZURE_STORAGE_CONNECTION_STRING" environment variable.
I am literally at wits ends here. A Google search on this error string only brings up references to code on Github etc. Would really appreciate some help.
Right so I finally managed to do this! Here is the overall details on how to use PowerShell to create a blob in Azure and store a file there.
http://www.nikgupta.net/2013/09/azure-blob-storage-powershell/
$context = New-AzureStorageContext -StorageAccountName FunkyStorage -StorageAccountKey {Enter your storage account key here}
Set-AzureStorageBlobContent -Blob "MyFunkyBlob" -Container FunkyContainer-File "c:\temp\1.txt" -Context $context -Force
You may need to set the 'current' subscription to use. For that, you must run Select-AzureSubscription.
If you run Get-AzureSubscription, you'll see all subscriptions in your publish settings. One of those subscriptions should be set as the default. As you scroll through the result list, you'll see one property, IsDefault for each subscription, set to True or False. If the subscription you're using is set to False, run:
Select-AzureSubscription -SubscriptionName mysub
Hopefully that fixes the issue you're running into.
Just a quick FYI: you can do this another (and faster way). I build a web language atop Windows PowerShell that heavily integrates with Azure. It's called PowerShell Pipeworks.
You can use 4 cmdlets to interact with the blobs:
Get-Blob
Import-Blob
Export-Blob
Remove-Blob
All take a -StorageAccount and a -StorageKey, and also a -StorageAccountSetting and a -StorageKeySetting. You can save creds to disk (or for use in a web app by using Add-SecureSetting). Once any blob cmdlet has a storage account, it will continue to reuse it.
Export-Blob is also handy in that you can pipe in a directory to it, and it will create the right content types, and provide -Public, which will mark the container it's stored in as public.
These cmdlets are a notch older (~3 months) than the Azure ones, and still about 3/4ths the time to execute (I believe a major chunk of this is their slower lookup on credentials), and are worth a try.