Question

I am trying to parse robocopy log files to get file size, path, and date modified. I am getting the information via regex with no issues. However, for some reason, I am getting an array with a single element, and that element contains 3 hashes. My terminology might be off; I am still learning about hashes. What I want is a regular array with multple elements.

Output that I am getting:

FileSize                         FilePath                         DateTime                        
--------                         --------                         --------                        
{23040, 36864, 27136, 24064...}  {\\server1\folder\Test File R... {2006/03/15 21:08:01, 2010/12...

As you can see, there is only one row, but that row contains multiple items. I want multiple rows.

Here is my code:

[regex]$Match_Regex = "^.{13}\s\d{4}/\d{2}/\d{2}\s\d{2}:\d{2}:\d{2}\s.*$"
[regex]$Replace_Regex = "^\s*([\d\.]*\s{0,1}\w{0,1})\s(\d{4}\/\d{2}\/\d{2}\s\d{2}:\d{2}:\d{2})\s(.*)$"

$MainContent = New-Object System.Collections.Generic.List[PSCustomObject]

Get-Content $Path\$InFile -ReadCount $Batch | ForEach-Object {
    $FileSize = $_ -match $Match_Regex -replace $Replace_Regex,('$1').Trim()
    $DateTime = $_ -match $Match_Regex -replace $Replace_Regex,('$2').Trim()
    $FilePath = $_ -match $Match_Regex -replace $Replace_Regex,('$3').Trim()

    $Props = @{
        FileSize = $FileSize;
        DateTime = $DateTime;
        FilePath = $FilePath
    }
    $Obj = [PSCustomObject]$Props
    $MainContent.Add($Obj)
}

$MainContent | % {
    $_
}

What am I doing wrong? I am just not getting it. Thanks.

Note: This needs to be as fast as possible because I have to process millions of lines, which is why I am trying System.Collections.Generic.List.

Was it helpful?

Solution

I think the problem is that for what you're doing you actually need two foreach-object loops. Using Get-Content with -Readcount is going to give you an array of arrays. Use the -Match in the first Foreach-Object to filter out the records that match in each array. That's going to give you an array of the matched records. Then you need to foreach through that array to create one object for each record:

[regex]$Match_Regex = "^.{13}\s\d{4}/\d{2}/\d{2}\s\d{2}:\d{2}:\d{2}\s.*$"
[regex]$Replace_Regex = "^\s*([\d\.]*\s{0,1}\w{0,1})\s(\d{4}\/\d{2}\/\d{2}\s\d{2}:\d{2}:\d{2})\s(.*)$"

$MainContent = 
  Get-Content $Path\$InFile -ReadCount $Batch |
   ForEach-Object {
    $_ -match $Match_Regex |
     ForEach-Object {
      $FileSize = $_ -replace $Replace_Regex,('$1').Trim()
      $DateTime = $_ -replace $Replace_Regex,('$2').Trim()
      $FilePath = $_ -replace $Replace_Regex,('$3').Trim()

      [PSCustomObject]@{
         FileSize = $FileSize
         DateTime = $DateTime
         FilePath = $FilePath
        }
    }    
 }

You don't really need to use the collection as an accumulator, just output PSCustomObjects, and let them accumulate in the result variable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top