Gráfico do Agendador de Tarefas do Windows?

4

Alguém sabe se existe algum utilitário / ferramenta que possa fazer um gráfico de todas as tarefas no Agendador de Tarefas do Windows com base na data e hora, por isso vou saber se existe alguma sobreposição em determinado ponto do tempo causando sobrecarga no servidor? / p>

Nós temos um servidor para todas as tarefas agendadas e está lento ultimamente devido ao design pobre feito pelo ex-admin, agora eu preciso descobrir a janela de execução para cada tarefa, eu posso fazer o gráfico manualmente no Excel, mas é apenas muito para passar um por um.

Espero que alguns utilitários possam fazer isso.

    
por Root Loop 24.12.2014 / 03:22

1 resposta

2

Este script do PowerShell lerá o Log de eventos do Agendador de Tarefas e exportará para CSV Task Name , Start Date , Finish Date e Duration para todas as tarefas que foram iniciadas. Em seguida, você pode alimentar esses dados para sua planilha escolhida e criar um diagrama GANTT.

Requisitos:

  • PowerShell 2.0
  • Windows Server 2008 \ Vista

O script aceita os seguintes argumentos:

  • Computadores : matriz de nomes de computadores a serem consultados. Se não for especificado, ele consultará o computador local.
  • MaxEvents : quantidade máxima de eventos a serem lidos no log de eventos. O padrão é 100.
  • Caminho : pasta existente no disco, onde os CSVs serão salvos. Se não for especificado, a pasta de script será usada. CSVs são nomeados assim: COMPUTERNAME_TaskScheduler.csv .
  • Usuário : nome de usuário para autenticação remota.
  • Senha : senha para o usuário. Se não for especificado, será solicitado pelo script.
  • Verbose : o script informará o que está acontecendo via Write-Verbose messages.

Exemplos (executados no console do PowerShell):

Obtenha dados do computador local, processe os últimos 100 eventos e salve o CSV na pasta de script:

.\TS_Gantt.ps1

Obtenha dados de computadores remotos, processe os últimos 200 eventos, salve os CSVs na pasta c:\ts_gantt :

.\TS_Gantt.ps1 -Computers Sun, Earth, Moon -MaxEvents 200 -Path 'c:\ts_gantt'

Script ( TS_Gantt.ps1 ):

