Reputation: 3630
I'm new to powershell, so the script is a Frankenstein of various examples of from sites.
My question is how can I make sure that a csv file I am creating for a DataTable keeps the column order I specify?
My script does this to populate the csv headers and values like so:
...snip...
$dataTable | ForEach-Object {
$csv+=New-Object PSObject -Property @{
program_code=$_.ProgramCode;
first_name=$_.FirstName;
last_name=$_.LastName;
email=$_.email;
phone=$_.phone;
phone2=$_.otherphone;
address=$_.addr1;
address2=$_.addr2;
city=$_.city;
state=$_.state;
postal_code=$_.Zip;
country=$_.Country;
grad_year=$_.HsGradDate;
lead_date=$_.LeadDate;
lead_source=$_.LeadSource;
school_status=$_.SchoolStatus;
}
}
$csv | Export-CSV C:\scripts\NewLeads$(Get-Date -Format yyyyMMdd).csv -notype -Append
...snip...
I want the file to have to columns in the order that I specify in the script, but when I open it in notepad or excel the columns appear in a seemingly random order. Keyword being seemingly since they may have some method of ordering themselves.
Upvotes: 12
Views: 15406
Reputation: 8019
In PowerShell V3, instead of:
$csv+=New-Object PSObject -Property @{
I would use:
$csv+=[pscustomobject]@{
The PowerShell V3 parser will preserve the order of the keys when you cast a hash literal to either [ordered] or [pscustomobject]. A small side benefit to this approach - it will also be faster.
If you are using V2, you'll need to skip the -Property parameter to New-Object and instead use multiple calls to Add-Member. It will look something like:
$csv+=New-Object PSObject |
Add-Member -Name program_code -Value $_.ProgramCode -MemberType NoteProperty -PassThru |
Add-Member -Name first_name -Value $_.FirstName -MemberType NoteProperty -PassThru |
...
Upvotes: 19
Reputation: 28174
Select the fields in the order required, then export.
$csv | select-object -property program_code,first_name,last_name,email,phone,phone2,address,address2,city,state,psotal_code,country,grad_year,lead_date,lead_source,school_status |
Export-CSV C:\scripts\NewLeads$(Get-Date -Format yyyyMMdd).csv -notype -Append
However, you may be able to short-circuit this a little. Depending on what $dataTable
really is, you may (should, in most cases) be able to select directly from that object and bypass creating the collection of PSObjects
. But if you need the custom headers, you'll need to use expressions in select-object
(linebreaks for readability).
$dataTable| select-object @{Name="program_code";Expression={$_.ProgramCode}},`
@{Name="first_name";Expression={$_.firstname}},`
@{Name="last_name";Expression={$_.lastname}},email,phone,`
@{Name="phone2";Expression={$_.otherphone}},`
@{Name="addr1";Expression={$_.address}},`
@{Name="addr2";Expression={$_.address2}},city,state,`
@{Name="postal_code";Expression={$_.zip}},country,`
@{Name="grad_year";Expression={$_.hsgraddate}},`
@{Name="lead_date";Expression={$_.leaddate}},`
@{Name="lead_source";Expression={$_.leadsource}},`
@{Name="school_status ";Expression={$_.schoolstatus }}|
Export-CSV C:\scripts\NewLeads$(Get-Date -Format yyyyMMdd).csv -notype -Append
Upvotes: 11