powershell import-csv two times - powershell

This is possibly a silly question but i tried to import 2 csv-files with powershell.
but when i try to write to the screen only the first one shows.
$connectivityCsvFile = #(Import-Csv "C:\connectivity.csv")
$logfileCsvFile = #(Import-Csv "C:\1-log.csv")
$logfileCsvFile
$connectivityCsvFile
print-screen of output
if I change the $logfileCsvFile with $connectivityCsvFile then the connectivity-file is printed and not the logfile
anyone knows why?

I think what PowerShell is doing is selecting the properties to show you based on the types in the first collection you are writing to output. The second collection has objects with entirely different properties and so the values default to blanks.
The lines
$logFileCsvFile
$connectivityCsvFile
don't really show you the values (at least that's not their primary effect). They cause the script to write the values to the output stream. The values in this stream are then displayed at the end of the command. Having an output stream with two different kinds of objects kind of messes up the default display behavior.
If you want to output to be print in a table format, you should use Format-Table (ft):
$logfileCsvFile | ft
$connectivityCsvFile | ft

Related

Create Record using Headers from a .csv

<EDIT: I kind of have it working, but in order to get it to work, my template csv has to have a blank line for every line I am going to be adding to it. So, if I could figure out how to add lines to the imported empty (just a header row) csv file, I could then use export-csv at the end. (It would be somewhat slower, but it would at least work.)>
I am creating a .csv file in PowerShell. The output file has 140 columns. Many of them are null.
I started out just doing
$out = 'S-'+$Snum+',,,,,TRUE,,,,,'+'S-'+$Snum+',"'
$out = $out + '{0:d9}' -f $item.SupplierCode2
until I had filled all the columns with the correct value. But, the system that is reading the output keeps changing the column locations. So, I wanted to take the header row from the template for the system and use that to name the columns. Then, if the columns change location, it won't matter because I will be referring to it by name.
Because there are so many columns, I'm trying to avoid a solution that has me enter all the column names. By using a blank .csv with just the headers, I can just paste that into the csv whenever it changes and I won't have to change my code.
So, I started by reading my csv file in so I can use the headers.
$TempA = Import-Csv -Path $Pathta -Encoding Default
Then I was hoping I could do something like this:
$TempA.'Supplier Key' = "S-$Snum"
$TempA.'Auto Complete' = "TRUE"
$TempA.'Supplier ID' = "S-$Snum"
$tempA.'Supplier Data - Supplier Reference ID' = '{0:d9}' -f $item.SupplierCode2
I would only need to fill in the fields that have values, everything else would be null.
Then I was thinking I could write out this record to a file. My old write looked like this
$writer2.WriteLine($out)
I wanted to write the line from the new csv line instead
$writer2.WriteLine($TempA)
I'd rather use streams if I can because the files are large and using add-Content really slows things down.
I know I need to do something to add a line to $TempA and I would like each loop to start with a new line (with all nulls) because there are times when certain lines only have a small subset of the values populated.
Clearly, I'm not taking the correct approach here. I'd really appreciate any advice anyone can give me.
Thank you.
If you only want to fill in certain fields, and don't mind using Export-Csv you can use the -append and -force switches, and it will put the properties in the right places. For example, if you had the template CSV file with only the column names in it you could do:
$Output = ForEach($item in $allItems){
[PSCustomObject]#{
'Supplier Key' = "S-$Snum"
'Auto Complete' = "TRUE"
'Supplier ID' = "S-$Snum"
'Supplier Data - Supplier Reference ID' = '{0:d9}' -f $item.SupplierCode2
}
}
$Output | Export-Csv -Path $Pathta -Append -Force
That would create objects with only the four properties that you are interested in, and then output them to the CSV in the correct columns, adding commas as needed to create blank values for all other columns.

Combining multiple csv files in Powershell changes format

I'm attempting to combine numerous csv files into a single outfile. It works okay in that the files are combined, however it changes the format of the outfile by making every line from the input files as a single value that just happens to contain commas. In other words, I get "1,2,3" in a single cell instead of "1" "2" "3" each in their own cell.
Get-Content C:\RollingLogs\*.csv | Out-File C:\CombinedLogs\outfile.csv
Here is a snip from the output file, if that helps to explain what's happening. The desired output is for "1" to be in column A, "2" in column B, etc. Instead we wind up with "1,2,3" all in column A.
I've tried specifying the comma as a delimiter with Out-File, but just makes everything a new line instead of keeping them in proper rows, which is worse. I also tried gc *.csv | Export-Csv outfile.csv but it just hangs without doing anything. Export-csv also changes the contents (1,2,3 from the input becomes "#TYPE System.Int32" and I don't know why). I have wondered if Import-Csv file1.csv | Export-Csv -Append outfile.csv might work, but since there are multiple input files it would require a foreach loop (I think?) and I have no idea how to do that.
Edit: Contents of the input file as seen in Notepad, to see delimiters
TCP,svchost.exe,1404,LISTENING
TCP,System,4,LISTENING
TCP,System,4,LISTENING
There are line breaks after the G, but they don't show up in StackOverflow without editing it more.

