Powershell-Skript zum Auflisten geplanter Aufgaben auf Remote-Systemen

Ich möchte ein PowerShell-Skript schreiben, das alle geplanten Aufgaben auf Remote-Systemen auflistet und das Benutzerkonto enthält, mit dem jede Aufgabe ausgeführt wird.

Auf dem lokalen System wird Windows 7 mit PowerShell 3.0 ausgeführt. Die Remote-Systeme reichen von Server 2003 bis 2008 R2 mit PowerShell-Versionen von 2.0 bis 3.0.

Welche PowerShell-Befehle oder-Funktionen kann ich für diese Aufgabe verwenden?

Author: Iszi, 2014-09-15

4 answers

Ich habe endlich ein Skript geschrieben, das meinen Bedürfnissen entspricht. Dieses Skript "scannt" alle in AD aufgelisteten Server und sucht in der c:\Windows\System32\tasks ordner für XML-Dateien. Dann wird der Wert des XML-Knotens userId jeder Datei in die endgültige CSV-Datei geschrieben.

Noch nicht perfekt, aber es funktioniert vollständig, um alle Aufgaben aller Server aufzulisten und zu protokollieren, welches Benutzerkonto zum Ausführen verwendet wird.

<#
.Synopsis
   PowerShell script to list all Scheduled Tasks and the User ID
.DESCRIPTION
   This script scan the content of the c:\Windows\System32\tasks and search the UserID XML value. 
   The output of the script is a comma-separated log file containing the Computername, Task name, UserID.
#>

Import-Module ActiveDirectory
$VerbosePreference = "continue"
$list = (Get-ADComputer -LDAPFilter "(&(objectcategory=computer)(OperatingSystem=*server*))").Name
Write-Verbose  -Message "Trying to query $($list.count) servers found in AD"
$logfilepath = "$home\Desktop\TasksLog.csv"
$ErrorActionPreference = "SilentlyContinue"

foreach ($computername in $list)
{
    $path = "\\" + $computername + "\c$\Windows\System32\Tasks"
    $tasks = Get-ChildItem -Path $path -File

    if ($tasks)
    {
        Write-Verbose -Message "I found $($tasks.count) tasks for $computername"
    }

    foreach ($item in $tasks)
    {
        $AbsolutePath = $path + "\" + $item.Name
        $task = [xml] (Get-Content $AbsolutePath)
        [STRING]$check = $task.Task.Principals.Principal.UserId

        if ($task.Task.Principals.Principal.UserId)
        {
          Write-Verbose -Message "Writing the log file with values for $computername"           
          Add-content -path $logfilepath -Value "$computername,$item,$check"
        }

    }
}

Die Ausgabe ist eine durch Kommas getrennte Datei, die wie folgt auf Ihrem Desktop generiert wird :

> SRV028,CCleanerSkipUAC,administrator
> SRV029,GoogleUpdateTaskMachineCore,System
> SRV030,GoogleUpdateTaskMachineUA,System
> SRV021,BackupMailboxes,DOMAIN\administrator
> SRV021,Compress&Archive,DOMAIN\sysScheduler
 9
Author: Ob1lan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2014-09-18 06:25:50

Hey dachte, ich würde eine modifizierte Version des Skripts von Ob1lan teilen. Die Änderung hilft beim Auffinden von Aufgaben in verschachtelten Ordnern und listet den Status der Aufgabe sowie die im Original enthaltenen Details auf.

$Computers = (get-adcomputer -filter {operatingsystem -like "*server*"}).name
$ErrorActionPreference = "SilentlyContinue"
$Report = @()
foreach ($Computer in $Computers)
{
    if (test-connection $Computer -quiet -count 1)
    {
        #Computer is online
        $path = "\\" + $Computer + "\c$\Windows\System32\Tasks"
        $tasks = Get-ChildItem -recurse -Path $path -File
        foreach ($task in $tasks)
        {
            $Details = "" | select ComputerName, Task, User, Enabled, Application
            $AbsolutePath = $task.directory.fullname + "\" + $task.Name
            $TaskInfo = [xml](Get-Content $AbsolutePath)
            $Details.ComputerName = $Computer
            $Details.Task = $task.name
            $Details.User = $TaskInfo.task.principals.principal.userid
            $Details.Enabled = $TaskInfo.task.settings.enabled
            $Details.Application = $TaskInfo.task.actions.exec.command
            $Details
            $Report += $Details
        }
    }
    else
    {
        #Computer is offline
    }
}
$Report | ft

HINWEIS: Wenn Sie viele Server haben, dauert die Ausführung sehr lange. Wenn Sie es parallel ausführen möchten, können Sie das Skript invoke-parallel (Google it) verwenden, das deutlich schneller ist:

. \\server\path\to\invoke-parallel.ps1
$Computers = (get-adcomputer -filter {operatingsystem -like "*server*"}).name
$ErrorActionPreference = "SilentlyContinue"
$Scriptblock =
{
    $path = "\\" + $_ + "\c$\Windows\System32\Tasks"
    $tasks = Get-ChildItem -recurse -Path $path -File
    foreach ($task in $tasks)
    {
        $Details = "" | select ComputerName, Task, User, Enabled, Application
        $AbsolutePath = $task.directory.fullname + "\" + $task.Name
        $TaskInfo = [xml](Get-Content $AbsolutePath)
        $Details.ComputerName = $_
        $Details.Task = $task.name
        $Details.User = $TaskInfo.task.principals.principal.userid
        $Details.Enabled = $TaskInfo.task.settings.enabled
        $Details.Application = $TaskInfo.task.actions.exec.command
        $Details
    }
}
$Report = invoke-parallel -input $Computers -scriptblock $Scriptblock -throttle 400 -runspacetimeout 30 -nocloseontimeout
$Report | ft 

Beispiel ausgabe:

Abbildung

 6
Author: laoist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2017-12-17 14:50:53

Ich habe diesen Befehl verwendet, um alle Aufgaben aufzulisten:

        Invoke-Command -ComputerName "computername" -Credential Get-Credential {schtasks.exe}
 2
Author: sanyam jain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2014-09-15 16:49:23

Achtung: Warnung: besser verwenden -literalpath, wie:

$TaskInfo = [xml](Get-Content -literalpath $AbsolutePath)

Oder get-content gibt nichts zurück, wenn Ihre Tasknamen oder Ordnernamen Platzhalter oder reguläre Zeichen enthalten, wie in meinem Fall "[' und "]"...

Ja, Powershell scheint nicht nur Literalstrings zu interpretieren, sondern auch den Inhalt von String - Typvariablen.

 1
Author: Patrick E,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/techietown.info/template/agent.layouts/content.php on line 61
2018-10-19 18:42:10