PowerShell创建三列哈希表实现Windows服务账号信息CSV导出
修复后可运行的PowerShell脚本
核心优化&特性
- 弃用低效的
+=数组追加操作,改用[System.Collections.Generic.List[PSObject]]存储结果,大批量查询时执行效率提升显著 - 移除冗余的哈希表中间存储逻辑,处理作业结果时直接构造输出对象,避免原代码中嵌套循环导致的字段匹配错误
- 替换已弃用的
Get-WmiObject为Get-CimInstance,远程查询稳定性更高、资源占用更低 - 原生支持多服务器批量查询,可直接修改
$servers变量填入远程设备列表
# 配置项,可根据需求修改 $servers = @($env:COMPUTERNAME) # 远程设备列表,多个设备用逗号分隔,如 @('PC01','SERVER01','PC02') $tgtAcct = 'SYSTEM' # 要匹配的服务账号特征,查域账号可填域名前缀如 'CONTOSO\\' $reportCsv = Join-Path -Path ([Environment]::GetFolderPath("Desktop")) -ChildPath ("report.$(Get-Date -Format "yyyyMMdd_HHmmss").csv") # 初始化结果集合,使用泛型列表避免+=的性能损耗 $outputList = [System.Collections.Generic.List[PSObject]]::new() $GetServiceAccounts = { [CmdletBinding()] param( $hostname ) $serviceList = @(Get-CimInstance -ClassName Win32_Service -ComputerName $hostname -Property Name, StartName, SystemName -ErrorAction Stop) return $serviceList } Function Process-CompletedJobs(){ $jobs = Get-Job -State Completed ForEach ($job in $jobs) { $data = Receive-Job $job Remove-Job $job If ($data -is [System.Object[]]) { $serviceList = $data | Where-Object { $_.StartName -ne $null -and $_.StartName.ToUpper().Contains($tgtAcct.ToUpper()) } ForEach ($service in $serviceList) { # 直接构造输出对象加入结果集,无需中间存储 $row = [PSCustomObject]@{ Account = $service.StartName Service = $service.Name Hostname = $service.SystemName } $outputList.Add($row) } } } } # 批量启动查询作业 foreach ($server in $servers) { Start-Job -ScriptBlock $GetServiceAccounts -Name "read_$($server)" -ArgumentList $server | Out-Null } # 等待所有作业完成后处理结果 Get-Job | Wait-Job | Out-Null Process-CompletedJobs # 导出CSV $outputList | Export-Csv -Path $reportCsv -NoTypeInformation -Encoding UTF8
注意:远程查询设备服务需要当前执行账号具备目标设备的管理员权限,且目标设备防火墙开放WMI/CIM相关入站规则
内容的提问来源于stack exchange,提问作者ToToRoYN
相关产品推荐
相关产品推荐

