Reputation: 2019
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
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
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
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
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
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
Reputation: 21972
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