how to use PowerShell to inventory Scheduled Tasks

2019-02-06 23:13发布

问题:

Does anyone have a link or script that uses PowerShell to inventory the Scheduled Tasks on a server, including the Action?

I am able to get the Scheduled Service com object and what I would call "top level" properties (name, state, lastruntime), but would like to also get information from the "Actions" part of the Schedule Tasks (essentially, the name of Scheduled Task and its commandline).

For example:

$schedule = new-object -com("Schedule.Service") 
$schedule.connect() 
$tasks = $schedule.getfolder("\").gettasks(0)

$tasks | select Name, LastRunTime

foreach ($t in $tasks)
{
foreach ($a in $t.Actions)
{
    $a.Path
}
}

The above snippet of code works in terms of listing the tasks; but the loop on the Actions simply does not seem to do anything, no error, no output whatsoever.

Any help would be appreciated.

回答1:

This is probably very similar to current answers, but I wrote a quick script to get you going. The problem with your current script is that there is no Actions property in a task. You need to extract it from the xml task-definition that the comobject provides. The following script will return an array of objects, one per scheduled task. It includes the action if the action is to run one or more command. It's just to get you going, so you need to modify it to include more of the properties if you need them.

function getTasks($path) {
    $out = @()

    # Get root tasks
    $schedule.GetFolder($path).GetTasks(0) | % {
        $xml = [xml]$_.xml
        $out += New-Object psobject -Property @{
            "Name" = $_.Name
            "Path" = $_.Path
            "LastRunTime" = $_.LastRunTime
            "NextRunTime" = $_.NextRunTime
            "Actions" = ($xml.Task.Actions.Exec | % { "$($_.Command) $($_.Arguments)" }) -join "`n"
        }
    }

    # Get tasks from subfolders
    $schedule.GetFolder($path).GetFolders(0) | % {
        $out += getTasks($_.Path)
    }

    #Output
    $out
}

$tasks = @()

$schedule = New-Object -ComObject "Schedule.Service"
$schedule.Connect() 

# Start inventory
$tasks += getTasks("\")

# Close com
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($schedule) | Out-Null
Remove-Variable schedule

# Output all tasks
$tasks

Ex. of output

PS > .\Untitled1.ps1 | ? { $_.Name -eq "test" }


Actions     : notepad.exe c:\test.txt
              calc.exe 
Path        : \test
Name        : test
LastRunTime : 30.12.1899 00:00:00
NextRunTime : 17.03.2013 13:36:38


回答2:

Get the PowerShellPack from the W7 RK, and try get-scheduledtask

http://archive.msdn.microsoft.com/PowerShellPack

Excerpt From MSDN:

The Windows 7 Resource Kit PowerShell Pack contains 10 modules to do all sorts of interesting things with PowerShell. Import-Module PowerShellPack actually imports 10 modules for you to use. Here’s a brief overview of each of the modules.

  • WPK Create rich user interfaces quick and easily from Windows PowerShell. Think HTA, but easy. Over 600 scripts to help you build quick user interfaces
  • TaskScheduler List scheduled tasks, create or delete tasks
  • FileSystem Monitor files and folders, check for duplicate files, and check disk space
  • IsePack Supercharge your scripting in the Integrated Scripting Environment with over 35 shortcuts
  • DotNet Explore loaded types, find commands that can work with a type, and explore how you can use PowerShell, DotNet and COM together
  • PSImageTools Convert, rotate, scale, and crop images and get image metadata
  • PSRSS Harness the FeedStore from PowerShell
  • PSSystemTools Get Operating System or Hardware Information
  • PSUserTools Get the users on a system, check for elevation, and start-processaadministrator
  • PSCodeGen Generates PowerShell scripts, C# code, and P/Invoke


回答3:

Another way would be a script I wrote called Get-ScheduledTask.ps1, available in this article:

How-To: Use PowerShell to Report on Scheduled Tasks

In this way you only need this single script and you don't need to download or install anything else.

Bill



回答4:

I know I'm late to the party, but the answer provided by @Frode F., while it works, is technically not correct.

You can access items of the Actions collection of a scheduled task via PowerShell, it's just not immediately obvious. I had to figure this out myself today as well.

Here's the code to do this all in PowerShell, without having to muck around with XML:

# I'm assuming that you have a scheduled task object in the variable $task:
$taskAction = $task.Definition.Actions.Item.Invoke(1) # Collections are 1-based

That's all there is to getting a single item out of the collection without using foreach.

Because the Actions property is a collection which contains a parameterized property Item (e.g. in C# you would write myTask.Actions[0] or in VB myTask.Actions.Item(1)), PowerShell represents the Item property as a PSParameterizedProperty object. To call the methods associated with the property, you use the Invoke method (for the getter) and InvokeSet method (for the setter).

I ran a quick test running the OP's code and it worked for me (I'm running PowerShell 4.0, however, so maybe that has something to do with it):

$schedule = new-object -com("Schedule.Service") 
$schedule.connect() 
$tasks = $schedule.getfolder("\").gettasks(0)

$tasks | select Name, LastRunTime

foreach ($t in $tasks)
{
    foreach ($a in $t.Actions)
    {
        Write-Host "Task Action Path: $($a.Path)" # This worked
        Write-Host "Task Action Working Dir: $($a.workingDirectory)" # This also worked
    }

    $firstAction = $t.Actions.Item.Invoke(1)
    Write-Host "1st Action Path: $($firstAction.Path)"
    Write-Host "1st Action Working Dir: $($firstAction.WorkingDirectory)"
}

HTH.



回答5:

here a quick one based on: https://blogs.technet.microsoft.com/heyscriptingguy/2015/01/17/weekend-scripter-use-powershell-to-document-scheduled-tasks/

Uses Powershell: Get-ScheduledTask and Get-ScheduledTaskInfo

### run like >>  Invoke-Command -ComputerName localhost, server1, server2 -FilePath C:\tmp\Get_WinTasks.ps1

$taskPath = "\"
$outcsv = "c:\$env:COMPUTERNAME-WinSchTaskDef.csv"
Get-ScheduledTask -TaskPath $taskPath |
    ForEach-Object { [pscustomobject]@{
     Server = $env:COMPUTERNAME
     Name = $_.TaskName
     Path = $_.TaskPath
     Description = $_.Description
     Author = $_.Author
     RunAsUser = $_.Principal.userid
    LastRunTime = $(($_ | Get-ScheduledTaskInfo).LastRunTime)
     LastResult = $(($_ | Get-ScheduledTaskInfo).LastTaskResult)
     NextRun = $(($_ | Get-ScheduledTaskInfo).NextRunTime)
     Status = $_.State
     Command = $_.Actions.execute
     Arguments = $_.Actions.Arguments }} |
     Export-Csv -Path $outcsv -NoTypeInformation