Private/Collectors.ScheduledTasks.ps1
|
function Get-ICScheduledTaskEvidence { [CmdletBinding()] param( [Parameter(Mandatory)] [object]$Context ) $warnings = New-Object System.Collections.ArrayList $files = New-Object System.Collections.ArrayList $taskRecords = New-Object System.Collections.ArrayList $taskCsv = New-Object System.Collections.ArrayList $xmlCount = 0 if (-not (Test-ICCommandAvailable -Name 'Get-ScheduledTask')) { Add-ICCollectorWarning -List $warnings -Message 'ScheduledTasks cmdlets are unavailable.' Add-ICOutputFiles -List $files -Path (Export-ICCollectorData -Context $Context -Collector ScheduledTasks -RelativePath 'evidence/scheduled-tasks/tasks.json' -Data @()) return New-ICCollectorResultData -OutputFiles @($files) -Warnings @($warnings) -Metrics ([ordered]@{ ScheduledTasks = 0; TaskXmlFiles = 0 }) } $tasks = @() try { $tasks = @(Get-ScheduledTask -ErrorAction Stop | Sort-Object TaskPath, TaskName) } catch { Add-ICCollectorWarning -List $warnings -Message "Scheduled task inventory: $($_.Exception.Message)" } foreach ($task in $tasks) { $info = $null try { $info = Get-ScheduledTaskInfo -InputObject $task -ErrorAction Stop } catch { Add-ICCollectorWarning -List $warnings -Message "Task info '$($task.TaskPath)$($task.TaskName)': $($_.Exception.Message)" } $actions = @($task.Actions | ForEach-Object { [ordered]@{ Type = $_.CimClass.CimClassName Execute = Get-ICPropertyValue -InputObject $_ -Name 'Execute' Arguments = Get-ICPropertyValue -InputObject $_ -Name 'Arguments' WorkingDirectory = Get-ICPropertyValue -InputObject $_ -Name 'WorkingDirectory' ClassId = Get-ICPropertyValue -InputObject $_ -Name 'ClassId' Data = Get-ICPropertyValue -InputObject $_ -Name 'Data' } }) $triggers = @($task.Triggers | ForEach-Object { [ordered]@{ Type = $_.CimClass.CimClassName Enabled = Get-ICPropertyValue -InputObject $_ -Name 'Enabled' StartBoundary = Get-ICPropertyValue -InputObject $_ -Name 'StartBoundary' EndBoundary = Get-ICPropertyValue -InputObject $_ -Name 'EndBoundary' Delay = Get-ICPropertyValue -InputObject $_ -Name 'Delay' RandomDelay = Get-ICPropertyValue -InputObject $_ -Name 'RandomDelay' UserId = Get-ICPropertyValue -InputObject $_ -Name 'UserId' Subscription = Get-ICPropertyValue -InputObject $_ -Name 'Subscription' RepetitionInterval = Get-ICPropertyValue -InputObject (Get-ICPropertyValue -InputObject $_ -Name 'Repetition') -Name 'Interval' RepetitionDuration = Get-ICPropertyValue -InputObject (Get-ICPropertyValue -InputObject $_ -Name 'Repetition') -Name 'Duration' StopAtDurationEnd = Get-ICPropertyValue -InputObject (Get-ICPropertyValue -InputObject $_ -Name 'Repetition') -Name 'StopAtDurationEnd' } }) $record = [pscustomobject][ordered]@{ TaskName = $task.TaskName TaskPath = $task.TaskPath State = [string]$task.State Author = $task.Author Description = $task.Description URI = $task.URI Hidden = Get-ICPropertyValue -InputObject $task.Settings -Name 'Hidden' Enabled = Get-ICPropertyValue -InputObject $task.Settings -Name 'Enabled' ExecutionTimeLimit = Get-ICPropertyValue -InputObject $task.Settings -Name 'ExecutionTimeLimit' MultipleInstances = [string](Get-ICPropertyValue -InputObject $task.Settings -Name 'MultipleInstances') RunOnlyIfIdle = Get-ICPropertyValue -InputObject $task.Settings -Name 'RunOnlyIfIdle' RunOnlyIfNetworkAvailable = Get-ICPropertyValue -InputObject $task.Settings -Name 'RunOnlyIfNetworkAvailable' WakeToRun = Get-ICPropertyValue -InputObject $task.Settings -Name 'WakeToRun' Principal = [ordered]@{ UserId = Get-ICPropertyValue -InputObject $task.Principal -Name 'UserId' GroupId = Get-ICPropertyValue -InputObject $task.Principal -Name 'GroupId' DisplayName = Get-ICPropertyValue -InputObject $task.Principal -Name 'DisplayName' LogonType = [string](Get-ICPropertyValue -InputObject $task.Principal -Name 'LogonType') RunLevel = [string](Get-ICPropertyValue -InputObject $task.Principal -Name 'RunLevel') ProcessTokenSidType = [string](Get-ICPropertyValue -InputObject $task.Principal -Name 'ProcessTokenSidType') RequiredPrivilege = Get-ICPropertyValue -InputObject $task.Principal -Name 'RequiredPrivilege' } Actions = $actions Triggers = $triggers LastRunTimeUtc = ConvertTo-ICIso8601 -Value (Get-ICPropertyValue -InputObject $info -Name 'LastRunTime') NextRunTimeUtc = ConvertTo-ICIso8601 -Value (Get-ICPropertyValue -InputObject $info -Name 'NextRunTime') LastTaskResult = Get-ICPropertyValue -InputObject $info -Name 'LastTaskResult' NumberOfMissedRuns = Get-ICPropertyValue -InputObject $info -Name 'NumberOfMissedRuns' } [void]$taskRecords.Add($record) [void]$taskCsv.Add([pscustomobject][ordered]@{ TaskPath = $task.TaskPath TaskName = $task.TaskName State = [string]$task.State Principal = [string](Get-ICPropertyValue -InputObject $task.Principal -Name 'UserId') RunLevel = [string](Get-ICPropertyValue -InputObject $task.Principal -Name 'RunLevel') Hidden = Get-ICPropertyValue -InputObject $task.Settings -Name 'Hidden' ActionSummary = ($actions | ForEach-Object { "$(Get-ICPropertyValue -InputObject $_ -Name 'Execute') $(Get-ICPropertyValue -InputObject $_ -Name 'Arguments')" }) -join ' | ' TriggerTypes = ($triggers | ForEach-Object { Get-ICPropertyValue -InputObject $_ -Name 'Type' }) -join ',' LastRunTimeUtc = ConvertTo-ICIso8601 -Value (Get-ICPropertyValue -InputObject $info -Name 'LastRunTime') NextRunTimeUtc = ConvertTo-ICIso8601 -Value (Get-ICPropertyValue -InputObject $info -Name 'NextRunTime') LastTaskResult = Get-ICPropertyValue -InputObject $info -Name 'LastTaskResult' }) if ($Context.Configuration.ExportScheduledTaskXml) { try { $xml = Export-ScheduledTask -TaskName $task.TaskName -TaskPath $task.TaskPath -ErrorAction Stop $identity = "$($task.TaskPath)$($task.TaskName)" $safeName = ConvertTo-ICSafeFileName -Value ($identity.Trim('\') -replace '\\', '_') -MaximumLength 90 $digest = Get-ICShortHash -Value $identity -Length 10 $xmlPath = Join-Path $Context.RootPath ("evidence/scheduled-tasks/xml/{0}-{1}.xml" -f $safeName, $digest) [void](Write-ICUtf8File -Path $xmlPath -Content ([string]$xml)) [void]$files.Add($xmlPath) $xmlCount++ } catch { Add-ICCollectorWarning -List $warnings -Message "Task XML '$($task.TaskPath)$($task.TaskName)': $($_.Exception.Message)" } } } Add-ICOutputFiles -List $files -Path (Export-ICCollectorData -Context $Context -Collector ScheduledTasks -RelativePath 'evidence/scheduled-tasks/tasks.json' -Data @($taskRecords)) $csvPath = Join-Path $Context.RootPath 'evidence/scheduled-tasks/tasks.csv' [void](Write-ICCsvFile -Path $csvPath -InputObject @($taskCsv) -SpreadsheetSafe ([bool](Get-ICPropertyValue -InputObject $Context.Configuration -Name 'SpreadsheetSafeCsv' -Default $true))) [void]$files.Add($csvPath) return New-ICCollectorResultData -OutputFiles @($files) -Warnings @($warnings) -Metrics ([ordered]@{ ScheduledTasks = $taskRecords.Count RunningTasks = @($taskRecords | Where-Object State -eq 'Running').Count HiddenTasks = @($taskRecords | Where-Object Hidden -eq $true).Count TaskXmlFiles = $xmlCount }) } |