PowerShell代码以交互方式工作,但不在脚本中

时间:2012-05-16 14:55:12

标签: powershell wmi winrm

拜!

所以,我只是参加了一些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

总结一下,为什么这个代码在手动输入到命令行时就像魅力一样,但是当从脚本执行时我得到上面的错误?

感谢。

1 个答案:

答案 0 :(得分:4)

Enter-PSSession仅供互动使用。如果将该行放在脚本中,则后续行在远程会话中运行。如果你想在脚本中远程运行一些脚本,你可以这样做:

$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,因此存在一些问题。退一步,你可以写上面这样简单一点:

$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变体,所以它更多地说明了技术和语法。你可能不得不玩它。