Related
I am trying to get the value and format in a certain way. I tried a few methods but it didn't work. I am new to Powershell and still learning.
Add-Content -Path data.csv -Value ‘"Type","Res","Size”'
$aList= #()
$Accountinfo = Get-AzStorageAccount -ResourceGroupName $resName
IF ($($Accountinfo).count -gt 0) {
foreach ($accountiinform in $Accountinfo) {
$Names = "Storage Account"
$props = [ordered]#{
"Res" = $Names
"Name" = $accountiinform.StorageAccountName
}
$aList += New-Object pscustomobject -Property $props
}
}
# There are more if statement-checking more resources and adding the $props object to $alist
$aList | foreach { Add-Content -Path data.csv -Value $_ }
what data.csv has:
"Type","Res","Size"
#{Res=Storage Account; Name=dataStorage;}
#{Res=VM; Name=dataVM; Size=250 GB;}
#{Res=VM; Name=dataVM2; Size=500 GB;}
What I want:
"Type","Res","Size"
Storage Account, Name=dataStorage,
VM,dataVM, 250 GB
VM, dataVM2,500 GB
Please change the last line to:
Replace
$aList | foreach { Add-Content -Path data.csv -Value $_ }
With this:
$aList | Export-Csv -Path C:\Temp\data.csv -NoTypeInformation
I have a csv file that contains lines that I'd like to extract and add as columns to a separate csv file.
This is an example of the contents of the first csv file.
I want to take everything between the third comma and semi-colon for each one and add them as columns to this csv file.
My desired output is this. Because there may be multiple servers in the first csv file I'd like to export a csv for each server but I can figure that bit out.
I've been playing around with the following but I can't figure it out.
Import-CSV $CsvTargetPath | ForEach-Object {
$newData = $_
Import-CSV $CsvSourcePath | ForEach-Object {
$_.AdditionalDisks.split(";") | ForEach-Object {
$newRecordProperties = [ordered]#{
$DriveLetter = $_.split(",")[3]
$Label = $_.split(",")[4]
$Filesystem = $_.split(",")[5]
}
$newRecord = new-object psobject -Property $newRecordProperties
Write-Output $newRecord
}
$CsvTargetPath | Add-Member -MemberType NoteProperty -Name DriveLetter -Value $DriveLetter -PassThru
$CsvTargetPath | Add-Member -MemberType NoteProperty -Name Label -Value $Label -PassThru
$CsvTargetPath | Add-Member -MemberType NoteProperty -Name Filesystem -Value $Filesystem -PassThru
}
} | Export-CSV $CsvTargetPath -NoTypeInformation
Here is the contents of the first csv in plain text.
VmName AdditionalDisks
Server01 90,0,thick,b,sql backup,refs;110,1,thick,d,sql data,refs;60,2,thick,f,sql transaction log,refs;50,3,thin,l,sql audit,refs;30,0,thick,t,sql tempdb data,refs
Server02 90,0,thick,b,sql backup,refs;110,1,thick,d,sql data,refs;60,2,thick,f,sql transaction log,refs;50,3,thin,l,sql audit,refs;30,0,thick,t,sql tempdb data,refs
Assuming the second csv file can also hold info for multiple servers (how else would you know the Uuid for each disk?), you could do like below
$additionalDiskInfo = Import-Csv -Path 'D:\Test\file1.csv'
$serverInfo = Import-Csv -Path 'D:\Test\file2.csv'
$additionalDiskInfo | ForEach-Object {
$server = $_.VmName
$targetItems = $serverInfo | Where-Object { $_.VmName -eq $server }
$extraDisks = $_.AdditionalDisks -split ';'
# make sure you don't run into index errors
$maxItems = [math]::Min($targetItems.Count, $extraDisks.Count)
# loop through the arrays and output combined objects
$result = for ($i = 0; $i -lt $maxItems; $i++) {
$n1, $n2, $n3, $driveLetter, $label, $fileSystem = $extraDisks[$i] -split ','
$targetItems[$i] | Select-Object *,
#{Name = 'DriveLetter'; Expression = {$driveLetter}},
#{Name = 'Label'; Expression = {$label}},
#{Name = 'FileSystem'; Expression = {$fileSystem}}
}
# now write a new csv file for this server
$result | Export-Csv -Path ('D:\Test\DiskInfo-{0}.csv' -f $server) -NoTypeInformation
}
The resulting csv files would look like this
"VMName","Harddisk","Uuid","DriveLetter","Label","FileSystem"
"Server01","Hard disk 2","600C293-7e48-3a63-fb02-cd44df98fe79","b","sql backup","refs"
"Server01","Hard disk 3","600C293-7e48-3a63-fb02-cd44df98f454","d","sql data","refs"
"Server01","Hard disk 4","600C293-7e48-3a63-fb02-cd44df98f10a","f","sql transaction log","refs"
"Server01","Hard disk 5","600C293-7e48-3a63-fb02-cd44df98f483","l","sql audit","refs"
"Server01","Hard disk 6","600C293-7e48-3a63-fb02-cd44df98fced","t","sql tempdb data","refs"
Try like this:
$csv=Import-Csv $CsvSourcePath
$csv|%{
[pscustomobject][ordered]#{
DriveLetter=($_.AdditionalDisks.Split(","))[3]
Label=($_.AdditionalDisks.Split(","))[4]
FileSystem=($_.AdditionalDisks.Split(","))[5]
}}|export-csv $CsvTargetPath -append
I am fairly new in powershell scripting and need help on the following output in a csv format. I am trying to select a column e.g. ACCOUNT.UPLOAD and make and if/else statement to output it in another csv file. May someone help please.
Output csv should look like below:
$results = Import-Csv 'C:\Users\test\Desktop\Test\customer.csv' |
Select-Object "ACCOUNT.UPLOAD"
ForEach ($row in $results)
{
If ($row.Type0 -ne 'CP000101', 'CP000102')
{
$row."ACCOUNT.UPLOAD" = "$($row.ACCOUNT.UPLOAD)"
Write-Host $row."ACCOUNT.UPLOAD"
}
}
$results | Export-Csv C:\Users\test\Desktop\Test\test.csv -NoTypeInformation
Thank you
This will get you what you need. Added comments to explain what I have done.
$results = Import-Csv "C:\Users\test\Desktop\Test\customer.csv" | Select-Object "ACCOUNT.UPLOAD"
# Created array to be able to add individual results from foreach
$TheCSV = #()
ForEach ($row in $results) {
# You can use a -ne in the right hand side, if done like this.
If (($row.'ACCOUNT.UPLOAD' -ne 'CP000101') -and $row.'ACCOUNT.UPLOAD' -ne 'CP000102') {
# Adds the ROW column to the entry and finds the index that it was in from $results.
# Did a +2 as it does not include the header and it starts at value 0. So to match it up with the actual excel row numbers, add 2.
$row | Add-Member -Name 'ROW' -type NoteProperty -Value "$([array]::IndexOf($results.'ACCOUNT.UPLOAD',$row.'ACCOUNT.UPLOAD')+2)"
$TheCSV += $row
}
}
$TheCSV | Export-Csv "C:\Users\test\Desktop\Test\test.csv" -NoTypeInformation
Do it PowerShell way:
param(
[Parameter(Position=0)]
$InputFile = 'D:\\Temp\\Data.csv',
[Parameter(Position=1)]
$OutputFile = 'D:\\Temp\\Output.csv'
)
Import-Csv $InputFile |
Select-Object "ACCOUNT.UPLOAD" |
%{
$lineno++
if ($_.'ACCOUNT.UPLOAD' -notin #('CP000101', 'CP000102')) {
$_ | Add-Member -Name 'ROW' -type NoteProperty -Value $lineno
$_ # Output to pipeline
}
} -Begin { $lineno = 1 } |
Export-Csv $OutputFile -NoTypeInformation
Using:
.\Script.ps1
.\Script.ps1 inputfilename.csv outputfilefname.csv
What I am attempting to do is read the file size from 4 files every minute and then output the results to a CSV file. I would like each file size written to their own column. I have attempted this with the code below but I am not getting the results I need. When the file sizes are written to the CSV they are added to a single column, each size on their own row.
If I expand my array ($Process) to two records it forces all of the file lengths in the first record to the first row, each in their own column (which is what I want).
The second record does the same.
Is there any way to force a single record to one line and their values in their own columns by making an adjustment to the code? I appreciate your help. Thank you.
$Csv = 'c:\users\rob\LogFileSize.csv'
$today = get-date -f "ddd"
$day = $today.ToLower()
$date = Get-Date
$numColstoExport=5
$a = dir C:\RTscada\bin\ErrorLogs\error1_Log_$day.txt
$a | Add-Member -MemberType AliasProperty -Name FileLength -Value Length
$b = dir C:\RTscada\bin\ErrorLogs\error2_Log_$day.txt
$b| Add-Member -MemberType AliasProperty -Name FileLength -Value Length
$c = dir C:\RTscada\bin\ErrorLogs\error3_Log_$day.txt
$c | Add-Member -MemberType AliasProperty -Name FileLength -Value Length
$d = dir C:\RTscada\bin\ErrorLogs\error4_Log_$day.txt
$d | Add-Member -MemberType AliasProperty -Name FileLength -Value Length
$error1 = $a.Length
$error2 = $b.Length
$error3 = $c.Length
$error4 = $d.Length
# Array of date and file lengths
$Process = #($date, $error1, $error2, $error3, $error4)
$holdarr=#()
$pNames=#("Date", "Error1", "Error2","Error2","Error4")
foreach ($row in $Process){
$obj = new-object PSObject
for ($i=0;$i -lt $numColstoExport; $i++){
$obj | Add-Member -MemberType NoteProperty -Name $pNames[$i] -Value $row[$i]
}
$holdarr+=$obj
$obj=$null
}
$holdarr | export-csv $Csv -NoTypeInformation -Append
This should do the trick:
function MonitorLogFiles {
Param(
$LogFiles,
$Csv
)
$FirstCsvLine = 'Date'
foreach ($LogFile in $LogFiles) {
$FirstCsvLine = $FirstCsvLine + ",$(Split-Path $LogFile -leaf)"
}
$FirstCsvLine | Out-File $Csv -Encoding UTF8
while ($True) {
$CurrentCsvLine = (Get-Date -format "dd-MMM-yyyy HH:mm").ToString()
foreach ($LogFile in $LogFiles) {
$Size = (Get-Item $LogFile).Length / 1KB
$CurrentCsvLine = $CurrentCsvLine + ",$Size KB"
}
$CurrentCsvLine | Out-File $Csv -append -Encoding UTF8
Start-Sleep -Seconds 60
}
}
MonitorLogFiles -LogFiles C:\test.txt,C:\Test2.txt -Csv c:\test.csv
You can do something like this:
$holdarr|Select-Object -Property Name, Value | Export-Csv $Csv -NoTypeInformation -Append
Note: Whatever desired columns you wish to select , take all of them in the select-object.
Hope it helps.
I have thousands of CSV files in a single directory. I'm looking for a way how to add 2 columns (including headers) to each file.
There are some conditions:
There is always 0 value in column #5
In column #6 I want to store file name without extension (ABC)
INPUT FILE EXAMPLE (FILENAME IS ABC.CSV)
HEADER1,HEADER2,HEADER3,HEADER4
04/22/2012,47.64,47.97,47.05
04/23/2012,47.6,48.2,47.4
04/24/2012,48.13,48.33,47.84
04/25/2012,47.81,48.14,47.59
04/26/2012,47.83,48.21,47.49
04/27/2012,47.2,47.31,46.84
04/28/2012,47.01,47.05,46.33
The code I've posted below has 1 problem,
It adds quotation marks ("04/22/2012","47.64","47.97","47.05","0","ABC") to every value in a new file.
OUTPUT FILE EXAMPLE I NEED
HEADER1,HEADER2,HEADER3,HEADER4,HEADER5,HEADER6
04/22/2012,47.64,47.97,47.05,0,ABC
04/23/2012,47.6,48.2,47.4,0,ABC
04/24/2012,48.13,48.33,47.84,0,ABC
04/25/2012,47.81,48.14,47.59,0,ABC
04/26/2012,47.83,48.21,47.49,0,ABC
04/27/2012,47.2,47.31,46.84,0,ABC
04/28/2012,47.01,47.05,46.33,0,ABC
$files = Get-ChildItem ".\" -filter "*.csv"
for ($i=0; $i -lt $files.Count; $i++) {
$outfile = $files[$i].FullName + "out"
$csv = Import-Csv $files[$i].FullName
$newcsv = #()
foreach ( $row in $csv ) {
$row | Add-Member -MemberType NoteProperty -Name 'HEADER 5' -Value '0'
$row | Add-Member -MemberType NoteProperty -Name 'HEADER 6' -Value $files[$i].BaseName
$newcsv += $row
}
$newcsv | Export-Csv $files[$i].FullName -NoTypeInformation
}
And one more question. Because I have thousands of files in a directory, is this code efficient enough to do a task as fast as possible?
Somebody has already suggested me to improve code by Instead of looping thru the rows consider building te members with select
$csv = $csv | select-object *,#{n="HEADER5";e={0}},#{n="HEADER6";e={$file.BaseName}}
But I don't know how to implement his suggestion into my code.
Not tested:
$InputFolder = 'c:\SomeFolder'
$OutputFolder = 'c:\SomeOtherFolder'
Get-ChildItem $InputFolder -Filter *.* |
where {-not $_.psiscontainer} |
foreach {
$FileName = $_.Name
$BaseName = $_.Basename
$data = Get-Content $_ -ReadCount 0
"$($data[0]),Header5,Header6" | Set-Content $OutputFolder\$FileName
$data[1..($data.Length -1)] -replace '$',",0,$BaseName" |
Add-Content $OutputFolder\$FileName
}
I think my original answer depended too much on v3/v4 stuff, how about something like the following:
$files = Get-ChildItem ".\" | Where-Object { $_.Extension -eq ".csv" }
for ($i=0; $i -lt $files.Count; $i++) {
$outfile = $files[$i].FullName + "out"
$csv = Import-Csv $files[$i].FullName
$newcsv = #()
foreach ( $row in $csv ) {
$row | Add-Member -MemberType NoteProperty -Name 'HEADER5' -Value '0'
$row | Add-Member -MemberType NoteProperty -Name 'HEADER6' -Value $files[$i].BaseName
$newcsv += $row
}
( $newcsv | ConvertTo-Csv -NoTypeInformation ) | Foreach-Object { $_ -replace '"', '' } | Out-File $outfile
}