致敬!
所以,我只是在日常的一些 powershell 编程中遇到了这个小家伙:
Get-WmiObject : Invalid class
At line:184 char:19
+ $RECApp = gwmi <<<< Win32_product | ? {$_.Name.Contains($Application)}
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId: GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
有趣的是,仅当从脚本执行代码时才会显示此错误,但是当手动输入命令行时,相同的代码会起作用。我不知道这是否与我正在执行脚本的远程计算机有关,但是如果它在手动输入时有效但在从脚本执行时无效,为什么要这样做呢?我将在这里为您提供一段代码:
Enter-PSSession -ComputerName $serverName
$App = gwmi Win32_product | ? {$_.Name.Contains($Application)}
$App.Uninstall();
exit
总而言之,为什么当手动输入到命令行时,这段代码可以像魅力一样工作,但是当从脚本执行时,我会收到上述错误?
谢谢。
最佳答案
Enter-PSSession
仅供交互使用。如果您将该行放入脚本中,则后续行不会在远程 session 中运行。如果您想在脚本中远程运行某些脚本,您可以这样做:
$session = New-PSSession -ComputerName $serverName
Invoke-Command -Session $session {
param($name)
$App = gwmi Win32_product | ? {$_.Name.Contains($name)}
$App.Uninstall();
} -arguments $application
这里有一点问题,因为我必须将 $application
作为参数传递给 Invoke-Command
,因为远程 session 中不存在该变量。退后一步,您可以将上面的内容写得更简单一些,如下所示:
$app = gwmi -computer $servername win32_product | ? {
$_.name.contains($application)
}
现在,问题在于您正在从服务器拉回所有 win32_product
对象并在本地计算机上进行过滤。这是大量不必要的网络流量。如果您可以在远程机器上进行过滤,速度会更快,所以让我们稍微修改一下:
$app = gwmi -computer $servername -query `
"select * from win32_product where name = '$application'"
$app.Uninstall()
现在只会从远程计算机检索您想要的 win32_product
。我尚未测试上述 gwmi -computer
变体,因此它更能说明技术和语法。您可能需要玩一下它。
关于PowerShell 代码以交互方式运行,但不在脚本内运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10621182/