关于计划作业故障排除

简短说明

说明如何解决计划作业的问题

长说明

本文档介绍在使用 PowerShell 的计划作业功能时可能会遇到的一些问题,并建议解决这些问题。

在使用 PowerShell 计划作业之前,请参阅 about_Scheduled_Jobs 以及有关主题的相关计划作业。

找不到作业结果

在 PowerShell 中获取作业结果的基本方法

计划作业运行时,它会创建计划作业的实例。 若要查看、管理和获取计划作业实例的结果,请使用作业 cmdlet。

注意

若要在计划作业的实例上使用作业 cmdlet,必须将 PSScheduledJob 模块导入到会话中。 若要导入 PSScheduledJob 模块,请键入 Import-Module PSScheduledJob 或使用任何计划作业 cmdlet,例如 Get-ScheduledJob

若要获取计划作业的所有实例的列表,请使用 Get-Job cmdlet。

Import-Module PSScheduledJob
Get-Job ProcessJob
Id     Name         PSJobTypeName   State         HasMoreData     Location
--     ----         -------------   -----         -----------     --------
43     ProcessJob   PSScheduledJob  Completed     False           localhost
44     ProcessJob   PSScheduledJob  Completed     False           localhost
45     ProcessJob   PSScheduledJob  Completed     False           localhost
46     ProcessJob   PSScheduledJob  Completed     False           localhost
47     ProcessJob   PSScheduledJob  Completed     False           localhost
48     ProcessJob   PSScheduledJob  Completed     False           localhost
49     ProcessJob   PSScheduledJob  Completed     False           localhost
50     ProcessJob   PSScheduledJob  Completed     False           localhost

cmdlet 在 Get-Job 管道中向下发送 ProcessJob 对象。 cmdlet Format-Table 在表中显示计划的作业实例的 NameIDPSBeginTime 属性。

Get-Job ProcessJob | Format-Table -Property Name, ID, PSBeginTime -Auto
Name       Id PSBeginTime
----       -- ---------
ProcessJob 43 11/2/2011 3:00:02 AM
ProcessJob 44 11/3/2011 3:00:02 AM
ProcessJob 45 11/4/2011 3:00:02 AM
ProcessJob 46 11/5/2011 3:00:02 AM
ProcessJob 47 11/6/2011 3:00:02 AM
ProcessJob 48 11/7/2011 12:00:01 AM
ProcessJob 49 11/7/2011 3:00:02 AM
ProcessJob 50 11/8/2011 3:00:02 AM

若要获取计划作业实例的结果,请使用 Receive-Job cmdlet。 以下命令获取 ProcessJob 的最新实例的结果, (ID = 50) 。

Receive-Job -ID 50

在磁盘上查找作业结果的基本方法

若要管理计划的作业,请使用作业 cmdlet,例如 Get-JobReceive-Job

如果未 Get-Job 获取作业实例或 Receive-Job 未获取作业结果,则可以在磁盘上搜索作业的执行历史记录文件。 执行历史记录包含所有触发的作业实例的记录。

验证以下路径中计划作业的目录中是否存在时间戳命名的目录:

$home\AppData\Local\Microsoft\Windows\PowerShell\ScheduledJob <ScheduledJobName>\Output

例如:

C:\Users<UserName>\AppData\Local\Microsoft\Windows\PowerShell\ScheduledJob <ScheduledJobName>\Output

例如, Get-ChildItem cmdlet 获取 ProcessJob 计划作业的磁盘上执行历史记录。

$Path = '$home\AppData\Local\Microsoft\Windows\PowerShell'
$Path += '\ScheduledJobs\ProcessJob\Output'
Get-ChildItem $Path
Directory: C:\Users\User01\AppData\Local\Microsoft\Windows\PowerShell
               \ScheduledJobs\ProcessJob\Output

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----         11/2/2011   3:00 AM            20111102-030002-260
d----         11/3/2011   3:00 AM            20111103-030002-277
d----         11/4/2011   3:00 AM            20111104-030002-209
d----         11/5/2011   3:00 AM            20111105-030002-251
d----         11/6/2011   3:00 AM            20111106-030002-174
d----         11/7/2011  12:00 AM            20111107-000001-914
d----         11/7/2011   3:00 AM            20111107-030002-376

