Powershell add header to blank csv - csv

I have a process that I am trying to fully automated and have hit upon a stumbling block.
The process runs through a number of SQL queries and then outputs these results to different named CSV files.
Where my issue lies is that where no results are returned in the query to the dataset when I export the data (which I must do to satisfy auditors) there is no header data written to the CSV file.
What I need to do therefore is IF the dataset contains 0 rows then to simply export a CSV file containing the headings "Client", "Balance", "Account".
Where as if there is data within the table then the process can continue as it currently does.
What I am is unsure how the hell this can be achieved...
I am currently muting whether or not I will have to export the data and then write a loop to delete any lines from the CSV containing for example "Client" then re-import the CSV's add the column heading that I want and export it again. As this is messy, ideally I would like to keep away from this..
Code is
$SqlCmd.CommandTimeout=$timeout;
$SqlCMD.CommandText = $034CASHQUERY;
$SqlCmd.Connection = $SqlConnection;
## - Extract Data and build sql data object
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter;
$SqlAdapter.SelectCommand = $SqlCmd;
$DataSet = New-Object System.Data.DataSet;
$SqlAdapter.Fill($DataSet);
$DataSetTable = $DataSet.Tables["Table"];
IF($DataSet.Tables["Table"]){
$isnotnull
$DataSet.Tables["Table"] | Export-Csv $034CASHOUT -NoTypeInformation
echo "CL2 Exported"
}
else {
}
Has anyone come across this before or aware of how to iterate through the issue?

You could create a .csv file and add the header text manually.
$headerText = ('"Client","Balance","Account"' + "`n")
New-Item $034CASHOUT | Add-Content -value $headerText
Also, I think your IF condition may be a bit wonky. Are you looking for:
IF($DataSet.Tables["Table"] -isnot $null)
All together:
IF($DataSet.Tables["Table"] -isnot $null){
$DataSet.Tables["Table"] | Export-Csv $034CASHOUT -NoTypeInformation
echo "CL2 Exported"
}
else {
$headerText = ('"Client","Balance","Account"' + "`n")
New-Item $034CASHOUT | Add-Content -value $headerText
}
This is probably not the best way to do it, but I think this is what you described.

Can you please provide more information on the data you're processing? I understand if there is no data you want "Client", "Balance", "Account".
When there is data present, will it also be in these 3 columns?
If so this is your answer:
$DataSet.Tables["Table"] |
Select-Object Client,Balance,Account |
Export-Csv $034CASHOUT -NoTypeInformation

Related

use where-object to find data, but want to add data to every row also the export to csv

Hi I have a script that reads a csv file, creates a json file, checks the users in the file against a service, then i get the result as a json file.
I take that result and finds the users i csv file and creates a new file.
I do that with a where-object
But i need to add some extra values on every user before i export it to csv
This is my 2 lines for finding users and then export
$matches = $users | where-object { $_.number -in $response.allowedItemIds } | Select-Object -Property Number,Surname,Forename,Emailaddress
$matches | Export-Csv -path $Saved$savefile -NoTypeInformation -Append
Is that possible or do i need to do a for each?
Cheers
Assuming I've interpretted your question correctly, you should be able to use PowerShell's Calculated Properties for this purpose.
For example, if you wanted to add a field called "Date" and set the current Date/Time to each user row, you could do the following:
$matches = $users | where-object { $_.number -in $response.allowedItemIds } | Select-Object -Property Number,Surname,Forename,Emailaddress, #{Name="Date";Expression={Get-Date}}
The Expression value can either be a static value such as "StaticValue", a variable such as $i (useful if used as part of a loop, for example) or more complex value that is returned from other cmdlets (as in my example above)

Merge two CSV files into one

