Home > Enterprise >  PowerShell | TXT Contents to Object
PowerShell | TXT Contents to Object

Time:11-17

Thank you for all the help I've gotten till now. I'm trying to challenge what I am learning with weird ideas. I'm trying to read through a TXT files and trying to convert them into Custom Objects in memory to manipulate later.

Contents of TXT file - there could be more "blocks"

  Object GUID:  86dabdb1-cdc7-421c-a58e-7c2cb55b1dba
  Name:         ScannerSchduler
  Location:     \\?\C:\Windows\System32\Tasks\Microsoft\Windows Defender\
  Type:         file
  Status:       stored
  Store time:   Wed Nov 10 11:47:55 2021 (1636525075)
  Threat GUID:  b9d9575c-4723-4df3-b9ee-5d97a1d5b8bf
  Threat name:  Troj/MineJob-A

  Object GUID:  3eeeb91c-731e-4e03-a55e-4b200df17805
  Name:         WindowsParentalControlsSettings
  Location:     \\?\C:\Windows\System32\Tasks\Microsoft\Windows\Shell\
  Type:         file
  Status:       stored
  Store time:   Wed Nov 10 11:47:58 2021 (1636525078)
  Threat GUID:  b9d9575c-4723-4df3-b9ee-5d97a1d5b8bf
  Threat name:  Troj/MineJob-A

2 white spaces in the beginning but we can Trim() right.

My target custom object which is an array of objects,

$Objects = @() 

ForEach ($a in $Array)
{
    $object = New-Object -TypeName PSObject
    $object | Add-Member -MemberType NoteProperty -Name "Object_GUID" -Value $var[1]
    $object | Add-Member -MemberType NoteProperty -Name "Name" -Value ??
    $object | Add-Member -MemberType NoteProperty -Name "Location" -Value ??
    $object | Add-Member -MemberType NoteProperty -Name "Type" -Value ??
    $object | Add-Member -MemberType NoteProperty -Name "Status" -Value ??
    $object | Add-Member -MemberType NoteProperty -Name "Store_time" -Value ??
    $object | Add-Member -MemberType NoteProperty -Name "Threat_GUID" -Value ??
    $object | Add-Member -MemberType NoteProperty -Name "Threat_Name" -Value ??
    $schtasks  = $object
}

I feel embarrassed to ask for help but this is not "homework". I don't know how to inculcate the scripting mind and think of ways. I've read a book, taken few courses but the best way is to seek challenges and I keep failing at tiny ones like these.

The contents of $Array will be lines containing information. How can I Foreach that split each line into two Name:Type combination.

Where-Object {$_.length -gt 0} | Foreach-Object {
    $var = $_.split(':',2).trim()
    New-Variable -Name $var[0] -Value $var[1]
    Write-Host ($var[0]   " = "   $var[1])

The above can give me Name:Value pair for each line it finds. But I'm unable to nest it inside something that can create an object for me. I'll keep trying on my own.

CodePudding user response:

Assuming the property list is always in order, you can use the Object GUID: line as an anchor for new objects:

$data = @'
  Object GUID:  86dabdb1-cdc7-421c-a58e-7c2cb55b1dba
  Name:         ScannerSchduler
  Location:     \\?\C:\Windows\System32\Tasks\Microsoft\Windows Defender\
  Type:         file
  Status:       stored
  Store time:   Wed Nov 10 11:47:55 2021 (1636525075)
  Threat GUID:  b9d9575c-4723-4df3-b9ee-5d97a1d5b8bf
  Threat name:  Troj/MineJob-A

  Object GUID:  3eeeb91c-731e-4e03-a55e-4b200df17805
  Name:         WindowsParentalControlsSettings
  Location:     \\?\C:\Windows\System32\Tasks\Microsoft\Windows\Shell\
  Type:         file
  Status:       stored
  Store time:   Wed Nov 10 11:47:58 2021 (1636525078)
  Threat GUID:  b9d9575c-4723-4df3-b9ee-5d97a1d5b8bf
  Threat name:  Troj/MineJob-A
'@ -split '\r?\n' 

$objects = $data |ForEach-Object -Process {
  # always trim leading and trailing whitespace from line
  $_ = $_.Trim()

  if($_ -like 'Object GUID:*'){
    # first line in new block, output current object if any
    if($properties.Count){
      [pscustomobject]$properties
    }
    # ... then start processing new object
    $properties = [ordered]@{}
  }

  if($_ -like '*:*'){
    # extract name/value pair, trim again
    $name,$value = $_.Split(':') |ForEach-Object Trim
    # add value to property table
    $properties[$name] = $value
  }
} -End {
  # do we still have data collected for the last block in the sequence? output the last object too then
  if($properties.Count){
    [pscustomobject]$properties
    $properties = $null
  }
}
  • Related