about_Scheduled_Jobs_Troubleshooting

简短说明

介绍如何解决计划作业的问题

长说明

本文档描述了在使用 PowerShell 的计划作业功能时可能会遇到的一些问题,并针对这些问题提供了建议的解决方法。

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

有关 PSScheduledJob 模块中包含的 cmdlet 的详细信息,请参阅 PSScheduledJob

找不到作业结果

在 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

Get-Job cmdlet 沿管道发送 ProcessJob 对象。 Format-Table cmdlet 在表中显示计划作业实例的 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

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

注意

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

若要导入 PSScheduledJob 模块,请运行以下命令:

Import-Module PSScheduledJob

Receive-Job cmdlet 可能已返回结果

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

如果不结合 Keep 参数使用 Receive-JobReceive-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 参数在会话中多次获取结果

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

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 属性值,请使用 Register-ScheduledJobSet-ScheduledJob cmdlet 的 MaxResultCount 参数。

以下命令将 ExecutionHistoryLength 属性值增大至 50。

Get-ScheduledJob ProcessJob | Set-ScheduledJob -MaxResultCount 50

作业实例结果可能已被删除

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

若要删除计划作业的执行历史记录,请使用计划作业的 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 获取作业结果,但结果仅在你收到结果之前可用,除非使用 Receive-Job cmdlet 的 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-ScheduledJobOption -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

由于权限不足,计划作业可能无法运行

计划作业以创建作业的用户的权限,或者由 Register-ScheduledJobSet-ScheduledJob 命令中 Credential 参数指定的用户的权限运行。

如果该用户无权运行命令或脚本,则作业将会失败。

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

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

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

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

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

删除计划作业的 <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 模块,然后运行该命令。

另请参阅