从CSV批量移除Azure用户许可证的PowerShell脚本仅运行首行后报错
MSOL批量移除许可证类型转换报错排查
前置要求
确保运行脚本前已完成Azure AD MSOL模块的服务连接,否则会触发连接类报错:
Connect-MsolService
根因定位
- 你使用
Import-Csv读取无表头的纯邮箱列表时,PowerShell会自动将CSV第一行识别为列名而非数据行,导致读取到的对象结构完全不符合预期 - 脚本中声明了循环索引
$i但未实际调用,直接将整个CSV返回的数组对象传入Get-MsolUser的*-UserPrincipalName*参数,而该参数仅接受单个字符串类型的用户主体名,因此触发了System.Object[]无法转换为System.String的类型错误 - 未从CSV对象中提取单条邮箱字段,全程传了全量数组值
修复方案
适配当前无表头CSV格式的完整脚本
你的CSV为纯邮箱列表、无表头行,直接改用Get-Content逐行读取并过滤空行,同时修正循环逻辑为单条用户处理:
# 逐行读取CSV,过滤空行/无效字符 $userUpnList = Get-Content C:\Tools\LicencesToRemove.csv | Where-Object { $_.Trim() -ne "" } foreach ($upn in $userUpnList) { # 获取当前用户已分配的所有许可证SKU ID $assignedSkus = (Get-MsolUser -UserPrincipalName $upn).Licenses.AccountSkuId foreach ($sku in $assignedSkus) { # 移除单个许可证 Set-MsolUserLicense -UserPrincipalName $upn -RemoveLicenses $sku } }
带表头的标准CSV适配方案
如果后续需要扩展CSV字段(如增加部门、备注列),先修改CSV结构,增加统一表头:
UserPrincipalName
test.delete1@abc.onmicrosoft.com
test.delete2@abc.onmicrosoft.com
test.delete3@abc.onmicrosoft.com
test.delete4@abc.onmicrosoft.com
对应脚本调整为:
$userList = Import-Csv C:\Tools\LicencesToRemove.csv foreach ($user in $userList) { $upn = $user.UserPrincipalName $assignedSkus = (Get-MsolUser -UserPrincipalName $upn).Licenses.AccountSkuId foreach ($sku in $assignedSkus) { Set-MsolUserLicense -UserPrincipalName $upn -RemoveLicenses $sku } }
关键修改点
- 替换了错误的CSV读取逻辑,分别适配无表头纯列表、带表头结构化列表两种场景
- 修正了循环调用逻辑,每次仅传单个用户主体名给命令参数,解决类型转换错误
- 增加了空行过滤,避免无效值触发非必要报错
- 移除了未使用的索引变量,改用PowerShell原生的
foreach遍历逻辑,可读性更强
内容的提问来源于stack exchange,提问作者Guillaume vM M
相关产品推荐
相关产品推荐

