Foreach-Object -Parallel结合Export-Csv使用问题求助
问题解决:Foreach-Object -Parallel 结合 Export-Csv 的两个问题
问题1:无法导出PSCustomObject到CSV
你在并行块里用$ReturnObject +=累加对象,但这个变量在每个并行线程里都是独立的未初始化状态,而且最后没有把创建的对象输出到管道,导致$data根本没接收到任何数据,自然无法导出CSV。
解决方法:直接在并行块末尾输出创建的PSObject,让管道收集每个线程的输出结果。
问题2:$i++无法正确递增计数
ForEach-Object -Parallel的每个线程都有独立的运行空间,$using:i只是复制了主线程中$i的初始值(0),线程内对$i的修改不会同步回主线程,多线程同时修改还会引发竞争条件,导致计数混乱。
解决方法:使用线程安全的[System.Threading.Interlocked]::Increment操作计数器,确保多线程下计数准确。
修正后的完整代码
$users1 = $users | Select-Object -First 10 $count = $users1.Count $i = 0 $data = $users1 | ForEach-Object -Parallel { # 线程安全地递增计数器 $currentCount = [System.Threading.Interlocked]::Increment([ref]$using:i) Write-Host ("Processing user {0} -> {1}/{2}." -f $_.UserPrincipalName, $currentCount, $using:count) $AuthMethods = Get-MgUserAuthenticationMethod -UserId $_.Id $Methods = $AuthMethods.AdditionalProperties.'@odata.type' | Select-Object -Unique $phoneNumber = $emailaddress = $null foreach ($Method in $Methods) { switch ($Method) { "#microsoft.graph.phoneAuthenticationMethod" { $phoneNumber = $AuthMethods.AdditionalProperties.phoneNumber -join ";" } "#microsoft.graph.emailAuthenticationMethod" { $emailaddress = $AuthMethods.AdditionalProperties.emailAddress -join ";" } } } # 直接输出创建的对象,让管道收集 [PSCustomObject]@{ User = $_.UserPrincipalName PhoneNumbers = $phoneNumber EmailAddress = $emailaddress } } -ThrottleLimit 5 $data | Export-Csv "c:\temp\authreport.csv" -NoTypeInformation -Append
额外说明
- 调整了
$users1和$count的赋值顺序,避免原代码中$count先拿到0值的错误。 - 用
[PSCustomObject]直接创建对象比New-Object PSObject更简洁高效。 Interlocked::Increment通过引用传递$using:i,确保所有线程共享同一个计数器,计数准确。
内容的提问来源于stack exchange,提问作者dss.pisces
相关产品推荐
相关产品推荐

