Link to home
Start Free TrialLog in
Avatar of michelle0436
michelle0436

asked on

How extract two tags from an XML export of schtasks.exe

Hello -

  I need to generate a list of Windows Scheduled tasks on a server.  I need the Registration Date and the Task Name.  If I use:
schtasks /query /xml >c:\temp\tasks.xml
Each task is returned and those two tags are included.

<!-- \test_of_date -->
<Date>


The best option would be able to run that command and only ask for those two tags.  Another option would be to read the resulting file and grab just those two tags.

Any idea how I can do this?  I have investigated the Powershell module PowerScheduledTasks, but it doesn't seem to add any functionality beyond schtasks.exe

Example from the file:

<!-- \test_of_date -->
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2015-10-15T16:22:22.9464466</Date>
    <Author>WRBTS\mmorris</Author>
  </RegistrationInfo>
  <Triggers>
    <CalendarTrigger>
      <StartBoundary>2015-10-15T16:21:58.3367566</StartBoundary>
      <Enabled>true</Enabled>
      <ScheduleByDay>
        <DaysInterval>1</DaysInterval>
      </ScheduleByDay>
    </CalendarTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <RunLevel>LeastPrivilege</RunLevel>
      <UserId>WRBTS\mmorris</UserId>
      <LogonType>InteractiveToken</LogonType>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <Duration>PT10M</Duration>
      <WaitTimeout>PT1H</WaitTimeout>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>P3D</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <ShowMessage>
      <Title>hello world</Title>
      <Body>hello world</Body>
    </ShowMessage>
  </Actions>
</Task>

Open in new window

Avatar of Bill Prew
Bill Prew

Just passing by, but here's a potential start at getting this info with just powershell.  Try this small script.

Get-ScheduledTask | foreach {
  [xml] $xml = Export-ScheduledTask -TaskName $_.TaskName -TaskPath $_.TaskPath
  $xml.Task.RegistrationInfo | Select Date,URI
}

Open in new window

~bp
Not all tasks have a created date.
The schtasks command needs to be modified slightly for PowerShell to work with it.  You can parse the output directly in memory instead of writing it to a file.
$x = [xml](schtasks /query /xml one)
foreach ( $i in (0..($x.Tasks.Task.Count)) )
{
    If ( ($x.Tasks.Task)[$i].registrationinfo.date )
    {
        New-Object PsObject -Property @{
                                Taskname = "$($x.Tasks.'#comment'[$i])"
                                Date = Get-Date "$(($x.Tasks.task)[$i].RegistrationInfo.Date)"
                                }
    }
}

Open in new window

Avatar of michelle0436

ASKER

Thank you so much for your assistance!

Bill - I added Author to the Select list.  However I found that a task I built has an entry with the date and author, but the URI field is empty.  Is it possible to get just the task names and not the URI?  I tried substituting TaskName for URI, but the column is empty.

Footech - How could I change your script to report back on all tasks, not just the ones that have a date?  Also - How could I add Author to the output?

Michelle
Unfortunately it looks like the task name is actually in the first line of the extracted XML, but as a comment.  As a result no approach that loads the XML data and works with it will load the comment.

We could just treat the XML file as a TXT file I guess, and "find" the comment and look for the date, but that could be a bit less dependable.

~bp
Not all tasks have an author property either, and if you look at the XML you'll see that quite a few have the author as what looks like a DLL resource (they all end up being Microsoft Corporation).
$x = [xml](schtasks /query /xml one)
foreach ( $i in (0..($x.Tasks.Task.Count)) )
{
    If ( ($x.Tasks.Task)[$i].registrationinfo.date )
    {
        $date = Get-Date "$(($x.Tasks.task)[$i].RegistrationInfo.Date)"
    }
    Else
    {
        $date = ""
    }
    If ( "$(($x.Tasks.task)[$i].RegistrationInfo.Author)" -match '^\$\(@%' )
    {
        $author = "Microsoft Corporation"
    }
    Else
    {
        $author  = "$(($x.Tasks.task)[$i].RegistrationInfo.Author)"
    }
    New-Object PsObject -Property @{
                            Taskname = "$($x.Tasks.'#comment'[$i])"
                            Date = $date
                            Author = $author
                            }
}

Open in new window

If you need additional info about tasks I'd suggest taking a look at https://gallery.technet.microsoft.com/scriptcenter/Retrieve-Remote-Scheduled-72985b8f to see if it gives you all you want.
ASKER CERTIFIED SOLUTION
Avatar of footech
footech
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I've requested that this question be deleted for the following reason:

Not enough information to confirm an answer.
The script posted in https:#a41085464 does everything asked for.  Task Name, Creation Date, and Author are shown for every task where they are available.
I tend to agree, while we haven't heard from the OP, I feel like the solution that was suggested is useful enough I'd like to see it kept for future reference and use by others.

~bp