Issue in export Array to CSV file

2019-09-21 22:55发布

I have list of machine in text file and I am trying to get the details of physical drives, OS architecture and physical memory. With the help of Matt (SO user) here is the powershell script.

$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 
}

Problem is in the CSV file I am getting single machine details but in server.txt file there are more than 1 machine. If I print $infoObject1 before New-Object then I can see there are details of multiple machine. It seems like some issue with array and I am not able to export it in CSV.

Can anybody please suggest on this.

2条回答
Melony?
2楼-- · 2019-09-21 23:38
foreach ($server in $servers) {
   ...
   New-Object -TypeName PSObject -Property $infoObject1 |
     Export-Csv -Path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation 
}

You're exporting inside the loop without using the parameter -Append (available in PowerShell v3 and newer). That overwrites your output file with each iteration, leaving you with just the data of the last server.

Either use the parameter -Append (if you have PowerShell v3 or newer):

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

or move Export-Csv outside the loop (works with all PowerShell versions):

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

Note that you need to run the loop in parentheses for this to work, as foreach loops don't output to the pipeline.

You could also replace the foreach loop with ForEach-Object if you want to feed the pipeline directly:

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
查看更多
等我变得足够好
3楼-- · 2019-09-21 23:47

It looks like you are having issues integrating my code. You have added a second loop that should not be there. Also as other users pointed out you are not creating the per server object outside the loop. The answer, from where your code comes from, has that part correct. I had even showed you where to put the 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 
查看更多
登录 后发表回答