Author Posts

April 11, 2016 at 8:28 pm

I am writing a bit of code and came across a situation where I have some output from foreach but I cannot figure out how I can export to a csv.

the code i have is as follows:


$servers = import-csv D:\server_list.csv

        foreach ($server in $servers){
        $servername = $server.computername        
            try {
            Get-ADComputer $servername -properties description | select name, description -ErrorVariable SilentlyContinue

            } catch{
       
                $testpath = test-path d:\15393848.txt

                    if ($testpath -eq $false){

                        New-item -itemtype file -name 15393848.txt -path d:\
        
                        }

                    Add-Content -Path d:\15393848.txt -value "$servername"

            }
    }

It outputs correctly and puts the text in the error log if the computer doesnt exist but need to have the display output in a csv. I had a look around the web and tried to use whats there and i saw one example of one guy use objects (http://goo.gl/VN7Imr)
but I don't think I am understanding the core concept in regards to this.

Any help appreciated.

April 11, 2016 at 10:48 pm

You can define a customized object if you want, but if you just want the result, you can assign a variable to to your for loop. Get-ADComputer has returned an ADObject for you already.

$servers = import-csv D:\server_list.csv

     $result=  foreach ($server in $servers){
        $servername = $server.computername        
            try {
            Get-ADComputer $servername -properties description | select name, description -ErrorVariable SilentlyContinue

            } catch{
       
                $testpath = test-path d:\15393848.txt

                    if ($testpath -eq $false){

                        New-item -itemtype file -name 15393848.txt -path d:\
        
                        }

                    Add-Content -Path d:\15393848.txt -value "$servername"

            }
    }

$result | export-csv c:\temp\server.csv 

Also´╝îin your url example, that's the old way to define a customized object- you define a hash table structure and then convert it to an object. After Powershell v3, you can directly use [pscustomobject] to create one in your loop.

Btw, I think you're Chinese from your name. If you can read Chinese, you can see my blog for more examples. http://beanxyz.blog.51cto.com/5570417/1737512

Cheers
Yuan

April 12, 2016 at 4:00 am

You can also change your code a little to use the ForEach-Object Cmdlet rather than the ForEach statement

Example:

ForEach ($dir in @("C:\","C:\Users","C:\Windows")){
    Get-ChildItem $dir
}

Using the above example, if I added a Pipe to export after the ForEach, I get an error.

ForEach ($dir in @("C:\","C:\Users","C:\Windows")){
    Get-ChildItem $dir
} | Export-Csv C:\Temp\Export.csv
At line:4 char:3
+ } | Export-Csv C:\Temp\Export.csv
+   ~
An empty pipe element is not allowed.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : EmptyPipeElement

This is because statements in and of themselves do not export object to the pipeline. In order to get the above code to work, I would need to add the Export on the cmdlet that actually exports the object for Export-CSV to work on.

ForEach ($dir in @("C:\","C:\Users","C:\Windows")){
    Get-ChildItem $dir | Export-Csv C:\Temp\Export.csv -Append
}

This works OK, but since it is inside the loop, I have to use the -Append parameter so the previous data does not get over-written each time through the loop. That also means additional IO which will cause the script to run slower and use more resources on the system.

What I can do instead is change this to use the ForEach-Object cmdlet to continue the pipeline.

@("C:\","C:\Users","C:\Windows") | ForEach-Object {
    Get-ChildItem $_
} | Export-Csv C:\Temp\Export.csv

Since ForEach-Object is a cmdlet that outputs objects to the Pipeline, Export-CSV will gladly take those objects as input.