每个以时间戳命名的目录都表示一个作业实例。 每个作业实例的结果保存在时间戳命名目录中 Results.xml 文件中。

例如,以下命令获取 ProcessJob 计划作业的每个已保存实例的 Results.xml 文件。 如果 缺少Results.xml 文件,则 PowerShell 无法返回或显示作业结果。

$Path = '$home\AppData\Local\Microsoft\Windows\PowerShell'
$Path += '\ScheduledJobs\ProcessJob\Output\*\Results.xml'
Get-ChildItem $Path
Directory: C:\Users\User01\Appdata\Local\Microsoft\Windows\PowerShell
               \ScheduledJobs\ProcessJob\Output

作业 cmdlet 可能无法获取计划的作业实例或其结果,因为 PSScheduledJob 模块未导入到会话中。

注意

在计划作业实例上使用作业 cmdlet 之前,请验证会话中是否包含 PSScheduledJob 模块。 如果没有 PSScheduledJob 模块,作业 cmdlet 无法获取计划的作业实例或其结果。

导入 PSScheduledJob 模块:

Import-Module PSScheduledJob

Receive-Job cmdlet 可能已返回结果

如果未 Receive-Job 返回作业实例结果,则可能是因为当前会话中针对该作业实例运行了命令 Receive-Job ,但没有 Keep 参数。

如果不 Receive-Job 使用 Keep 参数, Receive-Job 则 返回作业结果并将作业实例的 HasMoreData 属性设置为 FalseFalse 值表示Receive-Job已返回作业的结果,并且实例没有更多要返回的结果。 此设置适用于标准后台作业,但不适用于保存到磁盘的计划作业实例。

若要再次获取作业实例结果,请通过键入 PowerShell启动新的 PowerShell 会话。 导入 PSScheduledJob 模块,然后再次尝试该 Receive-Job 命令。

Receive-Job -ID 50
#No results
PowerShell.exe
Windows PowerShell
Copyright (C) 2012 Microsoft Corporation. All rights reserved.
Import-Module PSScheduledJob
Receive-Job -ID 50
Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id  ProcessName
-------  ------    -----      ----- -----   ------     --  -----------
1213         33    12348      21676    88    25.71   1608  CcmExec
29            4     1168       2920    43     0.02    748  conhost
46            6     2208       4612    45     0.03   1640  conhost

使用 Keep 参数在会话中多次获取结果

若要在会话中多次获取作业实例的结果,请使用 cmdlet 的 Receive-JobKeep 参数。

Import-Module PSScheduledJob
Receive-Job -ID 50 -Keep
Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id  ProcessName
-------  ------    -----      ----- -----   ------     --  -----------
1213         33    12348      21676    88    25.71   1608  CcmExec
29            4     1168       2920    43     0.02    748  conhost
46            6     2208       4612    45     0.03   1640  conhost
Receive-Job -ID 50 -Keep
Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id  ProcessName
-------  ------    -----      ----- -----   ------     --  -----------
1213         33    12348      21676    88    25.71   1608  CcmExec
29            4     1168       2920    43     0.02    748  conhost
46            6     2208       4612    45     0.03   1640  conhost

计划的作业可能已损坏

如果计划的作业损坏,PowerShell 将删除已损坏的计划作业及其结果。 无法恢复已损坏的计划作业的结果。

若要确定计划作业是否仍然存在,请使用 Get-ScheduledJob cmdlet。

Get-ScheduledJob

结果数可能超过了 ExecutionHistoryLength

计划作业的 ExecutionHistoryLength 属性确定将多少个作业实例及其结果保存到磁盘。 默认值为 32。 当计划作业的实例数超过此值时,PowerShell 会删除最早的作业实例,为每个新的作业实例腾出空间。

若要获取计划作业的 ExecutionHistoryLength 属性的值,请使用以下命令格式:

(Get-ScheduledJob <JobName>).ExecutionHistoryLength

例如,以下命令获取 ProcessJob 计划作业的 ExecutionHistoryLength 属性的值。

(Get-ScheduledJob ProcessJob).ExecutionHistoryLength

若要设置或更改 ExecutionHistoryLength 属性的值,请使用 和 Set-ScheduledJob cmdlet 的 Register-ScheduledJobMaxResultCount 参数。

