Windowsタスクスケジューラチャート


4

時間と日付に基づいてWindowsタスクスケジューラのすべてのタスクの図表を作成できるユーティリティ/ツールがあるかどうかを知っている人はいますか。

私たちはすべてのスケジュールされたタスクのためのサーバーを持っていて、それは元管理者によって作られた貧弱なデザインのため最近遅くなっています。一つずつ通過することがたくさんあります。

うまくいけば、いくつかのユーティリティがこれを行うことができます。


何かアイデアがありますか?そのような効用ハムのようには見えません....
Root Loop

このような(GANTT)グラフを作成するには、おそらくすべてのタスクの開始時間だけでなく終了時間または期間も必要になります。この情報はWindowsでは事前には利用できません。したがって、経験からの期間を知っていれば、次のような外部のチャート作成ツール用にデータを集める必要があります。 sourceforge.net/projects/ganttproject
Axel Kemper

おかげで、これに似たものを試してみました、それは私が探しているものではありません正確にはありません。私は自分自身でそれをうまくやると思います。
Root Loop

回答:


2

このPowershellスクリプトはタスクスケジューラのイベントログを読み取り、CSVにエクスポートします。 Task NameStart DateFinish Date そして Duration 起動されたすべてのタスクに対して。次に、このデータを選択したスプレッドシートに送り、GANTT図を作成します。

必要条件

  • PowerShell 2.0
  • Windows Server 2008 \ Vista

スクリプトは以下の引数を受け入れます。

  • コンピュータ 問い合わせるコンピュータ名の配列。指定されていない場合は、ローカルコンピュータに問い合わせます。
  • MaxEvents イベントログから読み取るイベントの最大数。デフォルトは100です。
  • パス CSVが保存されるディスク上の既存のフォルダ。指定しない場合は、スクリプトフォルダが使用されます。 CSVの名前は次のようになります。 COMPUTERNAME_TaskScheduler.csv
  • ユーザー リモート認証用のユーザー名。
  • パスワード ユーザーのパスワード指定しない場合は、スクリプトによって要求されます。
  • 冗長 スクリプトは、経由で何が起こっているのか教えてくれます Write-Verbose メッセージ

例(PowerShellコンソールから実行):

ローカルコンピュータからデータを取得し、最後の100イベントを処理し、CSVをスクリプトフォルダに保存します。

.\TS_Gantt.ps1

リモートコンピュータからデータを取得し、最後の200イベントを処理し、CSVファイルを c:\ts_gantt フォルダ:

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

スクリプト( 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
    }

更新(1): 私は別のユーザーとして認証する機能(Username \ Passwordパラメーター)を追加し、XMLを使用したフィルタリングに切り替えました。 もっと早く そしてVista \ Server 2008 PCに対してこのスクリプトを実行することを許可するべきです(避けてください このバグ )また、PowerShell 2.0と互換性があります。

更新(2): スクリプトのパス検出を微調整したので、今ではPowershell ISEでは機能しません。また、一部のPCでは、タスクスケジューラのログが無効になっていることがわかりました。ロギングが有効になっていることを確認するには、次の手順を実行します。

  1. 持っていれば、チェック All Tasks History 有効にします。読むべき Disable All Tasks History (うーん):

All Tasks History

  1. タスクスケジューラの Operational イベントログが有効になります。 開いた:

    イベントビューアー アプリケーションとサービスのログ マイクロソフト Windows タスクスケジューラ 運用上の →それを右クリック(または右ペインに移動) プロパティ

Task Scheduler Operational Event Log

Task Scheduler Operational Event Log Properies

更新(3): 存在しない、または利用できないイベントログの処理を修正しました。 Verbose メッセージ


私はすでに手動でチャートを作ったとしても私は確かにこれを試してみます。
Root Loop

私を投稿してください、私はフィードバックに興味があります!
beatcracker

それはここでクラッシュします: "$ Events = Get-WinEvent - ComputerName $ PC - FilterHashtable $ Filter - MaxEvents $ MaxEvents"
magicandre1981

奇妙なことに、私は8.1を実行していて、それはローカルPCと3つのリモートサーバーのためにちょうどうまく働きました。例外の詳細を投稿できますか?このスクリプトをドメイン管理者として実行しているので、これは認証の問題になる可能性があります。 localhostに対して実行しようとしてもクラッシュしませんか?
beatcracker

私は自分のローカルボックスでこれを試してみましたが、結果は正確ではありませんでした、すべてのstartDateが同じ、終了日が空、そしてすべての期間が同じでした。パラメータ "パス"上
Root Loop
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.