I'm working on PS script to list all Storage Accounts, which contains files with a modified date less than < X.
I'm able to list all SA containers, it's not a big deal but I'm not sure how to get further and list all files inside a particular container.
$storageAccCtx = (Get-AzStorageAccount -Name acc_name -ResourceGroupName acc_rg).Context
Get-AzStorageContainer -Context $storageAccCtx
I couldn't find any cmdlet for this.
Could anyone, please, advise what should I use next? Thanks.
Once you have the StorageContext, you can use this below Azure Storage Management Cmdlet to list all BlockBlob.
Get-AzStorageBlob -Container containerName -Context $storageAccCtx
To get list of all Azure Storage Management Cmdlet, please follow this documentation https://learn.microsoft.com/en-us/powershell/module/az.storage/?view=azps-4.8.0
You can use Get-AzStorageBlob to list the blobs in a storage container, the cmdlet is documented here. In a script you could use this cmdlet as follows to return all the blobs older than a particular date:
$CutOffDate = Get-Date -Year 2020 -Month 10 -Day 19
$OldBlobs = #()
$StorageAccounts = Get-AzStorageAccount
foreach ($StorageAccount in $StorageAccounts) {
$Containers = Get-AzStorageContainer -Context $StorageAccount.Context
foreach ($Container in $Containers) {
$ContainerBlobs = Get-AzStorageBlob -Container $Container.Name -Context $StorageAccount.Context
$OldBlobs += $ContainerBlobs | Where-Object { $_.LastModified -lt $CutOffDate }
}
}
$OldBlobs
Related
First post. My Powershell knowledge isnt great. I am trying to list out all containers that have the "PublicAccess" attribute set to On. I am trying to use the script provided by MS.
$rgName = "<Resource Group name>"
$accountName = "<Storage Account Name>"
$storageAccount = Get-AzStorageAccount -ResourceGroupName $rgName -Name $accountName
$ctx = $storageAccount.Context
Get-AzStorageContainer -Context $ctx | Select Name, PublicAccess
However I need to do this on a large amount of storage accounts. In the past I have used "foreach($item in $list)" to pass things into a small script. But never for multiple lists. Can anyone help?
Based off your extended requirements in the comments, this should work. (I've not tested it and not handled any potential errors related to permissions or anything else)
# Create a collection for the items found.
$StorageAccounts = [System.Collections.Generic.List[System.Object]] #{}
# Loop through the available Azure contexts.
foreach ($Context in (Get-AzContext -ListAvailable)) {
# Set each subscription in turn, voiding the output.
[System.Void](Set-AzContext -Context $Context)
# Create an object with the container name, public access values and the name of the storage account/subscription.
$StorageAccountInfo = Get-AZStorageAccount | Get-AzStorageContainer | Select-Object Name, PublicAccess, #{l = "StorageAccountName"; e = { $_.Context.StorageAccountName } }, #{l = "Subscription"; e = { $Context.Subscription.Name } }
# If there is data found, add it to the collection.
if ($null -ne $StorageAccountInfo) {
$StorageAccounts.AddRange($StorageAccountInfo)
}
}
# Export the collected information to Csv.
$StorageAccounts | Export-Csv -Path .\myStorageAccounts.csv -NoClobber -Encoding utf8
I'm developing a new powershell script in order to download any blobs from a specific container and the problem is due to security reasons because I do not want to paste in text plain the azure account key.
So I have implemented a solution using 'ConvertTo-SecureString' command but the problem still exists because when I create a connection string to the blob, there appears a message who said: "Server Failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. HTTP Status Code 403 - HTTP Error".
With the key in plain text I'm able to create the connection string properly and then list and download all blobs from the container.
I tried other solutions for example ' $Credential= New-Object System.Management.Automation.PSCredential ('$ShareUser, $SharePassword)'
but there is other problem related with the input is not valid base64 string.
Do you know how to avoid this issues and create a secure connection string with an Azure Storage Account?
Best regards and thanks in advance
Here a part of my powershell script
$SecurePassword= Read-Host -AsSecureString | ConvertFrom-SecureString
$SecurePassword | Out-File -FilePath C:\test_blob\pass_file.xml
$ConfigFile= 'C:\Users\\config_file.xml'
IF (Test-Path) {
[xml]$Config= Get-Content $ConfigFile
[string] $Server = $Config.Config.Server;
[string] $SharePassword = $Config.Config.SharePassword;
} ELSE
{
write-host "File do not exists: $ConfigFile"
}
#BlobStorageInformation
$StorageAccountName='test_acc'
$Container='test'
$DestinationFolder= 'C:\Users\user1\Blobs'
$Context = New-AzStorageConext -StorageAccountName $StorageAccountName -StorageAccountKey $SharePassword
#List of Blobs
$ListBlob=#()
$ListBlob+= Get-AzStorageBlob -context $Context -container $Container | Where-Object {$_.LastModified -lt (Get-Date).AddDAys(-1)}
Why would you maintain the password files or enter storage key manually when you have az powershell. Just login using az powershell, set the subscription and enjoy !
$ResourceGroupName = "YOURRESOURCEGROUPNAME"
$StorageAccountName = "YOURSTORAGEACCOUNTNAME"
$ContainerName = "YOURCONTAINERNAME"
$LocalPath = "D:\Temp"
Write-Output 'Downloading Content from Azure blob to local...'
$storageKey = (Get-AzStorageAccountKey -ResourceGroupName $ResourceGroupName -AccountName $StorageAccountName).value[0]
$storageContext = New-AzStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $storageKey
$blobs = Get-AzStorageBlob -Container $ContainerName -Context $storageContext
foreach($blob in $blobs)
{
Get-AzStorageBlobContent -Container $ContainerName -Context $storageContext -Force -Destination $LocalPath -Blob $blob.Name
}
Write-Output 'Content Downloaded Successfully !!!'
It's very easy to list azure managed disks in PS, but unmanaged ones are very tricky to list, as they're not objects from azure POV. I tried to wrote foreach loop to list me all unamanged disks (i.e. *.vhd files) for each storage account. This is the code I wrote:
$StorageAccounts = Get-AzureRmStorageAccount
$sa = $StorageAccounts | foreach-object {
#Get the Management key for the storage account
$key1 = (Get-AzureRmStorageAccountKey -ResourceGroupName $_.ResourceGroupName -name $_.StorageAccountName)[0].value
#Get the Storage Context to access the Storage Container
$storageContext = New-AzureStorageContext -StorageAccountName $_.StorageAccountName -StorageAccountKey $key1
#Get the Storage Container in the Variable
$storageContainer = Get-AzureStorageContainer -Context $storageContext
$blob = Get-AzureStorageBlob -Container $storageContainer.name -Context $storageContext
[PSCustomObject]#{
"Name" = $blob.Name
"Length" = $blob.Length
"Storage Account Name" = $_.StorageAccountName
}
}
I want the loop to fetch all the vhd's for each storageaccount and parse it into pscustomobject to list me all vhd*s from all storage accounts, but I get an error:
Get-AzureStorageBlob : Cannot validate argument on parameter
'Container'. The argument is null or empty. Provide an argument that
is not null or empty, and then try the command again. At line:13
char:41
Get-AzureStorageBlob : Cannot convert 'System.Object[]' to the type
'System.String' required by parameter 'Container'. Specified method is not > supported.
At line:13 char:41
Why loop is not parsing data to $storageContainer in line 11? I can see what's inside other two vars like $key1 and $storageContext.
you can rewrite your script in this fashion:
$StorageAccounts = Get-AzureRmStorageAccount
$StorageAccounts.foreach{
$ctx = $_.Context
$containers = Get-AzureStorageContainer -Context $ctx
$containers.foreach{
$blobs = Get-AzureStorageBlob -Container $_.name -Context $ctx
$blobs.foreach{
do_something
}
}
}
you dont need to get keys to construct context, because storage account variable contains the context. and then you need to iterate containers and blobs
I'm trying to download sme blob files from an azure storage account.
There are a mix of other containers and blockblobs in the parent container, I need to download just the blockblobs and not the other containers, I can't find a way of seperating them out, also I need to download some blobs from a conatiner within a container.
My code will download all the contents in the parent blob, including all sub containers.
$sub = "MySub"
$staccname = "straccname1234"
$key = "sdcsecurekeythinghere"
$ctx = New-AzureStorageContext -StorageAccountName $staccname `
-StorageAccountKey $key
$cont = "data\download\files.001" ##the container includes other cntainers and subcontainers
$dest = "C:\blb-Downloads"
Select-AzureSubscription -SubscriptionName $sub –Default
Set-AzureSubscription -Currentstaccname $staccname -SubscriptionName $sub
Get-AzureStorageBlob -Container $cont -Context $ctx
$blobs = Get-AzureStorageBlob -Container $cont -Context $ctx
$blobs | Get-AzureStorageBlobContent –Destination $dest -Context $ctx
There are approx 75 files in the parent blob and 123 files in data\downloads.
Using the newer Azure PowerShell Az module, you can use Get-AzStorageBlob to list all the block blobs from the container, then use Get-AzStorageBlobContent to download the blobs.
As already shown by #George Wallace, we can use Where-Object or its alias ? to filter block blob types.
Demo:
$resourceGroup = "myResourceGroup"
$storageAccount = "myStorageAccount"
$container = "myContainerName"
$destination = "./blobs"
# Create destination directory if it doesn't exist
if (-not (Test-Path -Path $destination -PathType Container)) {
New-Item -Path $destination -ItemType Directory
}
# Get storage account with container we want to download blobs from
$storageAccount = Get-AzStorageAccount -Name $storageAccount -ResourceGroupName $resourceGroup
# Get all BlockBlobs from container
$blockBlobs = Get-AzStorageBlob -Container $container -Context $storageAccount.Context
| Where-Object {$_.BlobType -eq "BlockBlob"}
# Download each blob from container into destination directory
$blockBlobs | Get-AzStorageBlobContent -Destination $destination -Force
Can you not just run the following and limit it to BlockBlobs only?
Get-AzureStorageBlob -Container $cont -Context $ctx | ? {$_.BlobType -eq "BlockBlob"}
This works for me
$storageaccountname = "jawadtestsaacc"
$sastoken = ""
$ContainerName = "access"
$Ctx = New-AzStorageContext -StorageAccountName $storageaccountname -SasToken $sastoken
Get-AzStorageBlob -Container "$ContainerName" -Blob "Az.json" -Context $Ctx | Get-AzStorageBlobContent
or
Get-AzStorageBlobContent -Container "$ContainerName" -Blob "Az.json" -Context $Ctx
How do I break a lease on an item in Blob Storage utilizing PowerShell?
I'm receiving the following when trying to upload something over the current image:
Add-AzureRmVhd : The remote server returned an error: (412) There is currently a lease on the blob and no lease ID was specified in the request..
At line:1 char:1
+ Add-AzureRmVhd -Destination $osDiskUri -LocalFilePath $localFileName ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [Add-AzureRmVhd], StorageException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.Compute.StorageServices.AddAzureVhdCommand
Login to the old portal and navigate to the Virtual Machines then the Images tab the url will be https://manage.windowsazure.com/#yourname.onmicrosoft.com#Workspaces/VirtualMachineExtension/images. Select the image and choose Delete on the bottom.
After that go to your storage and delete it.
You can also try the following which will remove blobs for a given container and then remove the container.
Add-AzureAccount
Get-AzureSubscription | Format-Table SubscriptionName, IsDefault, IsCurrent, CurrentStorageAccountName
$SubscriptionName = 'Your subsscription name'
Select-AzureSubscription -SubscriptionName $SubscriptionName
Get-AzureSubscription -Default
Get-AzureStorageAccount | Format-Table -Property StorageAccountName, Location, AccountType, StorageAccountStatus
$StorageAccountName = "Your storage account"
$StorageAccountKey = (Get-AzureStorageKey -StorageAccountName $StorageAccountName).Primary
$ContainerName = "Your container name"
$Context = New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey
#Get a reference to all the blobs in the container.
$blobs = Get-AzureStorageBlob -Container $ContainerName -Context $Context
#Remove lease on each Blob
$blobs | %{$_.ICloudBlob.BreakLease()}
#Delete blobs in a specified container.
$blobs| Remove-AzureStorageBlob
Remove-AzureStorageContainer -Container $ContainerName -Context $Context
If you want to break a seal on a blob you can use the How to break the locked lease of blob storage in Microsoft Azure (PowerShell)
$key = (Get-AzureRmStorageAccountKey -ResourceGroupName $selectedStorageAccount.ResourceGroupName -name $selectedStorageAccount.StorageAccountName -ErrorAction Stop)[0].value
$storageContext = New-AzureStorageContext -StorageAccountName $selectedStorageAccount.StorageAccountName -StorageAccountKey $key -ErrorAction Stop
$storageContainer = Get-AzureStorageContainer -Context $storageContext -Name $ContainerName -ErrorAction Stop
$blob = Get-AzureStorageBlob -Context $storageContext -Container $ContainerName -Blob $BlobName -ErrorAction Stop
$leaseStatus = $blob.ICloudBlob.Properties.LeaseStatus;
If($leaseStatus -eq "Locked")
{
$blob.ICloudBlob.BreakLease()
Write-Host "Successfully broken lease on '$BlobName' blob."
}
Else
{
#$blob.ICloudBlob.AcquireLease($null, $null, $null, $null, $null)
Write-Host "The '$BlobName' blob's lease status is unlocked."
}
If you want to a script for ARM resources you can use the
How to break the locked lease of blob storage by ARM in Microsoft Azure(PowerShell)
The lease is likely from something like a VM, or something else using the Blog Storage. As a result manually releasing the lease could cause problems.
With that said, the following PowerShell command should do the trick:
Get-AzureRmStorageAccount -Name "STORAGE_ACCOUNT_NAME" | Get-AzureStorageBlob -name "CONTAINER_NAME").ICloudBlob.BreakLease()
If its a VM, you should see the following post on removing the disk:
Cannot delete blob: There is currently a lease on the blob and no lease ID was specified in the request
However, if you simply want to replace the drive used by every machine that uses the given blob, stopping the VM, releasing the lease, uploading a new image, and starting the VM appears to work.