如何修复PowerShell导出Excel显示System.Object[]的问题
问题原因
出现System.Object[]的核心原因有两个:
- 取值逻辑错误:你提前把所有CSV行对应的EXO邮箱查询结果存为数组,后续构建单条导出对象时,直接取数组的
.UserName、.UserId属性拿到的是所有记录的用户名/ID组成的集合,不是和当前处理行一一对应的单个值,Excel无法直接渲染数组就会显示对象类型名。 - 变量名冲突:你把EXO查询结果、最终要导出的全量数据都命名为
$result,循环执行时会出现值覆盖的问题。
修复方案
把EXO邮箱查询逻辑移到CSV逐行处理的循环内部,每处理一行CSV就当场查询对应邮箱信息,直接给当前行的导出属性赋值即可,修正后的完整代码如下:
# 逐行处理CSV,所有逻辑在同一循环内完成,避免跨作用域取数组值 $exportData = Import-Csv "C:\AuditLogSearch\Dis\Modified-Audit-Log-Records.csv" | Where-Object { -join $_.psobject.Properties.Value } | ForEach-Object { # 提取当前行的邮箱地址 $exoMailbox = ($_.'Exchange Mailboxes' -split '[][]')[1] # 查询对应EXO邮箱信息,加容错参数避免查不到时报错中断 $exoUser = Get-EXOMailbox -Filter "PrimarySmtpAddress -eq '$exoMailbox'" -ErrorAction SilentlyContinue # 逐行构建导出对象,所有属性直接取当前上下文的单个值 [pscustomobject]@{ User = $_.User "Date & Time" = $_."Date & Time" "Case Name" = $_."Case Name" "Hold Name" = $_."Hold Name".Split('\')[1] "Record Type" = $_."Record Type" "Activity" = if ($null -ne ($importData | Where-Object { $_.Name -eq $_."Activity" }).Value) { ($importData | Where-Object { $_.Name -eq $_."Activity" }).Value } else { $_."Activity" } 'Searched User' = if ($exoUser) { $exoUser.DisplayName } else { "未找到对应邮箱" } 'Searched User GMID' = if ($exoUser) { $exoUser.Identity } else { "未找到对应邮箱" } 'SharePoint URL' = $spUrl 'Site Owner' = $spositeOwner "Search Conditions" = $_."Search Conditions" "SharePoint Sites" = $_."SharePoint Sites" "Exchange Public Folders" = $_."Exchange Public Folders" "Exchange Mailboxes" = $exoMailbox "Search Criteria" = $_."Search Criteria" "Result Status" = $_."Result Status" } } | Select-Object -Property User, "Date & Time", "Case Name", "Hold Name", "Record Type", "Activity" , "Searched User", "Searched User GMID", "SharePoint URL", "Exchange Mailboxes", "Exchange Public Folders" , "Search Criteria", "Result Status" # 导出Excel逻辑保持不变,传入逐行构建完成的数据集即可 $xlsx = $exportData | Export-Excel @params $ws = $xlsx.Workbook.Worksheets[$params.Worksheetname] $ws.Column(1).Width = 20 $ws.Column(2).Width = 20 $ws.Column(3).Width = 15 $ws.Column(4).Width = 15 $ws.Column(5).Width = 15 $ws.Column(6).Width = 160 $ws.View.ShowGridLines = $false Close-ExcelPackage $xlsx
额外注意点
- PowerShell的行注释符号是
#,原代码中用//写注释属于C#语法,执行时会触发报错,修正后已移除无效注释 - 给
Get-EXOMailbox命令增加了容错参数和空值判断,遇到CSV中邮箱格式错误、不存在对应EXO邮箱的场景不会中断脚本执行,对应单元格会显示预设的提示文本 - 提取邮箱地址的逻辑复用为变量,不需要重复执行字符串拆分操作,减少冗余计算
内容的提问来源于stack exchange,提问作者aasenomad
相关产品推荐
相关产品推荐

