時間と日付に基づいてWindowsタスクスケジューラのすべてのタスクの図表を作成できるユーティリティ/ツールがあるかどうかを知っている人はいますか。
私たちはすべてのスケジュールされたタスクのためのサーバーを持っていて、それは元管理者によって作られた貧弱なデザインのため最近遅くなっています。一つずつ通過することがたくさんあります。
うまくいけば、いくつかのユーティリティがこれを行うことができます。
時間と日付に基づいてWindowsタスクスケジューラのすべてのタスクの図表を作成できるユーティリティ/ツールがあるかどうかを知っている人はいますか。
私たちはすべてのスケジュールされたタスクのためのサーバーを持っていて、それは元管理者によって作られた貧弱なデザインのため最近遅くなっています。一つずつ通過することがたくさんあります。
うまくいけば、いくつかのユーティリティがこれを行うことができます。
回答:
このPowershellスクリプトはタスクスケジューラのイベントログを読み取り、CSVにエクスポートします。 Task Name
、 Start Date
、 Finish Date
そして Duration
起動されたすべてのタスクに対して。次に、このデータを選択したスプレッドシートに送り、GANTT図を作成します。
必要条件
スクリプトは以下の引数を受け入れます。
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では、タスクスケジューラのログが無効になっていることがわかりました。ロギングが有効になっていることを確認するには、次の手順を実行します。
All Tasks History
有効にします。読むべき Disable All Tasks History
(うーん): タスクスケジューラの Operational
イベントログが有効になります。
開いた:
イベントビューアー → アプリケーションとサービスのログ → マイクロソフト → Windows → タスクスケジューラ → 運用上の →それを右クリック(または右ペインに移動) プロパティ
更新(3): 存在しない、または利用できないイベントログの処理を修正しました。 Verbose
メッセージ