You need to enable JavaScript to run this app. 从CSV批量移除Azure用户许可证的PowerShell脚本仅运行首行后报错
优惠活动
大模型
产品
解决方案
定价
更多

从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.03 11:15:02