我目前正在管理基于 Windows Server 2008R2 的 Citrix 农场系统。过去,我曾使用 Powershell 脚本检查正在运行的用户进程,并在必要时重新启动它们。
我使用带有附加参数的工具“tasklist.exe”来检查已定义的进程是否在登录用户下运行。不幸的是,tasklist.exe 已经停止工作几天了。重新启动它会导致出现错误消息:
“错误:未找到”或“错误:无效类”。
由于服务器在德国,我把这条消息从德语翻译成了英语。在德国服务器上,它被称为
“Fehler: Nicht gefunden”和“Fehler: Ungultige Klasse”。
因此,我不确定翻译成英文是否正确。事件日志中没有错误日志。
由于它是一个生产系统,因此没有任何更新等变化,也没有互联网连接。
是否有可能缺少 dll 注册?我已检查“depends.exe”是否有任何可能的问题,但我无法确定正常工作的服务器和非正常工作的服务器之间的任何差异。
我还检查了启动“dcomcnfg”时是否有任何错误,但一切正常。
来自工作服务器的 tasklist.exe 的新副本不起作用。该问题与可执行文件本身无关。
下方提供的提示此链接经检查,结果为阴性。
regsvr32 %Windir%\system32\wbem\fastprox.dll
regsvr32 %Windir%\system32\wbem\wbemprox.dll
regsvr32 %Windir%\system32\wbem\wbemsvc.dll
病毒码是最新的(McAfee VDS 8.8 + ASE 8.8)。
有人能给我一些建议,告诉我如何让“tasklist.exe”重新运行吗?或者,我想要一个使用 Powershell 命令的解决方案,它可以帮助重建“tasklist.exe”的功能——这不是一件容易的事,因为我不是最好的脚本编写者。
提前感谢您的帮助、提示或建议!
编辑:
确实,问题与 WMI 有关。Ryan Ries 建议使用以下方法检查 WMI:
“wbemtest”
尝试连接时导致类似的错误。
在这种情况下,我收到了一个错误代码,我可以通过该代码找到解决方案微软技术网。
该页面列出的脚本对我来说不起作用,但是命令
“Winmgmt /salvagerepository”
做过。
因此,感谢 Ryan 提供的 WMI 提示,并感谢 r.tanner.f 提供的解决方法,以防其他所有方法都不起作用。
答案1
虽然除了 tasklist.exe 之外,还可以使用其他程序来获取系统正在运行的进程列表,但 tasklist.exe 突然停止工作让我很担心。它是系统上的一个基本进程,它停止工作可能是数据损坏或其他只会变得更糟的问题的征兆。
如果不尝试找出导致此问题的原因,即使您可以使用 Powershell 或 WMIC 或其他可执行文件来解决这个问题,也就像用电工胶带遮住汽车仪表盘上的“检查机油”灯一样。这并不意味着根本问题不存在。
此外,tasklist.exe 似乎利用 WMI 来获取信息,因此如果 tasklist.exe 不工作,则可能表明您的机器上的 WMI 存在系统问题,因此使用依赖 WMI 的其他工具可能也不会起作用...
以下是排除故障的方法。从 Sysinternals 获取进程监视器。捕获工作机器上的事件,并捕获非工作机器上的事件。在运行 tasklist.exe 时对其进行过滤。现在将两个跟踪文件并排放置,看看它们有何不同。工作机器上的哪些事件返回 SUCCESS,而非工作机器上的相同事件返回 NAME NOT FOUND 或其他非成功代码?
由于您收到的错误消息中提到了无效类,我敢打赌,注册表项、等中发生的事件HKCR\CLSID\{GUID}\
将\HKLM\Software\Classes
显示两个跟踪文件之间的一些明显差异。
编辑:此外,如果您想测试 WMI 本身,可以使用的一种方法是运行wbemtest
。单击Connect...
,并使用root\cimv2
作为命名空间。您应该可以将其他所有内容保留为空白或默认。然后,单击显示为的按钮Query
,并键入select * from win32_process
查询并单击Apply
。您应该会返回一堆有效的进程句柄,并且没有错误消息。
祝你好运...
答案2
用一点 PowerShell 替换对 tasklist.exe 的使用可能比追踪 tasklist.exe 出了什么问题更容易。不过,请看 Ryan Ries 的回答;他很好地说明了为什么追踪这个问题很重要,以及 WMI 可能被破坏并阻止它工作(在这种情况下,您的问题会更大)。无论如何,我更喜欢他的回答。
在 PowerShell 中检查当前用户运行的进程非常简单:
Get-WMIObject win32_process |
Where {$_.ProcessName -eq "foo.exe"} |
ForEach-Object {$_.GetOwner()} |
Where {$_.User -eq [Environment]::Username}
Get-WMIObject
显然会获取一个 WMI 对象,在本例中为 win32_process。将其导入Where-Object
并过滤任何不等于 foo.exe 的内容。然后循环遍历每个对象并运行该GetOwner()
方法。最后,过滤任何不等于当前用户的用户名。
为了便于阅读,我在管道后添加了一个返回(在脚本中也有效),但您也可以用一些别名来缩减它并坚持一行:
gwmi win32_process | ?{$_.ProcessName -eq "smartclient.exe"} | %{$_.GetOwner()} | ?{$_.User -eq [Environment]::UserName}
PowerShell 友好且不会造成任何影响。您无需成为一名优秀的脚本编写者即可从中获得所需的功能,因此不要犹豫尝试使用它。