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 在表中显示计划作业实例的 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
由于 PSScheduledJob 模块未导入到会话中,作业 cmdlet 可能无法获取计划作业实例或其结果。
注意
在对计划作业实例使用作业 cmdlet 之前,请验证会话中是否包含 PSScheduledJob 模块。 如果没有 PSScheduledJob 模块,作业 cmdlet 将无法获取计划作业实例或其结果。
若要导入 PSScheduledJob 模块,请运行以下命令:
Import-Module PSScheduledJob
Receive-Job cmdlet 可能已返回结果
如果 Receive-Job
未返回作业实例结果,可能是因为在当前会话中针对该作业实例运行了 Receive-Job
命令,但没有指定 Keep 参数。
如果不结合 Keep 参数使用 Receive-Job
,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 参数在会话中多次获取结果
若要在会话中多次获取作业实例的结果,请使用 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-ScheduledJob
和 Set-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-ScheduledJob
或 Set-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 模块,然后运行该命令。