You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell导出CSV时Enabled列显示System.Object[]异常排查

问题描述

编写PowerShell脚本用于审计导入的CSV文件,最终导出新增字段的完成版CSV:新增列用于标识CSV内的用户是否存在于AD中,若存在则标注对应账户是否为启用状态。
原始脚本代码如下:

#CSV file to have header of "Employee" with First and Last name in each row
Echo "CSV file to import must be in c:\temp folder location with header of "Employee""
$csvlocate = (Read-Host -Prompt "CSV File to import (enter in like filename.csv and make sure file is in c:\temp folder)")
$csvEmployees = Import-Csv -path C:\temp\$csvlocate.csv
$adUsers = Get-AdUser -Filter *

foreach ($Employee in $csvEmployees) {
    $Found = $adUsers | Where-Object { ($_.GivenName -eq $Employee.givenName) -and ($_.Surname -eq $Employee.surName) }
    if ($Found) {
        "In AD $($Employee.givenName) $($Employee.surName)."
        $Employee | Add-Member -Name InAD -Value $true -MemberType NoteProperty
        $Employee | Add-Member -Name Enabled -Value $Found.Enabled -MemberType NoteProperty
    } else {
        "Not in AD $($Employee.givenName) $($Employee.surName)."
        $Employee | Add-Member -Name InAD -Value $false -MemberType NoteProperty
        $Employee | Add-Member -Name Enabled -Value $false -MemberType NoteProperty
    }
}

$csvEmployeesNotInAd = $csvEmployees.foreach{
    $employee = @{
        'CSVName' = $_.Name
        'InAD' = $false
    }
    if ($_.Name -in $adUsers.Name) {
        $employee.InAD = $true
    }
    [pscustomobject]$employee
}

$csvEmployees | Export-Csv -Path C:\temp\$csvlocate.completed.csv -NoTypeInformation -Force

执行脚本后导出的CSV文件中,Enabled列所有内容均显示为System.Object[]。

问题原因
  • Get-AdUser cmdlet 默认返回的属性集不包含Enabled字段,未显式指定返回属性时,访问对象的Enabled成员会得到空数组值。Export-Csv序列化对象时会对非基础类型调用默认ToString()方法,数组类型的默认ToString()返回值就是固定字符串System.Object[],这是触发该问题的核心原因。
  • 现有匹配逻辑未限制返回结果数量,若AD中存在多个GivenName、Surname完全相同的用户,$Found变量会存储用户对象数组,此时访问$Found.Enabled会得到所有匹配用户的Enabled属性组成的数组,序列化后同样会显示为System.Object[]。
  • 脚本中定义的$csvEmployeesNotInAd代码块未被后续导出逻辑调用,属于无效冗余代码,会额外消耗执行性能,不直接触发当前报错。
  • 原始脚本的文件路径逻辑存在缺陷:提示用户输入带.csv后缀的文件名,但导入路径又额外拼接了.csv后缀,会触发文件找不到的报错。
修复方案

调整AD查询逻辑显式拉取需要的属性,增加单结果匹配限制,修正路径问题,删除冗余代码,修复后完整脚本如下:

# 提示导入文件规则
Write-Host "CSV file to import must be stored in c:\temp, with column headers including givenName and surName"
$csvlocate = Read-Host -Prompt "Enter full CSV filename (e.g. employeelist.csv, ensure file is saved in c:\temp)"
$csvEmployees = Import-Csv -Path "C:\temp\$csvlocate"
# 显式指定查询返回所需属性,避免默认属性集缺失字段
$adUsers = Get-AdUser -Filter * -Properties GivenName, Surname, Enabled

foreach ($Employee in $csvEmployees) {
    # 取第一个匹配的AD用户,避免同名多用户返回数组对象
    $Found = $adUsers | Where-Object { 
        $_.GivenName -eq $Employee.givenName -and $_.Surname -eq $Employee.surName 
    } | Select-Object -First 1

    if ($null -ne $Found) {
        Write-Host "Found AD account for $($Employee.givenName) $($Employee.surName)."
        $Employee | Add-Member -Name InAD -Value $true -MemberType NoteProperty
        # 赋值单用户的布尔类型Enabled属性,确保为单值
        $Employee | Add-Member -Name Enabled -Value $Found.Enabled -MemberType NoteProperty
    }
    else {
        Write-Host "No AD account found for $($Employee.givenName) $($Employee.surName)."
        $Employee | Add-Member -Name InAD -Value $false -MemberType NoteProperty
        $Employee | Add-Member -Name Enabled -Value $false -MemberType NoteProperty
    }
}

# 导出最终结果,自动处理文件名后缀避免重复
$exportPath = "C:\temp\$($csvlocate.Replace('.csv','')).completed.csv"
$csvEmployees | Export-Csv -Path $exportPath -NoTypeInformation -Force

优化提示:如果域内AD用户总量超过1000,不建议拉取全量AD用户到本地匹配,可以将循环内逻辑改为按用户名单次查询AD,大幅降低内存占用和执行耗时。

内容的提问来源于stack exchange,提问作者MatthewS

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 17:33:45