关于计划作业故障排除
简短说明
说明如何解决计划作业的问题
长说明
本文档介绍在使用 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
在表中显示计划的作业实例的 Name、 ID 和 PSBeginTime 属性。
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-Job
和 Receive-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 属性设置为 False。 False 值表示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-Job
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 属性的值,请使用 和 Set-ScheduledJob
cmdlet 的 Register-ScheduledJob
MaxResultCount 参数。
以下命令将 ExecutionHistoryLength 属性的值增加到 50。
Get-ScheduledJob ProcessJob | Set-ScheduledJob -MaxResultCount 50
作业实例结果可能已删除
cmdlet 的 Set-ScheduledJob
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 获取作业结果,但结果仅在收到之前可用,除非使用 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-ScheduledJob
Credential 参数指定的用户的权限运行。
如果该用户没有运行命令或脚本的权限,则作业将失败。
无法获取计划作业或计划作业已损坏
在极少数情况下,计划的作业可能会损坏或包含无法解决的内部矛盾。 通常,当手动编辑计划作业的 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 模块,然后运行命令。