导出阵列到CSV文件中的问题

时间:2016-01-08 09:57:16

标签: csv powershell powershell-v2.0

我在文本文件中有机器列表,我正在尝试获取物理驱动器,操作系统架构和物理内存的详细信息。在Matt(SO用户)的帮助下,这里是powershell脚本。

$server = Get-Content .\Server.txt
#$infoObject11 = @{}
$infoObject11 = @{}
foreach ($server in $servers) {
    # Gather all wmi drives query at once
    $alldisksInfo = Get-WmiObject -Query "SELECT * FROM Win32_DiskDrive" -ComputerName $server -ErrorAction SilentlyContinue | Group-Object __Server

    # Figure out the maximum number of disks
    $MaximumDrives = $alldisksInfo | Measure-Object -Property Count -Maximum | Select-Object -ExpandProperty Maximum

    # Build the objects, making empty properties for the drives that dont exist for each server where need be. 
    $server | ForEach-Object {
        # Clean the hashtable
        $infoObject1 = @{}
        # Populate Server
        $infoObject1.Server = $server 
        $HOSTNAME = Get-WMIObject -Query "Select * from Win32_OperatingSystem" -ComputerName $infoObject1.Server
        # Add other simple properties here
        $infoObject1.PhysicalMemory = (Get-WmiObject Win32_PhysicalMemory -ComputerName $infoObject1.Server | Measure-Object Capacity -Sum).Sum/1gb
        $infoObject1.OSarchitecture =$HOSTNAME.osarchitecture

        # Add the disks information from the $diskInfo Array
        $serverDisksWMI = $alldisksInfo | Where-Object{$_.Name -eq $infoObject1.Server} | Select-Object -ExpandProperty Group

        for ($diskIndex =0; $diskIndex -lt $MaximumDrives;$diskIndex++) {
            $infoObject1."PhysicalDisk$diskIndex" = [Math]::Round(($serverDisksWMI | Where-Object{($_.DeviceID -replace "^\D*") -eq $diskIndex} | Select -Expand Size)/1GB)
        }


    }
    # Create the custom object now.
    New-Object -TypeName psobject -Property $infoObject1  | Export-Csv -path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation 
}

问题出在CSV文件中我得到的是单机详细信息,但在server.txt文件中有多台机器。如果我在$infoObject1之前打印New-Object,那么我可以看到有多台机器的详细信息。这似乎是数组的一些问题,我无法以CSV格式导出它。

任何人都可以就此提出建议。

2 个答案:

答案 0 :(得分:3)

看起来您在集成我的代码时遇到了问题。你添加了第二个不应该存在的循环。另外,正如其他用户指出的那样,您不是在外部创建每服务器对象循环。 The answer, from where your code comes from, has that part correct。我甚至告诉过你把Export-CSV放在哪里。

$servers = Get-Content .\Server.txt

# Gather all wmi drives query at once
$alldisksInfo = Get-WmiObject -Query "SELECT * FROM Win32_DiskDrive" -ComputerName $servers -ErrorAction SilentlyContinue | Group-Object __Server

# Figure out the maximum number of disks
$MaximumDrives = $alldisksInfo | Measure-Object -Property Count -Maximum | Select-Object -ExpandProperty Maximum

# Build the objects, making empty properties for the drives that dont exist for each server where need be. 
$servers | ForEach-Object {
    # Clean the hashtable
    $infoObject1 = @{}
    # Populate Server
    $infoObject1.Server = $_ 
    # Add other simple properties here
    $infoObject1.PhysicalMemory = (Get-WmiObject Win32_PhysicalMemory -ComputerName $infoObject1.Server | Measure-Object Capacity -Sum | Select-Object -ExpandProperty Sum)/1GB
    $infoObject1.OSarchitecture = Get-WMIObject -Query "Select * from Win32_OperatingSystem" -ComputerName $infoObject1.Server | Select-Object -ExpandProperty OSArchitecture

    # Add the disks information from the $diskInfo Array
    $serverDisksWMI = $alldisksInfo | Where-Object{$_.Name -eq $infoObject1.Server} | Select-Object -ExpandProperty Group

    for ($diskIndex =0; $diskIndex -lt $MaximumDrives;$diskIndex++) {
        $infoObject1."PhysicalDisk$diskIndex" = [Math]::Round(($serverDisksWMI | Where-Object{($_.DeviceID -replace "^\D*") -eq $diskIndex} | Select-Object -ExpandProperty Size)/1GB)
    }

    # Create the custom object now for this pass in the loop.
    New-Object -TypeName psobject -Property $infoObject1  
} | Export-Csv -path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation 

答案 1 :(得分:2)

foreach ($server in $servers) {
   ...
   New-Object -TypeName PSObject -Property $infoObject1 |
     Export-Csv -Path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation 
}

您使用参数-Append(在PowerShell v3及更新版本中提供)

这会在每次迭代时覆盖您的输出文件,只留下最后一台服务器的数据。

使用参数-Append(如果你有PowerShell v3或更新版本):

foreach ($server in $servers) {
   ...
   New-Object -TypeName PSObject -Property $infoObject1 |
     Export-Csv -Append -Path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation
}

或将Export-Csv移到循环之外(适用于所有PowerShell版本):

(foreach ($server in $servers) {
   ...
   New-Object -TypeName PSObject -Property $infoObject1
}) | Export-Csv -Path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation

请注意,您需要在括号中运行循环才能使其正常工作,因为foreach循环不会输出到管道。

如果您想直接提供管道,也可以将foreach循环替换为ForEach-Object

Get-Content .\Server.txt | ForEach-Object {
   $server = $_
   ...
   New-Object -TypeName PSObject -Property $infoObject1
} | Export-Csv -Path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation