Chris
Chris

Reputation: 2019

How to check if a blob already exists in Azure blob container using PowerShell

I have a Windows PowerShell script that uploads a file to my Azure Blob Storage. I want the file only to upload if it doesn't already exists in the container.

How do I check if the blob already exists ?

I tired to use Get-AzureStorageBlob but if the blob doesn't exists, it returns an error. Should I parse the error message to determine that the blob doesn't exists ? This doesn't seem right...

And Set-AzureStorageBlobContent is asking for a confirmation when the blob exists. Is there a way to automatically answer "No" ? This cmdlet doesn't have -confirm and -force would overwrite the file (which I don't want).

Upvotes: 10

Views: 19383

Answers (6)

badbob001
badbob001

Reputation: 29

Similar to @jimhark's answer, but I like to use a more generic error detection method that doesn't depend on the command returning something. And may be more flexible than try/catch since that needs a terminating error. And the use of if/else lets you clearly do something if there is no error, which try/catch doesn't directly support.

$null = Get-AzureStorageBlob -Blob $azureBlobName -Container $azureStorageContainer -Context $azureContext -ErrorAction SilentlyContinue -Errorvar errorvar
if ($errorvar){
    Write-Host "Blob Issue: $(@($errorvar.exception.message)[0])"
}else{
    Write-Host "Blob Found"
{

Errorvar can also capture errors from multiple commands by simply prefixing the variable name with a '+' on subsequent commands.

$null = Get-AzureStorageBlob -Blob $azureBlobName1 -Container $azureStorageContainer -Context $azureContext -ErrorAction SilentlyContinue -Errorvar errorvar

$null = Get-AzureStorageBlob -Blob $azureBlobName2 -Container $azureStorageContainer -Context $azureContext -ErrorAction SilentlyContinue -Errorvar +errorvar

if ($errorvar){
    Write-Host "Blob Issues: $(@($errorvar.exception.message) -join ';')"
}else{
    Write-Host "Blobs Found"
{

Upvotes: 0

jimhark
jimhark

Reputation: 5046

This is a variant of @Chris's answer. Chris used Exceptions and Try/Catch. In larger systems try/catch is great. It allows an error deep in the code to throw an exception, and the system will backtrack the call history looking for a matching catch statement. However when all the code is in one function, for simplicity, I prefer checking return values:

$blob = Get-AzureStorageBlob -Blob $azureBlobName -Container $azureStorageContainer -Context $azureContext -ErrorAction Ignore
if (-not $blob)
{
    Write-Host "Blob Not Found"
}

Upvotes: 18

frank tan
frank tan

Reputation: 141

  $storageAccount = Get-AzureRmStorageAccount -ErrorAction Stop | where-object {$_.StorageAccountName -eq $StorageAccountName}
     If($storageAccount)
     {
        $key = (Get-AzureRmStorageAccountKey -ResourceGroupName $storageAccount.ResourceGroupName -name $storageAccount.StorageAccountName -ErrorAction Stop)[0].value
        $storageContext = New-AzureStorageContext -StorageAccountName $storageAccount.StorageAccountName -StorageAccountKey $key -ErrorAction Stop
        $storageContainer = Get-AzureStorageContainer -Context $storageContext -ErrorAction Stop | where-object {$_.Name -eq $ContainerName}
        If($storageContainer)
        {
            $blob = Get-AzureStorageBlob -Context $storageContext -Container $ContainerName -ErrorAction Stop | where-object {$_.Name -eq $BlobName}
            If($blob)
            {
                Write-Host "'$BlobName' blob found."
            }
            Else 
            {
                Write-Warning "'$BlobName' blob not found."
            }
        }
        Else 
        {
            Write-Warning "'$ContainerName' storage container not found."
        }
     }
     Else 
     {
         Write-Warning "'$StorageAccountName' storage account not found."
     }

You can download detail script from how to check if a blob exists in Azure Storage using PowerShell

Upvotes: 0

abbgrade
abbgrade

Reputation: 578

You can get a list of all blobs and look for your file.

$blobs = Get-AzureStorageBlob -Container $config.ImportContainerName -Context $storageContext

ForEach($file in Get-ChildItem -Path $config.LocalImportPath) {
    $blobName = $config.ImportBlobPrefix + "/" + $file.Name
    $blob = $blobs | Where-Object {$_.Name -eq $blobName}
    if (-not $file.Length -eq $blob.Length) {
        echo "todo upload" $file.Name
    }
}

Upvotes: -1

Chris
Chris

Reputation: 2019

A solution is to wrap the call to Get-AzureStorageBlob in a try/catch and catch ResourceNotFoundException to determine that the blob doesn't exist.

And don't forget the -ErrorAction Stop at the end.

try
{   
    $blob = Get-AzureStorageBlob -Blob $azureBlobName -Container $azureStorageContainer -Context $azureContext -ErrorAction Stop
}
catch [Microsoft.WindowsAzure.Commands.Storage.Common.ResourceNotFoundException]
{
    # Add logic here to remember that the blob doesn't exist...
    Write-Host "Blob Not Found"
}
catch
{
    # Report any other error
    Write-Error $Error[0].Exception;
}

Upvotes: 15

That's right, Set-AzureStorageBlobContent doesn't have neither -Confirm flag nor -WhatIf flag.

Are you really sure you want to ignore the fact that particular blob contains something and just overwrite it's content silently?

It looks like that the only one possible (and pretty ugly one) solution here will be a try/catch block with Get-AzureStorageBlob inside.

Upvotes: 0

Related Questions