I am trying to read a csv file and store in a hasmap. Below is the code I am using.
$data | ForEach-Object {
$ht = #{}
$_.psobject.Properties |
#Get only the grouped properties (that have a number at the end)
Where-Object { $_.Name -match '\d+$' } |
#Group properties by param/group number
Group-Object {$_.Name -replace '\w+(\d+)$', '$1' } | ForEach-Object {
$param = $_.Group | Where-Object { $_.Name -match 'param' }
$value = $_.Group | Where-Object { $_.Name -match 'value' }
#If property has value
if($value.value -ne ""){
#Add to hashtable
$ht.add($param.Value,$value.Value)
}
}
$ht
}
Below is the output for $ht. I am getting 1 $null value for one of the field OrgId.
Name Value
---- -----
{orgId, } {1000002, $null}
type CSVFile
codepage MS1252
agentId 00000208000000000002
name infa_param_file_Pravakar
dateFormat MM/dd/yyyy HH:mm:ss
database C:\\Program Files\\Informatica Cloud Secure A
Sample CSV:
"param1","value1","param2","value2","param3","value3","param4","value4","param5","value5","param6","value6","param7","value7","param8","value8","param9","value9","param10","value10","param11","value11"
"orgId","000002","name","infa_param_file_Pravakar","agentId","00000208000000000002","dateFormat","MM/dd/yyyy HH:mm:ss","database","C:\\Program Files\\Informatica Cloud Secure Agent\\main\\rdtmDir\\userparameters","codepage","MS1252","type","CSVFile","","","","","","","",""
Related
Beginner with powershell and looking for some help with the #{Label='ID'; expression={??} section please:-
$ID = #()
Import-Csv C:\computers2.csv | ForEach-Object {$ID += $_.ID}
Get-WmiObject -Class Win32_LogicalDisk -ComputerName $ID |
Select-Object -Property DeviceID, #{Label='ID'; expression=
{$ID}},
#{Label='Total (Gb)'; expression={($_.Size/1GB).ToString('F2')}},
#{Label='Free (Gb)'; expression=
{($_.FreeSpace/1GB).ToString('F2')}},
#{label='Percent'; expression={[Math]::Round(($_.freespace /
$_.size) * 100, 2)}} | Format-Table
The output I get is this:-
output
What I'm trying to achieve would be this:-
desired output
Managed to work it out after following some guides and getting the correct variables
$CSV = Import-Csv C:\computers.csv
$SPACE = ForEach ($ID in $CSV) {
Get-WmiObject -Class Win32_LogicalDisk -ComputerName ($ID.ID) |
Select-Object -Property DeviceID,
#{Label='ID'; expression={$_.SystemName}},
#{Label='Total (Gb)'; expression={($_.Size/1GB).ToString('F2')}},
#{Label='Free (Gb)'; expression={($_.FreeSpace/1GB).ToString('F2')}},
#{Label='PercentFree'; expression={[Math]::Round(($_.freespace / $_.size) *
100, 2)}}
} | FormatTable
I am trying to export my results from a compare-object into a csv but I get an error When I export it. It looks ok when I just call it in excel. My guess is whenever there is a output of more than one value the error is placed instead of the value.
Here are my csvs
past.csv
VKEY
V-12345
V-23456
V-1111
current.csv
VKEY
V-12345
V-6789
V-23456
V-256
My new csv should say
Past, Current
V-6789,V-1111
V-256
What I am getting now is
Past, Current
System.Object[],#{vkey=V-1111}
.
$Past = Import-CSV "past.csv"
$Current = Import-CSV "Current.csv"
$pastchange = Compare-Object $Past $Current -Property vkey | Where-Object {$_.SideIndicator -eq '=>'} | Select-Object VKEY
$currentchange = Compare-Object $Past $Current -Property vkey | Where-Object {$_.SideIndicator -eq '<='} | Select-Object VKEY
$obj = New-Object PSObject
$obj | Add-Member NoteProperty Past $pastchange
$obj | Add-Member NoteProperty Current $currentchange
$obj | Export-Csv "ChangeResults.csv" -NoTypeInformation
That System.Object[] displayed in $obj.Past column is simply an array of custom objects similar to #{vkey=V-1111} in $obj.Past column. Proof:
PS D:\PShell> $obj
$obj.Past.Gettype() | Format-Table
$obj.Current.Gettype()
"---"
$obj.Past | ForEach-Object { $_.Gettype() }
Past Current
---- -------
{#{vkey=V-6789}, #{vkey=V-256}} #{vkey=V-1111}
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False PSCustomObject System.Object
---
True False PSCustomObject System.Object
True False PSCustomObject System.Object
My solution makes use of ArrayList Class (.NET Framework):
$csvOutFile = "d:\test\ChangeResults.csv" # change to fit your circumstances
$PastInFile = "d:\test\past.csv"
$CurrInFile = "d:\test\curr.csv"
$Past = Import-CSV $PastInFile
$Curr = Import-CSV $CurrInFile
# compare CSV files and convert results to arrays
$PastCh=#(, <# always return an array #>
$( Compare-Object $Past $Curr -Property vkey |
Where-Object { $_.SideIndicator -eq '=>' } ) |
ForEach-Object { $_ | Select-Object -ExpandProperty vkey }
)
$CurrCh=#(, <# even if no SideIndicator matches #>
$( Compare-Object $Past $Curr -Property vkey |
Where-Object { $_.SideIndicator -eq '<=' } ) |
ForEach-Object { $_ | Select-Object -ExpandProperty vkey }
)
[System.Collections.ArrayList]$csvout = New-Object System.Collections.ArrayList($null)
$auxHash = #{} # an auxiliary hash object
$max = ($CurrCh.Count, $PastCh.Count | Measure-Object -Maximum).Maximum
for ($i=0; $i -lt $max; $i++) {
Try { $auxHash.Past = $PastCh.GetValue($i) } Catch { $auxHash.Past = '' }
Try { $auxHash.Curr = $CurrCh.GetValue($i) } Catch { $auxHash.Curr = '' }
$csvout.Add((New-Object PSObject -Property $auxHash)) > $null
}
$csvout | Format-Table -AutoSize # show content: 'variable $csvout'
$csvout | Export-Csv $csvOutFile -NoTypeInformation
Get-Content $csvOutFile # show content: "output file $csvOutFile"
Output:
PS D:\PShell> D:\PShell\SO\37753277.ps1
Past Curr
---- ----
V-6789 V-1111
V-256
"Past","Curr"
"V-6789","V-1111"
"V-256",""
PS D:\PShell>
Here is an alternative for Try … Catch blocks:
<# another approach instead of `Try..Catch`:
if ($i -lt $PastCh.Count) { $auxHash.Past = $PastCh.GetValue($i)
} else { $auxHash.Past = '' }
if ($i -lt $CurrCh.Count) { $auxHash.Curr = $CurrCh.GetValue($i)
} else { $auxHash.Curr = '' }
#>
I having a hard time,again, trying to transpose row into columns.
The original code comes from #Mathias R. Jessen, Powershell transpose rows into columns but now I need to add some additionals columns in the csv file. I would like to have (I don't mind about the order)
EndTime,ActualStartTime,"MachineName1", "MachineName2", MachineNameX",ElapsedTime,FinalJobStatus
#1.csv
#MachineName, TotalDataSizeBytes, ActualStartTime,EndTime,ElapsedTime,FinalJobStatus
#SERVER1, 322349304901, 28/02/2016 23:00:03, 29/03/2016 23:33:23, 222,OK
#SERVER1, 322349304902, 26/02/2016 23:00:03, 27/03/2016 23:33:24, 222,OK
#SERVER2, 322349304903, 28/02/2016 23:00:01, 29/03/2016 23:33:25, 11, OK
#SERVER2, 322349304904, 26/02/2016 23:00:01, 27/03/2016 23:33:26, 122,OK
#
#2.csv (Desired output)
#EndTime","ActualStartTime","SERVER1","SERVER2",ElapsedTime,FinalJobStatus
#"29/03/2016 23:33:23","28/02/2016 23:00:03","322349304901",222,OK
#"27/03/2016 23:33:24","26/02/2016 23:00:03","322349304902",222,OK
#"29/03/2016 23:33:25","28/02/2016 23:00:01",,"322349304903",11,OK
#"27/03/2016 23:33:26","26/02/2016 23:00:01",,"322349304904",122,OK
$Rows = Import-Csv c:\_Scripts\1.csv
$MachineNames = $Rows |Select-Object -ExpandProperty MachineName |Sort -Unique
$ConsolidatedRows = $Rows |Group-Object EndTime |ForEach-Object {
$NewRowProperties = #{ EndTime = [DateTime]::Parse($_.Name) }
foreach($Row in $_.Group)
{
$NewRowProperties.Add($Row.MachineName,$Row.TotalDataSizeBytes)
}
New-Object psobject -Property $NewRowProperties
}
$ConsolidatedRows |Select-Object #("EndTime";$MachineNames) |
Sort-Object EndTime |Export-Csv c:\_Scripts\2.csv -NoTypeInformation
Edit1. I have succeeded:
$Rows = Import-Csv c:\_Scripts\1.csv
$MachineNames = $Rows |Select-Object -ExpandProperty MachineName |Sort -Unique
$ConsolidatedRows =""
$NewRowProperties =""
$ConsolidatedRows = $Rows |Group-Object EndTime |ForEach-Object {
$NewRowProperties = #{ EndTime = [DateTime]::Parse($_.Name) }
foreach($Row in $_.Group)
{
$NewRowProperties.Add("ActualStartTime",$Row.ActualStartTime)
$NewRowProperties.Add("ElapsedTime",$Row.ElapsedTime)
$NewRowProperties.Add($Row.MachineName,$Row.TotalDataSizeBytes)
$NewRowProperties.Add("FinalJobStatus",$Row.FinalJobStatus)
}
New-Object psobject -Property $NewRowProperties
}
$ConsolidatedRows |Ft
$ConsolidatedRows |Select-Object #("EndTime";$MachineNames;"ActualStartTime";"ElapsedTime";"FinalJobStatus")
|Sort-Object EndTime |Export-Csv c:\_Scripts\2.csv -NoTypeInformation
I am trying to retrieve the running applications, the computers' username and its IP address. Now, every time that the results are saved on the text file, the IP address part would always give me this result:
"Length"
"11"
Is there any way to get the IP address?
$savepath = "C:\Users\$([Environment]::UserName)\Desktop\apps\runningapps.txt"
Get-Process | where {$_.mainwindowtitle.length -ne 0} |
select name, mainwindowtitle| ConvertTo-Csv -NoType |
Set-Content $savepath
Get-WmiObject -Class Win32_ComputerSystem | select username |
ConvertTo-Csv -NoType | Add-Content $savepath
Get-WmiObject Win32_NetworkAdapterConfiguration |
Where { $_.IPAddress } |
Select -Expand IPAddress |
Where { $_ -notlike "*:*" } | ConvertTo-Csv -NoType | Add-Content $savepath
The IP addresses are a list of strings, so you can write them directly to the output file if you want them one address per line:
Get-WmiObject Win32_NetworkAdapterConfiguration |
Where { $_.IPAddress } |
Select -Expand IPAddress |
Where { $_ -notlike "*:*" } | Add-Content $savepath
If you want the addresses as a comma separated list in one line you need to join them first:
(Get-WmiObject Win32_NetworkAdapterConfiguration |
Where { $_.IPAddress } |
Select -Expand IPAddress |
Where { $_ -notlike "*:*" }) -join ',' | Add-Content $savepath
ConvertTo-Csv won't help you here, because it takes an object as input and outputs a comma-separated list of the object's properties. If your input objects are strings (which have only the property Length) then the output becomes a list of the lengths of the input strings.
As a side note: a simpler way of building the output file path is to use the USERPROFILE environment variable:
$savepath = "$env:USERPROFILE\Desktop\apps\runningapps.txt"
I am trying to replace null values in a certain column to 0 using PowerShell.
I have the CSV in this format:
test test2 test3 test4
---- ----- ----- -----
blah fsds 4 45645
bla1 fsds1 45645
blah2 fsds2 4 34322
blah3 fsds3 4 67544
blah4 fsds4 3432432
so I want to go through the null values in "test3" and replace to 0.
I have this, but it doesn't work:
$inFilePath = "G:\powershell\excel\test.csv"
$csvColumnNames = (Get-Content $inFilePath | Select-Object -First 1).Split(",")
foreach ($row in $inFilePath) {
if ($row.test3 -eq $null) {
$row.test3 = 0
Write-Host "updating value in excel"
}
}
$csvColumnNames | Export-Csv "G:\powershell\excel\replaced2.csv" -NoTypeInformation
you are on the right track with foreach and if.Try this:
foreach($row in $inFilePath)
{
if (-not $row.test3)
{
$row.test3= 0
}
}
to get the column headers:
$inFilePath | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name
Use Import-Csv for reading and Export-Csv for writing CSV files.
$inFilePath = "G:\powershell\excel\test.csv"
$outFilePath = "G:\powershell\excel\replaced2.csv"
Import-Csv $inFilePath | % {
if (-not $_.test3) { $_.test3 = 0 }
$_ # echo all records, so they can be exported back to a file
} | Export-Csv $outFilePath -NoType