PowerShell to extract specific column from csv and store in a variable

My keys.csv file looks like this
PrjKey BldKey key
LS LOOKUPSNAP1 LS-LOOKUPSNAP1
LS LSUH3 LS-LSUH3
LSPERF LPMDS0 LSPERF-LPMDS0
LSPERF LSP0 LSPERF-LSP0
I want to extract the values column "key" and store in a variable. I tried this
Import-Csv .\keys.csv | select key | ft -hide
the output has a blank line at the top. How can I eliminate it. I only want those 4 values to be "stored in a variable" Yes I don't want to save the output as a csv again.
Can someone help please?
You had the right idea of using Select-Object to get the one property you want. The two issues you had was that Select-Object key returns and object array with a key property when it looks like you just want string array of keys. Also never use Format-cmdlets when you want to save the data or use it in another form. They destroy objects for the purpose of display data on the screen. So that all being said..
$keys = Import-Csv .\keys.csv | select -ExpandProperty key
Depending on your PowerShell version
$keys = (Import-Csv .\keys.csv).key

powershell desc analogy - list output columns and their types

If there anything like SQL's describe so I don't have to look through a "blanket" of | select * output before actually selecting the few columns that I need?
E.g. Get-Process's possible output columns include Id, Name,VirtualMemorySize as well as about three dozen others. I want to get that list of column names, preferrably with their types.
If this for human viewable output then use Format-Table e.g.
Get-Process | Format-Table Name,Id,PM -Auto
Note: if you have lots of output do not use the -AutoSize parameter as that buffers up all its input to determine the optimal size of each column. If you don't specify that parameter, PowerShell will split up the screen space evenly based on number of properties selected but it will display each object as soon as it is received.
For the "column" names, that is bit trickier. You can easily get the list of "ALL" the property names e.g.:
Get-Process | Get-Member -MemberType Properties
If you want just the properties that would normally be display by Format-Table then you need to inspect the View Definition for the System.Diagnostics.Process type in C:\Windows\System32\WindowsPowerShell\v1.0\DotNetTypes.format.ps1xml.

why export-csv returns a file that contains wierd data?

I have a binary cmdlet Get-CustomPSObject. When I do something like:
Get-CustomPSObject > a.txt
the result is stored as a plain text, meaning that the Get-CustomPSObject is working fine.
However when I try:
Get-CustomPSObject | Export-csv a.csv
The a.csv file becomes:
"Capacity","Count","IsReadOnly","IsFixedSize","SyncRoot","IsSynchronized"
"4","1","False","False","System.Object","False"
none of these fields are in my PSObject. I've no idea what they stands for. Any thoughts?
Export-CSV takes the first object it recieves to create the headers. Most likely, your Get-CustomPSOjbect runs a method/cmdlet/script that returns an object you didn't save. E.g. you use something like
get-childitem
and not
$files = get-childitem
inside your Get-CustomPSObject function.
EDIT
Okay, so you're cmdlet is a binary cmdlet. Important information. I'm no expert in this, so please correct me if I'm wrong.
When you make a binary cmdlet that can output multiple objects, you need to write them one by one. One of the ideas behind PowerShell is the use of a pipeline that can use objects as they come without waiting for the complete array.
Because of your current "design flaw" in your binary cmdlet, Export-CSV tries to export the array(as one item) to a csv-file and not the elements inside.
You now use this:
WriteObject(list/array of objects)
This is bad. It outputs all objects at the same time.
To fix it, run this at the end of your "object-creation-loop":
WriteObject(mycurrentobject)
This is good. You enable the use of pipeline and every object is sent out one by one when they're created. Export-CSV can then recieve each object and convert them to csv-format.
In your first example using > the output is run through Powershell formatting system while in the second using export-csv it is not.
If you look at get-custompsobject | gm you should see those extra properties that aren't shown in console or sent to your text file.
For export-csv you can control which properties are sent to the csv file using select-object
get-custompsobjct | select-object column1, column2 | export-csv a.csv