我的目标是使用Powershell检查、禁用和删除许多Windows服务器上的计划任务。有些服务器是Windows 2008R2,因此获取调度任务是不可能的。我必须使用schtasks
这是我目前掌握的情况
$servers = (Get-ADComputer -Server DomainController -Filter 'OperatingSystem -like "*Server*"').DNSHostname
$servers |
ForEach-Object {
if (Test-Connection -Count 1 -Quiet -ComputerName $_) {
Write-Output "$($_) exists, checking for Scheduled Task"
Invoke-Command -ComputerName $_ {
If((schtasks /query /TN 'SOMETASK')) {
Write-Output "Processing removal of scheduled task`n"
schtasks /change /TN 'SOMETASK' /DISABLE
schtasks /delete /TN 'SOMETASK' /F
}
else {
Write-Output "Scheduled Task does not exist`n"
}
}
}
}
当某个任务存在时,这很好,但当它不存在时,Powershell会抛出一个错误,如下所示:
ERROR: The system cannot find the file specified.
+ CategoryInfo : NotSpecified: (ERROR: The syst...file specified.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
+ PSComputerName : SERVER1
NotSpecified: (:) [], RemoteException
Scheduled Task does not exist
我可以通过将$ErrorActionPreference设置为“静默继续”来规避此行为,但这会抑制我可能感兴趣的其他错误。我也尝试了尝试,捕获,但仍然生成错误。我不认为我可以将 -错误处理参数添加到 IF 语句中。任何人都可以伸出援助之手吗?
谢谢你,
这似乎使执行这项工作过于复杂。
为什么禁用和删除vs只是删除,因为这似乎有点多余?
所有计划的任务都是xml文件和reg条目,如果您不再需要该任务,可以删除它们。因此,您可以使用sue Get-ChildItem。
# File system:
(Get-ChildItem -Path "$env:windir\System32\Tasks").FullName
# Results
<#
...
C:\Windows\System32\Tasks\Microsoft
...
C:\Windows\System32\Tasks\MicrosoftEdgeUpdateTaskMachineCore
...
#>
# Registry:
Get-ChildItem -Path 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Schedule\Taskcache\Tasks'
# Results
<#
Name Property
---- --------
{01C5B377-A7EB-4FF3-9C6C-86852 Path : \Microsoft\Windows\Management\Provisioning\Logon
...
#>
Get-ChildItem -Path 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Schedule\Taskcache\Tree'
# Results
<#
Name Property
---- --------
Adobe Acrobat Update Task SD : {1...
#>
只需按名称选择任务,然后使用普通文件系统 cmdlet 删除文件和注册表项即可。
就个人而言,我更喜欢使用Scheduler ComObject来管理计划任务。您可以使用它连接到其他服务器,并简单地搜索它们以管理它们的任务。
$Scheduler = New-Object -ComObject Schedule.Service
$servers = (Get-ADComputer -Server DomainController -Filter 'OperatingSystem -like "*Server*"').DNSHostname
$servers |
ForEach-Object {
if (Test-Connection -Count 1 -Quiet -ComputerName $_) {
Write-Output "$($_) exists, checking for Scheduled Task"
$Scheduler.Connect($_)
$RootFolder = $Scheduler.GetFolder("\")
$TargetTask = $RootFolder.GetTask('SOMETASK')
# If the task wasn't found continue to the next server
If(!$TargetTask){
Write-Output "Scheduled Task does not exist`n"
Continue
}
Write-Output "Processing removal of scheduled task`n"
$TargetTask.Enabled = $false
$RootFolder.DeleteTask('SOMETASK')
}
}
tl;dr:
使用2
< li >要解决至少PowerShell [Core] 7.0(见下文)中出现的错误,请确保< code > $ ErrorActionPreferece
未设置为< code >“Stop”。
# Execute with stderr silenced.
# Rely on the presence of stdout output in the success case only
# to make the conditional true.
if (schtasks /query /TN 'SOMETASK' 2>$null) { # success, task exists
"Processing removal of scheduled task`n"
# ...
}
有关背景信息和更多一般用例,请继续阅读。
鉴于来自外部程序的 stderr 流的行如何表现,如您的问题所示,这听起来像是在 PowerShell ISE 中运行代码,我建议远离:PowerShell ISE 已经过时,应避免前进(链接答案的底部)。
ISE默认通过PowerShell的错误流显示stderr lines尤其有问题——参见这个GitHub问题。
幸运的是,常规控制台不会这样做 - 它将 stderr 行传递到主机(控制台),并正常打印它们(不是红色),这是正确的做法,因为您通常不能假设所有 stderr 输出都表示错误(尽管流的名称)。
对于表现良好的外部程序,您应该只从其进程退出代码(如自动$LASTEXITCODE
变量[1]中反映的那样)获得成功与失败,而不是从 stderr 输出的存在中得出成功与失败: 退出代码 0
表示成功,任何非零退出代码(通常)表示失败。
至于您的具体情况:
在常规控制台中,$ErrorActionPretion
首选项变量的值不适用于外部程序,例如schtasks.exe
,除非在您还使用2时以错误的形式[在PowerShell 7.2中修复]
由于您的
schtasks /query /TN “SOMETASK”
命令用作测试,因此您可以执行以下操作:
# Execute with all streams silenced (both stdout and stderr, in this case).
# schtask.exe will indicate the non-existence of the specified task
# with exit code 1
schtasks /query /TN 'SOMETASK' *>$null
if ($LASTEXITCODE -eq 0) { # success, task exists
"Processing removal of scheduled task`n"
# ...
}
# You can also squeeze it into a single conditional, using
# $(...), the subexpression operator.
if (0 -eq $(schtasks /query /TN 'SOMETASK' *>$null; $LASTEXITCODE)) { # success, task exists
"Processing removal of scheduled task`n"
# ...
}
在您的特定情况下,可以使用更简洁的解决方案,该解决方案依赖于您的
schtasks
命令 (a) 在成功的情况下生成 stdout 输出(如果任务存在)和 (b) 仅在成功的情况下执行此操作:
# Execute with stderr silenced.
# Rely on the presence of stdout output in the success case only
# to make the conditional true.
if (schtasks /query /TN 'SOMETASK' 2>$null) { # success, task exists
"Processing removal of scheduled task`n"
# ...
}
如果
schtasks.exe
生成标准输出(映射到 PowerShell 的成功输出流 1
),则 PowerShell 的隐式到布尔转换将考虑条件$true
(有关 PowerShell 到布尔转换规则的概述,请参阅此答案的底部部分)。
请注意,条件只作用于成功输出流的输出(< code>1
),其他流会通过,如stderr输出(< code>2)在这种情况下(正如您所经历的)。
阿拉伯数字
1
和 2
分别是 PowerShell 的成功输出/错误流的数量,对于外部程序,它们分别指其标准输出(标准输出)和 stderr(标准错误)流 - 请参阅about_Redirection
。
您还可以使用<code>2捕获stderr输出
>
阿拉伯数字
正如上述错误所暗示的,您必须确保$ErrorActionPretion
未设置为'Stop'
,因为2
除了上述错误,使用
2
< li >这两个问题的根本原因是stderr行意外地通过PowerShell的错误流进行路由,尽管没有很好的理由这样做-请参阅GitHub问题#11133。
[1]请注意,自动
$?
变量也被设置为布尔值($true
/$false
),但不可靠:因为stderr输出当前(v7.0)意外地通过PowerShell的错误流路由,如果使用2重定向
我试图用命令提示符用java编译一个程序。我的程序在eclipse中运行良好,但是,当我试图在命令提示符中编译它时,我收到了一条错误消息。任何帮助和指导都将不胜感激。 triton.java:20:错误:不能dind符号循环Loop=new Loop(); 符号:类循环位置:类Triton trion.java:20:错误:找不到符号循环循环=新循环();sybmol:类循环位置:类Triton
我的命令提示符出错了。我从Jupyter尝试了,但出现了一些错误。我感谢任何查看或回答的人,感谢您的时间!
好吧,我是新来的Java,并试图从命令提示符运行一个java程序(因为Sublime编译和运行它的小东西,但不允许用户输入和东西)。 我将命令提示符设置为我有我的文件的文件夹,称为Learner.java. 我在环境变量中为JDK bin设置了一个路径,并创建了一个JAVA_HOME变量,其中包含JDK bin的值(其他一些帖子建议)。 在我讨论这个问题之前,这是我的代码: 如你所见,这是一个以“
$ gdb -q `which gdb` Reading symbols from /home/xmj/install/binutils-gdb-git/bin/gdb...done. (gdb) r -q Starting program: /home/xmj/install/binutils-gdb-git/bin/gdb -q [Thread debugging using libthrea
本文向大家介绍通过什么命令指定命令提示符?相关面试题,主要包含被问及通过什么命令指定命令提示符?时的应答技巧和注意事项,需要的朋友参考一下 答案: \u:显示当前用户账号 \h:显示当前主机名 \W:只显示当前路径最后一个目录 \w:显示当前绝对路径(当前用户目录会以~代替) $PWD:显示当前全路径 $:显示命令行’$'或者’#'符号 #:下达的第几个命令 \d:代表日期,格式为 week da
我是刚到爪哇的。我正在尝试将大型机代码转换为Java。我在命令行下面运行。 我可以知道如何设置res.jar。 命令行代码