I have two CSV files that don't have any unique identifiers. The number of rows of both files is always the same. I want to merge them as it is (the 2nd CSV as additional columns into the 1st CSV).
Content of file1.csv:
Server,Info
server1,item1
server1,item2
server1,item3
server2,item1
server2,item2
server2,item3
server3,item1
server3,item2
server3,item3
Content of file2.csv:
Items,ColumnA,ColumnB,ColumnC
item#1:,aa,jj,ss
item#2:,bb,kk,tt
item#3:,cc,ll,uu
item#1:,dd,mm,vv
item#2:,ee,nn,ww
item#3:,ff,oo,xx
item#1:,gg,pp,yy
item#2:,hh,qq,zz
item#3:,ii,rr,ab
Expecting output of csv file:
Server,Info,Items,ColumnA,ColumnB,ColumnC
server1,item1,item#1:,aa,jj,ss
server1,item2,item#2:,bb,kk,tt
server1,item3,item#3:,cc,ll,uu
server2,item1,item#1:,dd,mm,vv
server2,item2,item#2:,ee,nn,ww
server2,item3,item#3:,ff,oo,xx
server3,item1,item#1:,gg,pp,yy
server3,item2,item#2:,hh,qq,zz
server3,item3,item#3:,ii,rr,ab
I have search intensively in the net, but couldn't find any solution... Would really appreciate if someone can provide me some answers here...
You can use the Get-Content cmdlet to read both CSV files, iterate over it using a for-loop and use a format string to join them together. Finally, write the new file back using the Out-File cmdlet:
$file1 = Get-Content 'Path_to_file1.csv'
$file2 = Get-Content 'Path_to_file2.csv'
$content = for ($i = 0; $i -lt $file1.Length; $i++)
{
'{0},{1}' -f $file1[$i].Trim(), $file2[$i].Trim()
}
$content | out-file 'Path_to_file3.csv'

Find and Replace many Items with Powershell from Data within a CSV, XLS or two txt documents

So I recently have found the need to do a find and replace of mutliple items within a XML document. Currently I have found the code below which will allow me to do multiple find and replaces but these are hard coded within the powershell.
(get-content c:\temp\report2.xml) | foreach-object {$_ -replace "192.168.1.1", "Server1"} | foreach-object {$_ -replace "192.168.1.20", "RandomServername"} | set-content c:\temp\report3.xml
Ideally instead of hard coding the value I would like to find and replace from a list, ideally in a CSV or and XLSX. Maybe two txt file would be easier.
If it was from a CSV it could grab the value to find from A1 and the value to replace it with from B1 and keep looping down until the values are empty.
I understand I would have to use the get-content and the for each command I was just wondering if this was possible and how to go about it/ if anybody could help me.
Thanks in advance.
SG
#next line is to clear output file
$null > c:\temp\report3.xml
$replacers = Import-Csv c:\temp\replaceSource.csv
gc c:\temp\aip.xml | ForEach-Object {
$output = $_
foreach ($r in $replacers) {
$output = $output -replace $r.ReplaceWhat, $r.ReplaceTo
}
#the output has to be appended, not to rewrite everything
return $output | Out-File c:\temp\report3.xml -Append
}
Content of replaceSource.csv looks like:
ReplaceWhat,ReplaceTo
192.168.1.1,server1
192.168.1.20,SERVER2
Note the headers

Powershell: Reading in a column from a .CSV file and then adding a specific string to the beginning and exporting again

