Azure Cloud Shell上传脚本添加Reader角色失败,手动执行正常
1. 缺少AzureAD模块安装步骤
你的脚本里调用了Get-AzureADServicePrincipal,但只安装了Az模块——这个命令属于AzureAD模块。手动执行时你可能之前已经安装过该模块,所以能正常运行;但上传脚本执行时,环境是全新的(或模块未加载),导致无法获取服务主体ID,进而执行New-AzRoleAssignment时因ObjectId为空返回Bad Request。
解决办法:在脚本开头添加AzureAD模块的安装和导入命令:
Install-Module AzureAD -Scope CurrentUser -Force Import-Module AzureAD
2. Az模块与Azure CLI上下文冲突
脚本里同时用了Connect-AzAccount(Az模块)和az login(Azure CLI),两者的认证上下文是独立的。手动执行时你分步操作,确保了Az模块上下文正确;但脚本批量执行时,az login可能干扰Az模块的订阅上下文,导致Get-AzContext拿到错误的订阅ID或权限不匹配。
解决办法:删掉冗余的az login命令,只用Az模块的认证方式即可:
# 移除这一行:az login
3. 认证后上下文未完全加载就执行后续命令
脚本中Connect-AzAccount之后立即执行Get-AzContext或Get-AzureADServicePrincipal,可能因为认证会话还未完全初始化,导致获取的订阅ID或服务主体ID为空。手动执行时你有操作间隔,上下文已加载完成。
解决办法:在认证后添加短暂延迟,或者强制刷新上下文:
Connect-AzAccount -UseDeviceAuthentication # 添加延迟确保上下文加载 Start-Sleep -Seconds 5 # 或者强制获取上下文 $context = Get-AzContext -ErrorAction Stop
4. 脚本文件编码或引号解析问题
脚本上传到文件存储后,可能因为编码格式(比如UTF-8带BOM)导致PowerShell解析引号时出错,Filter "DisplayName eq '$($appName)'"中的变量无法正确替换,导致Get-AzureADServicePrincipal返回空值。
解决办法:保存脚本时使用UTF-8无BOM编码,或者修改Filter写法避免引号冲突:
$spId = (Get-AzureADServicePrincipal -Filter "DisplayName eq ""$appName""").ObjectId
内容的提问来源于stack exchange,提问作者Harry