以下命令将 ExecutionHistoryLength 属性的值增加到 50。

Get-ScheduledJob ProcessJob | Set-ScheduledJob -MaxResultCount 50

作业实例结果可能已删除

cmdlet 的 Set-ScheduledJobClearExecutionHistory 参数删除作业的执行历史记录。 可以使用此功能释放磁盘空间或删除不需要、已使用、分析或保存在其他位置的结果。

若要删除计划作业的执行历史记录,请使用计划作业的 ClearExecutionHistory 参数。

以下命令删除 ProcessJob 计划作业的执行历史记录。

Get-ScheduledJob ProcessJob | Set-ScheduledJob -ClearExecutionHistory

此外, Remove-Job cmdlet 会删除作业结果。 使用 Remove-Job 删除计划作业时,它会删除磁盘上作业的所有实例,包括执行历史记录和所有作业结果。

使用 Start-Job cmdlet 启动的作业不会保存到磁盘

使用 Start-Job 启动计划作业时,而不是使用作业触发器启动 Start-Job 标准后台作业。 后台作业及其结果不存储在磁盘上作业的执行历史记录中。

可以使用 Get-Job cmdlet 获取作业,使用 Receive-Job cmdlet 获取作业结果,但结果仅在收到之前可用,除非使用 cmdlet 的 Receive-Job Keep 参数。

此外,后台作业及其结果特定于会话;它们仅存在于创建它们的会话中。 如果使用 删除作业 Remove-Job,请关闭会话或关闭 PowerShell,则会删除作业实例及其结果。

计划的作业不运行

如果作业触发或已禁用计划作业,则计划的作业不会自动运行。

使用 Get-ScheduledJob cmdlet 获取计划的作业。 验证计划作业的 Enabled 属性的值是否为 True

Get-ScheduledJob ProcessJob
Id         Name            Triggers        Command         Enabled
--         ----            --------        -------         -------
4          ProcessJob      {1, 2}          Get-Process     True
(Get-ScheduledJob ProcessJob).Enabled
True

使用 Get-JobTrigger cmdlet 获取计划作业的作业触发器。 验证作业触发器的 Enabled 属性的值是否为 True

Get-ScheduledJob ProcessJob | Get-JobTrigger
Id      Frequency    Time                   DaysOfWeek            Enabled
--      ---------    ----                   ----------            -------
1       Weekly       11/7/2011 5:00:00 AM   {Monday, Thursday}    True
2       Daily        11/7/2011 3:00:00 PM                         True
Get-ScheduledJob ProcessJob|Get-JobTrigger|Format-Table ID, Enabled -Auto
Id Enabled
-- -------
1    True
2    True

如果作业触发器无效,计划的作业不会自动运行

例如,作业触发器可以指定过去的日期或未发生的日期,例如每月的第 5 个星期一。

如果不满足作业触发器的条件或作业选项,则计划的作业不会自动运行。

例如,如果某个特定用户未登录或仅远程连接,则仅当特定用户登录到计算机时才运行的计划作业将不会运行。

检查计划作业的选项,并确保它们感到满意。 例如,要求计算机处于空闲状态或需要网络连接,或者具有较长 IdleDuration 或短暂 IdleTimeout 的计划作业可能永远不会运行。

Get-ScheduledJobOption使用 cmdlet 检查作业选项及其值。

Get-ScheduledJob -Name ProcessJob
StartIfOnBatteries     : False
StopIfGoingOnBatteries : True
WakeToRun              : True
StartIfNotIdle         : True
StopIfGoingOffIdle     : False
RestartOnIdleResume    : False
IdleDuration           : 00:10:00
IdleTimeout            : 01:00:00
ShowInTaskScheduler    : True
RunElevated            : False
RunWithoutNetwork      : True
DoNotAllowDemandStart  : False
MultipleInstancePolicy : IgnoreNew
JobDefinition          : Microsoft.PowerShell.ScheduledJob.ScheduledJobDefinition

有关计划作业选项的说明,请参阅 New-ScheduledJobOption

计划的作业实例可能已失败

