PowerShell 代码以交互方式运行,但不在脚本内运行

标签 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

总而言之,为什么当手动输入到命令行时,这段代码可以像魅力一样工作,但是当从脚本执行时,我会收到上述错误?

谢谢。

最佳答案

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/

相关文章:

windows - 使用 VBScript 查询本地组策略

c# - WMI "string embedded instance"

powershell - Windows 自定义不适用于 Terraform

Powershell Remedy ARQ 文件,可能存在编码问题

powershell - 如何从函数语句中退出 powershell 函数

c# - 非英语系统上的 WMI 查询

windows - 适用于 Windows 的 Ansible : Cannot access Windows machine via WinRM

PowerShell 安全扩展任意字符串中的非打印字符

function - 在 Powershell 中,如何在函数内设置变量值并使该值在父作用域中可用?

azure - 无法使用 Azure 认证测试工具 1.2 连接到 VM