Azure Storage容器列表查询PowerShell认证及容器问题排查
Let's tackle your issues step by step—since you can successfully create files, your core authentication setup is close, but there are subtle differences in how the REST API expects signatures for GET operations (like listing content) vs PUT (like uploading files). Plus, I'll cover how to list root-level storage content too.
First: Fixing the AuthenticationFailed Error
The most common cause of signature mismatches when switching from PUT to GET is missing adjustments to the signature string components. Azure's REST API signature requires exact matching of several request attributes, and GET requests have different requirements than PUT:
- HTTP Method: For listing container content, this must be
GET(you were usingPUTfor file uploads—easy to forget to update this!). - Content-Length: GET requests don't have a request body, so this value must be
0(for PUT, you used the file size). - Canonicalized Resource: For listing a container's blobs, this should be formatted as
/$storageAccountName/$containerName(if you're using thecomp=listparameter, it gets appended correctly in the signature).
Here's a corrected signature generation snippet tailored for GET requests:
$storageAccountName = "liveworkerstorage" $containerName = "your-container-name" # Replace with your actual container name (lowercase!) $accessKey = "your-storage-account-access-key" # Set request details for listing container content $method = "GET" $contentLength = 0 $date = [DateTime]::UtcNow.ToString("R") $canonicalResource = "/$storageAccountName/$containerName`ncomp:list" $stringToSign = "$method`n`n`n$contentLength`n`napplication/xml`n`n`n`n`n`n$canonicalResource" # Generate the signature $hmacSha256 = New-Object System.Security.Cryptography.HMACSHA256 $hmacSha256.Key = [Convert]::FromBase64String($accessKey) $signature = [Convert]::ToBase64String($hmacSha256.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))) # Build the authorization header $authHeader = "SharedKey $storageAccountName`:$signature"
Fixing the ContainerNotFound Error
If you switched code and started getting this error, here are the top checks:
- Container Name Case: Azure Storage container names must be lowercase, can't contain uppercase letters or spaces. Double-check that your
$containerNamevariable matches the exact name (case-sensitive in the API request). - Canonical Resource Path: Ensure your
$canonicalResourcedoesn't have extra slashes or typos. For example,/liveworkerstorage/mycontaineris correct—/liveworkerstorage//mycontainer(double slash) would cause a not-found error. - Request URL: Verify the full request URL is correct:
https://$storageAccountName.blob.core.windows.net/$containerName?comp=list
Listing Root-Level Storage Content (All Containers)
To list all containers in your storage account (root-level content), you'll adjust the request to target the account itself instead of a specific container. Here's the modified code:
# Request details for listing all containers (root level) $method = "GET" $contentLength = 0 $date = [DateTime]::UtcNow.ToString("R") $canonicalResource = "/$storageAccountName/?comp=list" $stringToSign = "$method`n`n`n$contentLength`n`napplication/xml`n`n`n`n`n`n$canonicalResource" # Generate signature (same as before) $hmacSha256 = New-Object System.Security.Cryptography.HMACSHA256 $hmacSha256.Key = [Convert]::FromBase64String($accessKey) $signature = [Convert]::ToBase64String($hmacSha256.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))) $authHeader = "SharedKey $storageAccountName`:$signature" # Send the request $listContainersUrl = "https://$storageAccountName.blob.core.windows.net/?comp=list" $headers = @{ "Authorization" = $authHeader "x-ms-date" = $date "x-ms-version" = "2021-06-08" # Use a recent API version } Invoke-RestMethod -Uri $listContainersUrl -Method $method -Headers $headers
Full Working Example for Listing Container Blobs
Putting it all together, here's a complete script to list blobs in an existing container without errors:
$storageAccountName = "liveworkerstorage" $containerName = "your-container-name" $accessKey = "your-access-key" $apiVersion = "2021-06-08" # Prepare request parameters $method = "GET" $contentLength = 0 $date = [DateTime]::UtcNow.ToString("R") $canonicalResource = "/$storageAccountName/$containerName`ncomp:list" $stringToSign = "$method`n`n`n$contentLength`n`napplication/xml`n`n`n`n`n`n$canonicalResource" # Generate signature $hmacSha256 = New-Object System.Security.Cryptography.HMACSHA256 $hmacSha256.Key = [Convert]::FromBase64String($accessKey) $signature = [Convert]::ToBase64String($hmacSha256.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))) # Build headers $headers = @{ "Authorization" = "SharedKey $storageAccountName`:$signature" "x-ms-date" = $date "x-ms-version" = $apiVersion } # Execute request $listBlobsUrl = "https://$storageAccountName.blob.core.windows.net/$containerName?comp=list" try { $response = Invoke-RestMethod -Uri $listBlobsUrl -Method $method -Headers $headers Write-Host "Success! Blob list:" $response.EnumerationResults.Blobs.Blob } catch { Write-Host "Error: $_" Write-Host "Response content: $($_.Exception.Response.Content.ReadAsStringAsync().Result)" }
Key Notes to Avoid Future Errors
- Always use a recent API version (
x-ms-versionheader) to ensure compatibility with modern Storage features. - Double-check all components of the
stringToSign—even a missing newline or incorrect parameter order will break the signature. - For GET requests, never omit the
Content-Length: 0in the string to sign (even if you don't send it in the request header, Azure expects it in the signature).
内容的提问来源于stack exchange,提问作者mdie

