Deano
Deano

Reputation: 155

Create a CSV file from text file

My script outputs a text file of any websites being hosted. The text file would look like the following:

Default
Settings
Layouts
Stackexchangelogon

I need to get these into a CSV file with the following headers:

For Type, I need website name, Base, I need it to have IIS and for Status, I need to have Monitored.

The final output would be something like,

Type                  Base          Status
Default               IIS           Monitored
Settings              IIS           Monitored
Layouts               IIS           Monitored
Stackexchangelogon    IIS           Monitored

I have searched the web and still puzzled on how to achieve this. It needs to work on PowerShell 2.0 because of Windows 2003 hosts.

This is what I have so far -

$website = Get-content "D:\Websites.txt"

$CSV = @()
$row = New-Object System.Object
$website | ForEach-Object {
  $row | Add-Member -MemberType NoteProperty -Force -Name "Type" -Value $_
  $row | Add-Member -MemberType NoteProperty -Force -Name "Base" -Value "IIS"
  $row | Add-Member -MemberType NoteProperty -Force -Name "Status" -Value "Monitored"

  $CSV += $row
}

But its not adding each website. I get repeats of the last one on the list. Result:

Type                         Base                         Status
----                         ----                         ------
Stackexchangelogon           IIS                          Monitored
Stackexchangelogon           IIS                          Monitored
Stackexchangelogon           IIS                          Monitored
Stackexchangelogon           IIS                          Monitored

Any ideas?

Upvotes: 0

Views: 225

Answers (2)

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200473

The code in your question doesn't work because you create $row outside the loop and just modify this one object inside the loop. $CSV += $row then appends a reference to the object to the array. Because of that your array is filled with references to the same object, and the output displays the final state of this single object after the loop.

There are several ways to avoid this, for instance by creating a new object with each iteration (like you do in your own answer), or by appending a clone of the object to the array:

$CSV += $row.PSObject.Copy()

However, both approaches are suboptimal, as they don't make proper use of the pipeline. Your code could be streamlined quite a bit by using calculated properties:

Get-Content 'D:\Websites.txt' |
    Select-Object @{n='Type';e={$_}}, @{n='Base';e={'IIS'}},
                  @{n='Status';e={'Monitored'}} |
    Export-Csv 'D:\test.csv' -NoType

Upvotes: 1

Deano
Deano

Reputation: 155

Resolved using -

$website = Get-content "D:\Websites.txt"

$CSV = @()
$website | ForEach-Object {
    $row = New-Object System.Object
    $row | Add-Member -MemberType NoteProperty -Force -Name "Type" -Value $_
    $row | Add-Member -MemberType NoteProperty -Force -Name "Base" -Value "IIS"
    $row | Add-Member -MemberType NoteProperty -Force -Name "Status" -Value "Monitored"

    $CSV += $row
}

$CSV | Export-Csv "d:\test.csv" -NoTypeInformation

Upvotes: 0

Related Questions