使用Azure Automation+PowerShell将ADLS中Excel多工作表转CSV遇异常
问题分析与修复方案
以下是你的代码中存在的关键问题及对应的修复方案:
核心问题点
- Get-AzStorageAccount语法错误:原代码中管道后直接拼接
-ResourceGroupName参数的写法无效,该参数需直接作为Get-AzStorageAccount的参数传入。 - 未下载Blob到本地临时存储:Azure Automation无法直接读取ADLS中的Blob路径,必须先将文件下载到本地临时目录(
$env:TEMP),原代码未指定下载目标路径,导致后续Excel操作找不到文件。 - 直接向ADLS路径导出CSV无效:
Export-Csv仅支持本地文件系统路径,不能直接写入ADLS的Blob路径,需先导出到本地临时文件,再上传到ADLS。 - 管道逻辑错误:
Export-Csv无输出对象,因此后续管道到Set-AzStorageBlobContent完全无效,需拆分导出和上传步骤。 - 函数作用域缺失变量:
Export-UDF-XLToCSV函数中使用的$ContainerName和$SAContext属于全局变量,函数默认无法访问,需将其作为参数传入。
修正后的完整代码
########## Get Base Filename from full folder name ############ function Get-UDF-BaseFile { [CmdletBinding()] param ( [string] $fileLocation ) $baseFile = $fileLocation -split "/", -1 Return $baseFile[-1] } #### For Each Excel File, get the worksheets and save each as CSV to ADLS ######## Function Export-UDF-XLToCSV ($excelLocalPath, $csvBlobDir, $containerName, $storageContext) { Write-Output "Processing local file: $excelLocalPath" $excelFile = Get-UDF-BaseFile -fileLocation $excelLocalPath $excelFilePrefix = $excelFile.Split(".")[0] $sheets = (Get-ExcelSheetInfo -Path $excelLocalPath).Name foreach ($sheet in $sheets) { # 生成本地临时CSV文件路径 $localCsvPath = Join-Path -Path $env:TEMP -ChildPath "$excelFilePrefix__$sheet.csv" # 生成目标Blob路径 $targetBlobPath = Join-Path -Path $csvBlobDir -ChildPath "$excelFilePrefix__$sheet.csv" # 导出到本地CSV Import-Excel -WorksheetName $sheet -Path $excelLocalPath | Export-Csv -Path $localCsvPath -NoTypeInformation -Encoding UTF8 # 上传到ADLS Set-AzStorageBlobContent -Container $containerName -File $localCsvPath -Blob $targetBlobPath -Context $storageContext -Force Write-Output "Excel File: $excelFile, Exported Sheet: $sheet to Blob path: $targetBlobPath" # 删除临时文件 Remove-Item -Path $localCsvPath -Force } } ####################################################################### # Start of Main Code ####################################################################### $StorageAccountName = "mystorageaccount" $ResourceGroupName = "myresourcegroup-rg" # 修正Get-AzStorageAccount的参数写法 $StorageAccount = Get-AzStorageAccount -Name $StorageAccountName -ResourceGroupName $ResourceGroupName $SAContext = $StorageAccount.Context $ContainerName = "root" $BlobDirRoot = "sources/myexports" $BlobDir = $BlobDirRoot + "/excel/*.xlsx" $listOfFiles = Get-AzStorageBlob -Container $ContainerName -Blob $BlobDir -Context $SAContext $DestinationDir = $BlobDirRoot + "/csv/" foreach ($file in $listOfFiles) { # 生成本地临时文件路径 $localExcelPath = Join-Path -Path $env:TEMP -ChildPath (Get-UDF-BaseFile -fileLocation $file.Name) # 下载Blob到本地临时目录 Get-AzStorageBlobContent -Container $ContainerName -Blob $file.Name -Destination $localExcelPath -Context $SAContext -Force # 调用处理函数,传入必要参数 Export-UDF-XLToCSV -excelLocalPath $localExcelPath -csvBlobDir $DestinationDir -containerName $ContainerName -storageContext $SAContext # 删除本地临时Excel文件 Remove-Item -Path $localExcelPath -Force }
额外说明
- 代码中使用了
$env:TEMP作为临时存储目录,这是Azure Automation运行环境中允许的临时文件存储位置,执行完成后会自动清理,也可手动删除临时文件避免占用空间。 - 添加了
-Force参数到Get-AzStorageBlobContent和Set-AzStorageBlobContent,避免因文件已存在导致的操作失败。 - 为
Export-Csv添加了-Encoding UTF8参数,确保CSV文件编码兼容。
内容的提问来源于stack exchange,提问作者Ernest Ega
相关产品推荐
相关产品推荐