I'm attempting to write a script which will read in a CSV generated by querying AD for user information (that part is done) but then will allow me to add a string to the beginning of each value of a column in the CSV file and then export it.
For instance we have this CSV file:
"displayname","Office"
Bob,7142
Janet,8923
SantaClaus,0912
NicCage,0823
I want to take each entry for "Office", add the string "BUG" before it and then export it back out. The modified CSV should look like:
"displayname","Office"
Bob,BUG7142
Janet,BUG8923
SantaClaus,BUG0912
NicCage,BUG0823
At this point, I've been attempting to read in just the "Office" column and then displaying it with "Write-Host". The idea being that if I can do that then maybe I can create a new variable that would be something like:
$BUG = "BUG"
$NewVar = $BUG$Office
Which would hopefully look like the second CSV file. I am extremely new to powershell scripting.
The attempts I've made so far are these:
Attempt #1:
$UserList = Import-CSV C:\Users\username\CSV.csv
$UserList | ForEach-Object ($_.Office) { $UserList }
Attempt #2:
$projectName = import-csv C:\Users\username\CSV.csv | % {$_.Office}
$BUG = "BUG"
$projectName | ForEach-Object ($_) {$projectName}
Attempt #3:
$UserList = Import-CSV C:\Users\username\CSV.csv
#ForEach ($Office in $Userlist) {
#Write-Host $UserList.Office
#}
Attempt #4:
Import-Csv "C:\Users\username\CSV.csv" -Header ("displayname","Office","whenCreated","EmailAddress") | Select-Object Office | Export-CSV -Path C:\users\Username\test.csv
I have gotten it to read out just the Office numbers before using the ForEach-Object loop structure but then it never stops reading out the office numbers so that's unhelpful.
I think I'm going in the right direction, but I just can't figure out how to modify a column like this.
Instead of trying to extract the Office column, just pipe the full data set (all columns) to ForEach-Object, change the value of the Office property and pipe it back to Export-Csv:
$Prefix = "BUG"
Import-Csv .\file.csv | ForEach-Object {
$_.Office = $Prefix + $_.Office
$_
} | Export-Csv .\file_modified.csv -NoTypeInformation

powershell ip address csv file

I am trying to dump the contents of only the live adapters to a csv file, for later importing.
The issue was the usage of $_. below.
$colNicConfigs = Get-WMIObject Win32_NetworkAdapterConfiguration | where { $_.IPEnabled -eq "TRUE" }
#loop over each adapter
foreach ($objNicConfig in $colNicConfigs)
{
$objnic=Get-WMIObject Win32_NetworkAdapter | where {$_.deviceID -eq "$objNicConfig.Index" }
#$strname=$objnicconfig.description.split(":")[0]
#replace strname above when testing against actual server since no dot1q defined on my wks
$strname="MGMT:Something"
$connid=$_.NetworkConnectionID
$ipaddr=$_.IPAddress(0)
$ipsm=$_.IPSubnet(0)
$dg=$_.DefaultIPGateway
}
# create dictionary entries
$report = #()
$report += New-Object psobject -Property #{Name=$strname;ConnID=$connid;IP=$ipaddr;SM=$ipsm;DG=$dg}
$report | export-csv .\nic.csv
Your initial issues are the use of "$underscore" within your foreach loop. If you want to reference properties of the $objNicConfig you will use that in place of the "$underscore". So instead of $connid=$_.networkConnectionID you would use $connid=$objNicConfig.networkConnectionID
Also IpAddress and IPSubnet are not methods they are properties, so dropping the (0) will return the write info. If your NIC has multiple IPs I cannot attest to how this will display as my machine does not, that I'm testing on.
Other things I see is that you will need to nest another foreach loop in there in order to reference both WMI namespaces...so something like:
$colNicConfigs = Get-WMIObject Win32_NetworkAdapterConfiguration | where { $_.IPEnabled -eq "TRUE" }
foreach ($objNicConfig in $colNicConfigs)
{
foreach($objnic in (gwmi win32_networkadapter | where {$_.DeviceID -eq $objNicConfig.Index}))
{
$strName = "MGMT:Something"
$objNicConfig.NetworkConnectionID
$objNicConfig.IpAddress
$objNic.IPSubnet
$objNicConfig.DefaultIPGateway
}
}
The above code is what I used to return info on the NICs of my computer.
Now with the "dictionary entries" section. You will not be able to reference the variables within your foreach loop in the manner of adding a psobject. You are only going to capture the last one found within the foreach loop code. If you want to first collect the information in your foreach loop and then use it later down in your script I would suggest looking at hash tables for this.