Param
(
    [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
    [ValidateNotNullOrEmpty()]
    [string[]]$Computers = $env:COMPUTERNAME,

    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [ValidateRange(1, 2147483647)]
    [int]$MaxEvents = 100,

    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [ValidateScript({
        if(!(Test-Path -LiteralPath $_ -PathType Container))
        {
            throw "Folder doesn't exist: $_"
        }
        $true
    })]
    [ValidateNotNullOrEmpty()]
    [string]$Path,

    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [ValidateNotNullOrEmpty()]
    [string]$User,

    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [string]$Password

)

# Get script path, to save CSV's, if not specified
if(!$Path)
{
    if($psISE.CurrentFile.FullPath)
    {
        $Path = $psISE.CurrentFile.FullPath | Split-Path
    }
    elseif($script:MyInvocation.MyCommand.Path)
    {
        $Path = $script:MyInvocation.MyCommand.Path | Split-Path
    }
    else
    {
        $Path = $PWD.Path
    }

    Write-Verbose "No Path specified, defaulting to: $Path"
}

# Get user credentials, if needed
if($User)
{
    Write-Verbose "User specified: $User"
    if($Password)
    {
        Write-Verbose 'Password specified, converting to credentials object'
        $SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force
        $Credentials =  New-Object System.Management.Automation.PSCredential -ArgumentList $User, $SecurePassword
    }
    else
    {
        Write-Verbose 'Password not specified, requesting from user.'
        $Credentials = Get-Credential -UserName $User -Message "Enter password for user: $User" -ErrorAction Stop
        if(!$Credentials)
        {
            Write-Verbose 'User cancelled password request'
        }
    }
}

# https://mnaoumov.wordpress.com/2014/05/15/task-scheduler-event-ids/
$TaskStartId = 100
$TaskFinishId = 102
$FilterXml = @"
<QueryList>
  <Query Id="0" Path="Microsoft-Windows-TaskScheduler/Operational">
    <Select Path="Microsoft-Windows-TaskScheduler/Operational">*[System[(EventID=$TaskStartId or EventID=$TaskFinishId)]]</Select>
  </Query>
</QueryList>
"@

# Hashtable to hold results
$Result = @{}

# Loop through computers
foreach ($PC in $Computers){

    # Grab the events from a PC
    $Params = @{
        ComputerName = $PC
        FilterXml = $FilterXml
        MaxEvents = $MaxEvents
    }

    if($Credentials)
    {
        $Params += @{Credential = $Credentials}
    }

    Write-Verbose "Trying to get Task Scheduler's event log. Computer: $PC"
    try
    {
        $Events = Get-WinEvent @Params -ErrorAction Stop
        Write-Verbose "Success"
    }
    catch
    {
        Write-Error "Can't access Task Scheduler's event log. Computer: $PC"
        continue
    }

    if(!$Events)
    {
        Write-Error "Task Scheduler's event log is empty! Computer: $PC"
        continue
    }

    Write-Verbose 'Extracting additional data from events'
    $Events |
        ForEach-Object {
            # Hashtable for new properties
            $Properties = @{}

            # Convert the event to XML and iterate through each one       
            # of the XML message properties to extract additional data  
            ([xml]$_.ToXml()).Event.EventData.Data |
                ForEach-Object {
                    $Properties.Add($_.name, $_.'#text')
                }

            # Add extracted properties to the event object
            $_ | Add-Member -NotePropertyMembers $Properties
        }

    # Set default start\finish date for event in case
    # it's still running or was started before $MaxEvents
    $DefaultStartDate = $Events[-1].TimeCreated
    $DefaultFinishDate = Get-Date
    Write-Verbose "Default task start date: $DefaultStartDate"
    Write-Verbose "Default task finish date: $DefaultFinishDate"

    Write-Verbose 'Processing events...'
    # Group events by ID and process them
    $PcEvents = $Events |
        Group-Object -Property InstanceId |
            ForEach-Object {
                # Get Name and start\finish Date
                $TaskName = $_.Group[0].TaskName
                $StartDate = ($_.Group | Where-Object {$_.OpcodeDisplayName -eq 'Start'}).TimeCreated
                $FinishDate = ($_.Group | Where-Object {$_.OpcodeDisplayName -eq 'Stop'}).TimeCreated

                # If we can't get dates, set them to defaults
                if(!$StartDate)
                {
                    $StartDate = $DefaultStartDate
                }
                elseif(!$FinishDate)
                {
                    $FinishDate = $DefaultFinishDate
                }

                # Hashtable holding object's properties
                $ItemProp = @{
                    Name = $TaskName
                    StartDate = $StartDate
                    FinishDate = $FinishDate
                    Duration = $FinishDate - $StartDate
                }

                # Output new object to the pipeline
                New-Object psobject -Property $ItemProp |
                    Select-Object Name, StartDate, FinishDate, Duration
        }

    # Add data to results
    $Result += @{$PC = $PcEvents}
}


# Loop through results
$Result.GetEnumerator() |
    ForEach-Object {
        # Export results to CSV, one file per computer
        $CsvPath = Join-Path -Path $Path -ChildPath ($_.Key + '_TaskScheduler.csv')
        Write-Verbose "Saving data to CSV: $CsvPath"
        $_.Value | Export-Csv -LiteralPath $CsvPath -Force -NoTypeInformation
    }

Update (1): Adicionei a capacidade de autenticação como usuário diferente (parâmetros Username \ Password) e mudei para filtragem usando XML, que é mais rápido e deve permitir a execução deste script contra os PCs Vista \ Server 2008 (evita este bug ). Além disso, o PowerShell 2.0 é compatível agora.

Update (2): Eu ajustei a detecção do caminho do script, então agora ele não deve quebrar o Powershell ISE. Além disso, descobri que, em alguns PCs, o log do Agendador de Tarefas está desabilitado. Aqui está o que fazer para verificar se o registro está ativado:

  1. Verifique se você tem All Tasks History ativado. Deve ler Disable All Tasks History (ugh):

  • Verifique se o log de eventos Operational do Agendador de Tarefas está ativado. Aberto:

    Visualizador de Eventos Log de Aplicativos e Serviços Microsoft Windows Agendador de Tarefas Operacional → clique com o botão direito do mouse (ou vá para o painel direito) Propriedades

  • Atualização (3): Corrigida a manipulação de logs de eventos ausentes ou não disponíveis, adicionado um monte de Verbose mensagens.

        
    por 03.03.2015 / 16:47