如果计划的作业命令失败,PowerShell 会通过生成错误消息立即报告该命令。 但是,如果在任务计划程序尝试运行作业时作业失败,则 PowerShell 将不提供该错误。

使用以下方法检测并更正作业失败:

检查任务计划程序事件日志中是否存在错误。 若要检查日志,请使用事件查看器或 PowerShell 命令,如下所示:

Get-WinEvent -LogName Microsoft-Windows-TaskScheduler/Operational |
 Where {$_.Message -like "fail"}

检查任务计划程序中的作业记录。 PowerShell 计划作业存储在以下任务计划文件夹中:

Task Scheduler Library\Microsoft\Windows\PowerShell\ScheduledJobs

计划作业可能无法运行,因为权限不足

计划的作业使用创建作业的用户的权限或 或 Set-ScheduledJob 命令中的 Register-ScheduledJobCredential 参数指定的用户的权限运行。

如果该用户没有运行命令或脚本的权限,则作业将失败。

无法获取计划作业或计划作业已损坏

在极少数情况下,计划的作业可能会损坏或包含无法解决的内部矛盾。 通常,当手动编辑计划作业的 XML 文件时,就会发生这种情况,从而导致 XML 无效。

当计划的作业损坏时,PowerShell 会尝试从磁盘中删除计划作业、其执行历史记录及其结果。

如果无法删除计划的作业,则每次运行 cmdlet 时都会收到损坏的 Get-ScheduledJob 作业错误消息。

若要删除已损坏的计划作业,请使用以下任一方法:

<ScheduledJobName>删除计划作业的目录。 请勿删除 ScheduledJob 目录。

目录的位置:

$env:UserProfile\AppData\Local\Microsoft\Windows\PowerShell \ScheduledJobs<ScheduledJobName>

例如:

C:\Users<UserName>\AppData\Local\Microsoft\Windows\PowerShell\ ScheduledJobs<ScheduledJobName>.

使用任务计划程序删除计划的作业。 PowerShell 计划任务显示在以下任务计划程序路径中:

Task Scheduler Library\Microsoft\Windows\PowerShell \ScheduledJobs<ScheduledJobName>

作业 cmdlet 无法一致地找到计划作业

PSScheduledJob 模块不在当前会话中时,作业 cmdlet 无法获取计划作业、启动作业或获取其结果。

若要导入 PSScheduledJob 模块,请键入 Import-Module PSScheduledJob 或运行或获取模块中的任何 cmdlet,例如 Get-ScheduledJob cmdlet。 从 PowerShell 3.0 开始,获取或使用模块中的任何 cmdlet 时,将自动导入模块。

PSScheduledJob 模块不在当前会话中时,可以使用以下命令序列。

Get-Job ProcessJob
Get-Job : The command cannot find the job because the job name
ProcessJob was not found.
Verify the value of the Name parameter, and then try the command again.
+ CategoryInfo          : ObjectNotFound: (ProcessJob:String) [Get-Job],
PSArgumentException
+ FullyQualifiedErrorId : JobWithSpecifiedNameNotFound,Microsoft.PowerShell.
Commands.GetJobCommand
Get-Job
Get-ScheduledJob ProcessJob
Id         Name            Triggers        Command      Enabled
--         ----            --------        -------      -------
4          ProcessJob      {1}             Get-Process  True
Get-Job ProcessJob
Id     Name         PSJobTypeName   State       HasMoreData     Location
--     ----         -------------   -----       -----------     --------
43     ProcessJob   PSScheduledJob  Completed   True            localhost
44     ProcessJob   PSScheduledJob  Completed   True            localhost
45     ProcessJob   PSScheduledJob  Completed   True            localhost
46     ProcessJob   PSScheduledJob  Completed   True            localhost
47     ProcessJob   PSScheduledJob  Completed   True            localhost
48     ProcessJob   PSScheduledJob  Completed   True            localhost
49     ProcessJob   PSScheduledJob  Completed   True            localhost
50     ProcessJob   PSScheduledJob  Completed   True            localhost

出现此行为的原因是命令 Get-ScheduledJob 会自动导入 PSScheduledJob 模块,然后运行命令。

另请参阅

about_Scheduled_Jobs_Basics

about_Scheduled_Jobs_Advanced

about_Scheduled_Jobs

任务计划程序