Azure自动化Runbook中Azure模块导入失败:无法访问PSConfig.json
Azure Automation多Runbook并发执行Connect-AzAccount的文件占用问题
错误详情
Import-Module: 无法访问文件
C:\Users\username\.Azure\PSConfig.json,因为该文件正被另一个进程占用。位置:C:\Program Files\WindowsPowerShell\Modules\AZ.Accounts\2.8.0\Az.Accounts.psm1:117
问题场景
Azure Automation同时触发多个PowerShell runbook时,所有runbook执行Connect-AZAccount会触发上述错误。由于某个脚本访问PSConfig.json时会锁定文件,导致其他runbook无法识别Azure模块cmdlets,最终执行失败。
已尝试的无效操作
尝试重新导入Az.Accounts模块,模块能成功导入,但脚本仍无法识别任何Azure模块cmdlets。当前使用的重试代码如下:
$try = 20 do { if ([string]::IsNullOrEmpty((Get-Module Az.Accounts))) { Write-Output "Importing AZ.Accounts" Import-Module AZ.Accounts } try { Connect-AzAccount -Identity -Subscription $SubscriptionId -ErrorAction Stop } catch { Write-Warning "Failed to connect to Azure! $($Error[0].Exception.Message)" } $AZContext = Get-AzContext $try-- } while ($AZContext.Subscription.Id -ne $SubscriptionId -OR $try -le 0)
解决思路
- 使用无配置文件连接:在
Connect-AzAccount中添加-NoProfile参数,该参数会跳过加载和写入本地PSConfig.json文件,从根源避免文件锁定冲突。修改后的连接命令:Connect-AzAccount -Identity -Subscription $SubscriptionId -NoProfile -ErrorAction Stop - 升级Az.Accounts模块:当前使用的2.8.0版本较旧,存在文件锁定的已知问题。升级到最新稳定版的Az.Accounts模块,新版本优化了文件访问逻辑,减少锁竞争概率。
- 限制Runbook并发数:如果业务允许,在Azure Automation中设置目标Runbook的并发作业限制,避免过多进程同时访问配置文件资源。
- 针对性捕获重试:在代码中专门捕获“文件被占用”的异常,等待1-2秒后再重试,替代盲目重试逻辑。示例代码:
$try = 20 do { $moduleLoaded = Get-Module Az.Accounts if (-not $moduleLoaded) { Write-Output "Importing AZ.Accounts" try { Import-Module AZ.Accounts -ErrorAction Stop $moduleLoaded = $true } catch { if ($_.Exception.Message -match "PSConfig.json.*被另一个进程占用") { Write-Warning "PSConfig.json被占用,等待1秒后重试导入" Start-Sleep -Seconds 1 continue } Write-Warning "导入AZ.Accounts失败: $($_.Exception.Message)" } } if ($moduleLoaded) { try { Connect-AzAccount -Identity -Subscription $SubscriptionId -NoProfile -ErrorAction Stop $AZContext = Get-AzContext if ($AZContext.Subscription.Id -eq $SubscriptionId) { break } } catch { if ($_.Exception.Message -match "PSConfig.json.*被另一个进程占用") { Write-Warning "连接时PSConfig.json被占用,等待1秒后重试" Start-Sleep -Seconds 1 } else { Write-Warning "连接Azure失败: $($_.Exception.Message)" } $AZContext = $null } } $try-- } while ($try -gt 0)
内容的提问来源于stack exchange,提问作者TheEnderPrime
相关产品推荐
相关产品推荐

