如何修改PowerShell脚本从Azure Blob存储下载最新文件至Windows虚拟机
问题描述
我正在开发一个使用托管标识(Managed Identity)进行身份验证的PowerShell脚本,用于从Azure Blob存储下载文件。目前已有可正常运行的脚本片段,且已在Azure门户中为虚拟机分配了存储账户所需的RBAC角色,可成功下载指定文件。现在希望无需明确指定文件名,而是始终从Blob存储容器中获取最新文件,请问如何修改脚本实现该需求?
原运行脚本片段:
Connect-AzAccount -identity $responseID = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://storage.azure.com/' ` -Headers @{Metadata="true"} $val = $response.Content | ConvertFrom-Json $access_token = $content.access_token $Path = "C:\Venkat" $url = "https://Storageaccount.blob.core.windows.net/testcontainer/Test.txt" $RequestHeader = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" $RequestHeader.Add("Authorization", "Bearer $access_token") $RequestHeader.Add("x-ms-version", "2019-02-02") $result = Invoke-WebRequest -Uri $url -Headers $RequestHeader $result.content $output = $result.content Invoke-WebRequest -Headers $header -Uri $url -OutFile "C:\Venkat\Test.txt" -PassThru
解决方案
要实现动态获取容器内最新文件的需求,需先调用Blob存储的列出容器内Blob接口,获取所有Blob的元数据并筛选出最新项,再执行下载操作。以下是修改后的完整脚本及说明:
修改后的完整脚本
# 通过托管标识登录Azure Connect-AzAccount -Identity # 获取存储服务的访问令牌 $tokenResponse = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://storage.azure.com/' ` -Headers @{Metadata="true"} -UseBasicParsing $tokenContent = $tokenResponse.Content | ConvertFrom-Json $accessToken = $tokenContent.access_token # 配置存储账户和容器信息 $storageAccountName = "Storageaccount" $containerName = "testcontainer" $downloadPath = "C:\Venkat" # 构造列表Blob的请求URL和请求头 $listBlobsUrl = "https://$storageAccountName.blob.core.windows.net/$containerName?restype=container&comp=list" $requestHeaders = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" $requestHeaders.Add("Authorization", "Bearer $accessToken") $requestHeaders.Add("x-ms-version", "2019-02-02") # 获取容器内所有Blob的列表 $listResponse = Invoke-WebRequest -Uri $listBlobsUrl -Headers $requestHeaders -UseBasicParsing [xml]$blobsXml = $listResponse.Content # 筛选出最新的Blob(按LastModified时间倒序,取第一个) $latestBlob = $blobsXml.EnumerationResults.Blobs.Blob | Sort-Object -Property LastModified -Descending | Select-Object -First 1 if ($latestBlob) { # 构造最新Blob的下载URL $latestBlobUrl = "https://$storageAccountName.blob.core.windows.net/$containerName/$($latestBlob.Name)" # 下载最新Blob到指定路径 $outputFilePath = Join-Path -Path $downloadPath -ChildPath $latestBlob.Name Invoke-WebRequest -Uri $latestBlobUrl -Headers $requestHeaders -OutFile $outputFilePath -UseBasicParsing -PassThru Write-Host "已成功下载最新文件:$($latestBlob.Name),保存路径:$outputFilePath" } else { Write-Host "容器$containerName中未找到任何Blob文件" }
关键说明
- 修复了原脚本的变量错误:原脚本中
$response.Content应为$responseID.Content,$access_token的赋值变量也存在混淆问题 - 列表Blob接口返回XML格式数据,通过解析XML获取Blob的
Name和LastModified属性 - 按
LastModified字段倒序排序,确保获取的是最后修改的文件 - 自动拼接最新Blob的原始文件名作为下载路径,避免文件覆盖或命名冲突
- 加入空容器判断逻辑,防止脚本因无Blob数据报错
内容的提问来源于stack exchange,提问作者Michael Brown
相关产品推荐
相关产品推荐

