0

I am trying to parse XMLs recursively into a CSV. The code works but I see an error which I researched and found that it could be because of an ill-formed XML file but I do not think Windows Tasks would be like that, they are consistent!

function Flatten-Xml ([System.Xml.XmlNode]$Xml, [Parameter(DontShow)]$ParentName) {
    if (!$ParentName) { $Properties = [Ordered]@{} }
    $Xml |Get-Member -MemberType 'Property' |ForEach-Object {
        $Name = if ($ParentName) { "$ParentName.$($_.Name)" } else { $_.Name }
        $Value = $Xml.$($_.Name)
        if ($Value -is [System.Xml.XmlElement]) { Flatten-Xml $Value $Name }
        elseif ($Value -is [String]) { $Properties[$Name] = $Value }
    }
    if (!$ParentName) { [PSCustomObject]$Properties }
}

function UnifyProperties {
  $Names = [System.Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase)
  $InputCollected = @($Input)
  $InputCollected.ForEach({ 
    foreach ($Name in $_.psobject.Properties.Name) { $Null = $Names.Add($Name) }
  })
  $inputCollected | Select-Object @($Names)
}

$ListOfTasks = (Get-ChildItem -File -Path .\ -Recurse).fullname
$Final = @()
$ListOfTasks | 

foreach {

    $xml = [xml](get-content $_)
    $Final += Flatten-Xml $Xml
}

$Final | UnifyProperties | Export-Csv -Path .\01Test.csv -NoTypeInformation

2nd Script which does the same thing,

[CmdletBinding()]
param (
  [Parameter(Mandatory = $true)] $PathToXML
)

$ListOfTasks = (Get-ChildItem -File -Path $PathToXML -Recurse).fullname
$ListOfTasks | foreach {
    $ModifiedTime = (gci -Path $_).LastWriteTimeUtc.toString('yyyy-MM-ddTHH:mm:ss')+':00z'
    $xmlFile = [xml](get-content "$_")
    $Date = $xmlFile.ChildNodes.RegistrationInfo.Date
    $Author = $xmlFile.ChildNodes.RegistrationInfo.Author
    $Description = $xmlFile.ChildNodes.RegistrationInfo.Description
    $URI = $xmlFile.ChildNodes.RegistrationInfo.URI
    $Principals = $xmlFile.ChildNodes.Principals.Principal.UserId
    $LogonType = $xmlFile.ChildNodes.Principals.Principal.LogonType
    $Enabled = $xmlFile.ChildNodes.Settings.Enabled
    $Action = $xmlFile.ChildNodes.Actions.Exec.Command
    $Arguments = $xmlFile.ChildNodes.Actions.Exec.Arguments

    $xmlFile.ChildNodes[1] | 
    ForEach-Object {
                [PSCustomObject]@{
                    TaskFile_LastModifiedTime = $ModifiedTime
                    Registration_Date = $Date
                    Author = $Author
                    Description = $Description
                    Task_Name = $URI
                    Principals_UserContext = $Principals
                    LogonType = $LogonType
                    Enabled = $Enabled
                    Action_Arguments = $Action + " " + $Arguments
                    #Arguments = $Arguments
                }
            } 
} | Export-Csv -Path .\Parsed_Tasks_XML.csv -NoTypeInformation

Cannot convert value "System.Object[]" to type "System.Xml.XmlDocument". Error: "'', hexadecimal value 0x08, is an invalid character. Line 1, position 1."
At C:\Users\Vikas\Desktop\0Sophos-P520\Research\Parse_TaskXMLs_Verbose.ps1:27 char:5
+     $xml = [xml](get-content $_)
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvalidCastToXmlDocument

The collection of XMLs: Don't worry it's safe!

https://file.io/NjxQlKHOshdd

I'm unable to pinpoint into the specific file which might be causing problems! I want this to be error free in order to proceed. Any guidance will be helpful.

Origami
  • 87
  • 7
  • 1
    FYI, I have done an update on the[`Flatten-Xml` script](https://stackoverflow.com/a/74431608/1701026) as it didn't incorporate the fact that there can be multiple children with the same name in one parent node. Anyways, I think that you will need to further nail down with xml file caused the issue yourself (e.g. with a `Write-Host`: `$ListOfTasks | foreach { Write-Host 'File:' $_ ...`) and create a [mcve] with a specific (narrowed) `xml` string. – iRon Nov 15 '22 at 08:59
  • As an aside: [try avoid using the increase assignment operator (+=) to create a collection](https://stackoverflow.com/a/60708579/1701026) as it might get very expensive. – iRon Nov 15 '22 at 09:01
  • Figure it out - thank you. https://ibb.co/QjFbJHy And thank you for the other advice as well, I'll play around with it. – Origami Nov 15 '22 at 09:40

0 Answers0