2

I hope you can help me out. I work with two ArrayLists:

array1 is filled with log.csv (contains header and logon-data, values of column 'pc' are unique). It's defined as ArrayList because I want to add entries.

#pc,name,date,city
#pc-x,name-1,2017-01-01,berlin
#pc-y,name-1,2017-01-02,berlin
#pc-z,name-2,2017-01-02,munich
[System.Collections.ArrayList]$array1 = Import-Csv log.csv

array2 is filled during runtime

$array2=[System.Collections.ArrayList]@()
... ForEach-Object {
$array2.Add([PSCustomObject]@{ pc=$pcname
                               name=$loginname
                               date=$logindate }) >$null }

What I want to do: Update array1.date=array2.date where array1.pc=array2.pc

If no entry found in array1 I want to add it:

 $array1.Add([PSCustomObject]@{ pc=$pcname
                                name=$loginname
                                date=$logindate 
                                city='[unknown]' }) >$null

Finally array1 is exported again:

$array1 | Export-Csv log.csv -Encoding UTF8 -NoTypeInformation

So the question is: how can I find the entry in array1 and update it? Trying hard for days now ...

3
  • There is a nice article on how to use Join-Object Commented Oct 27, 2017 at 9:23
  • You should flatten your array first , then you can check for the elements using iteration Commented Oct 27, 2017 at 10:48
  • i ask my self, why Join-object are not a native command to PowerShell.... Commented Oct 28, 2017 at 10:21

2 Answers 2

2

try Something like this:

$array1=import-csv "C:\temp\log.csv"
$array2=import-csv "C:\temp\log2.csv"

#modify founded and output not founded
$toadd=$array2 | %{
$current=$_
$founded=$array1 | where pc -eq $current.pc | %{$_.date=$current.date;$_}

    if ($founded -eq $null)
    {
      $current.city='UNKNOW' 
      $current 
    }
}

#output of $array1 modified and elements to add
$array1, $toadd
Sign up to request clarification or add additional context in comments.

2 Comments

Can you explain "$_" after ";" in "%{$_.date=$current.date;$_}" please?
its for put current item to output
0

Here is a sample I created that might help. Note: I use List types instead of ArrayList ones. Also, it assumes only one possible matching PC name in the data to be updated. You'll have to alter it to update the file since it merely updates the first List variable. Let me know how it goes.

[PSCustomObject]
{
[string] $pc,
[string] $name,
[string] $date,
[string] $city
}

[System.Collections.Generic.List[PSCustomObject]] $list1 = Import-Csv "C:\SOSamples\log.csv";
[System.Collections.Generic.List[PSCustomObject]] $list2 = Import-Csv "C:\SOSamples\log2.csv";
[PSCustomObject] $record = $null;
[PSCustomObject] $match = $null;

foreach($record in $list2)
{
    # NOTE: This only retrieves the FIRST MATCHING item using a CASE-INSENSITIVE comparison       
    $match = $list1 | Where { $_.pc.ToLower() -eq $record.pc.ToLower() } | Select -First 1;

    if($match -eq $null)
    {
        Write-Host "Not Found!";
        $list1.Add($record);
    }
    else 
    {
        Write-Host "Found!";
        $match.date = $record.date;
    }
}

Write-Host "--------------------------------------------------------------------"

foreach($record in $list1)
{
    Write-Host $record
}

2 Comments

Will "$match.date = $record.date" also update "$list1"?
It should, but verify as I did this almost a week ago. ;-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.