Author Posts

May 9, 2013 at 1:00 am

First the code:

$servers = "Server01", "Server02"

ForEach ($server in $servers) {

# Get the WMI information
$os = get-wmiobject -class win32_operatingsystem -computerName $server
$cs = get-wmiobject -class win32_computersystem -computerName $server
$AssetTag = Get-WmiObject Win32_SystemEnclosure -ComputerName $server

# Create a new Object to contain all necessary WMI information abou the Server

$Props = @{ Computername = $os.__Server
OS = $os.Caption
BoardManufacturer = $cs.manufacturer
AssetTag = $AssetTag.SerialNumber
}

$obj = New-Object -TypeName PSObject -Property $Props

 $foo = @()

$Foo += $obj
$foo
}

Now the question:

the $Foo at the end gives me a table with 2 rows, correctly filled in on the console.  All seems fine

 

Now if I do:  $Foo | export-csv c:\export.csv  I only get the information of Server02 in my csv, none of the info of the first server is there..

It doesn't matter if I do it inside or outside the Foreach loop.

 

If I do $Foo | out-gridview  inside the Foreach loop, it actually opens 2 gridview windows, each containing the information about one of the servers.

 

If I do $Foo | out-gridview outside of the Forach loop, then I only get one window that opens, which contains the info of Server02

 

 

This is driving me crazy, I'm missing something, but I can't put my hand on it.  It's weird that $foo looks fine when I run it in the console (inside the foreach loop) but doesn't export correctly.

 

May 9, 2013 at 2:07 am

Hi,

You are doing export to csv into loop "foreach", try do declare variable ex. $foo = @() before "foreach" loop  like this:

$foo = @()
ForEach ($server in $servers) {
...
$foo += something
}
$foo | export-csv .....

Should work.

 

 

Regards,

Kamil Tatar

May 9, 2013 at 2:25 am

Kamil, thank you very much.  You were spot on.

I assume that I re-declared $foo () each time the loop ran? (emptying it basically?  )

May 9, 2013 at 6:46 am

And as a note, the usual practice is to just write a function or script that outputs to the pipeline, rather than accumulating the objects in your own array first. Accumulating creates a blocking command in the pipeline.

 

May 9, 2013 at 8:19 am

I'm afraid that I don't understand what you mean with that.

I based myself on listing 21.8 of Powershell in Depth, and I don't see a function in there.

 

 

May 11, 2013 at 4:15 pm

Phillippe,

So what Don is trying to tell you is that by creating an object and putting it into an array you're messing with the flow of the pipeline.  I've modified your script and I'm putting it in a codeblock below:

$servers = “Server01", "Server02"
ForEach ($server in $servers) 
    {
        # Get the WMI information
        $os = get-wmiobject -class win32_operatingsystem -computerName $server
        $cs = get-wmiobject -class win32_computersystem -computerName $server
        $AssetTag = Get-WmiObject Win32_SystemEnclosure -ComputerName $server

        # Create a new Object to contain all necessary WMI information abou the Server

        $Props = @{ 
                Computername = $os.__Server
                OS = $os.Caption
                BoardManufacturer = $cs.manufacturer
                AssetTag = $AssetTag.SerialNumber
            }
        New-Object -TypeName PSObject -Property $Props
    }

Now that script will output an object for each ComputerName you run through it.  That means you can send it to export-csv or out-gridview or anything else.  It's bad practice, and in this case entirely unnecessary, to load custom objects into an array as part of your function or script.