Home > Mobile >  Parse XML PowerShell Recursively
Parse XML PowerShell Recursively

Time:11-15

Thank you for all the help I've ever gotten here.

Scenario: Parsing XMLs Recursively into a neat CSV

Structure:

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Author>Microsoft Corporation</Author>
    <URI>\OneDrive Reporting Task-S-1-5-21-XXXXXXXXXX-XXXXXXX-683614252-544081760</URI>
  </RegistrationInfo>
  <Triggers>
    <TimeTrigger>
      <StartBoundary>2022-09-07T12:45:02</StartBoundary>
      <Enabled>true</Enabled>
      <Repetition>
        <Interval>P1D</Interval>
        <StopAtDurationEnd>false</StopAtDurationEnd>
      </Repetition>
    </TimeTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>S-1-5-21-XXXXXXXX-XXXXXXX-683614252-544081760</UserId>
      <RunLevel>LeastPrivilege</RunLevel>
      <LogonType>InteractiveToken</LogonType>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>true</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>true</RunOnlyIfNetworkAvailable>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT2H</ExecutionTimeLimit>
    <Priority>7</Priority>
    <RestartOnFailure>
      <Interval>PT30M</Interval>
      <Count>2</Count>
    </RestartOnFailure>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>%localappdata%\Microsoft\OneDrive\OneDriveStandaloneUpdater.exe</Command>
      <Arguments>/reporting</Arguments>
    </Exec>
  </Actions>
</Task>

I have managed to parse one XML into a CSV:

$xmlFile = [xml](get-content "OneDrive Reporting Task-S-1-5-21-xxxxxxxx-xxxxxxxx-683614252-544134134")
$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.Triggers.CalendarTrigger.Enabled
$Action = $xmlFile.ChildNodes.Actions.Exec.Command
$Arguments = $xmlFile.ChildNodes.Actions.Exec.Arguments

$xmlFile.ChildNodes[1] | 
ForEach-Object{
         [PSCustomObject]@{
             Registration_Date = $Date
             Author = $Author
             Description = $Description
             URI = $URI
             Principals_UserContext = $Principals
             LogonType = $LogonType
             Enabled = $Enabled
             Action = $Action
             Arguments = $Arguments
         }
     } | Export-Csv .\01Parsed_Tasks_XML.csv -NoTypeInformation

The idea is to look for XMLs recursively in a Folder, and do all the above and keep appending the data. I'll keep trying but in the meanwhile, would appreciate some help too.

CodePudding user response:

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 }
}
Flatten-Xml $Xml

Task.Actions.Context                                   : Author
Task.Actions.Exec.Arguments                            : /reporting
Task.Actions.Exec.Command                              : %localappdata%\Microsoft\OneDrive\OneDriveStandaloneUpdater.exe
Task.Principals.Principal.id                           : Author
Task.Principals.Principal.LogonType                    : InteractiveToken
Task.Principals.Principal.RunLevel                     : LeastPrivilege
Task.Principals.Principal.UserId                       : S-1-5-21-XXXXXXXX-XXXXXXX-683614252-544081760
Task.RegistrationInfo.Author                           : Microsoft Corporation
Task.RegistrationInfo.URI                              : \OneDrive Reporting Task-S-1-5-21-XXXXXXXXXX-XXXXXXX-683614252-544081760
Task.Settings.AllowHardTerminate                       : true
Task.Settings.AllowStartOnDemand                       : true
Task.Settings.DisallowStartIfOnBatteries               : false
Task.Settings.Enabled                                  : true
Task.Settings.ExecutionTimeLimit                       : PT2H
Task.Settings.Hidden                                   : false
Task.Settings.MultipleInstancesPolicy                  : IgnoreNew
Task.Settings.Priority                                 : 7
Task.Settings.RestartOnFailure.Count                   : 2
Task.Settings.RestartOnFailure.Interval                : PT30M
Task.Settings.RunOnlyIfIdle                            : false
Task.Settings.RunOnlyIfNetworkAvailable                : true
Task.Settings.StartWhenAvailable                       : true
Task.Settings.StopIfGoingOnBatteries                   : true
Task.Settings.WakeToRun                                : false
Task.Triggers.TimeTrigger.Enabled                      : true
Task.Triggers.TimeTrigger.Repetition.Interval          : P1D
Task.Triggers.TimeTrigger.Repetition.StopAtDurationEnd : false
Task.Triggers.TimeTrigger.StartBoundary                : 2022-09-07T12:45:02
Task.version                                           : 1.2
Task.xmlns                                             : http://schemas.microsoft.com/windows/2004/02/mit/task
xml                                                    : version="1.0" encoding="UTF-16"
  • Related