【问题标题】:Breaking foreach loop in PowerShell v2在 PowerShell v2 中打破 foreach 循环
【发布时间】:2014-01-14 22:58:54
【问题描述】:

我在终止 PowerShell v2 中的 foreach-object 循环时遇到问题。对于我要完成的任务的粗略概念,这是伪代码:

  • 从文本文件中读取主机列表
  • 为文本文件中的每个主机获取 Win32_Product(根据排除列表过滤), 将输出转换为 html 并保存。

脚本的原因是我已经积累了一个文本文件,其中列出了标准客户端图像中包含的所有应用程序,并且希望定期从另一个文本文件中扫描主机,以查看是否有任何未经授权、粗略或其他不必要的应用程序在主机上。

代码在粗略的意义上确实可以工作,但我遇到的主要问题是脚本不会在没有人工干预的情况下终止。我想我在这里缺少的组件是运行循环直到某些条件存在(即第二次遇到主机文件中的第一行),然后终止脚本。虽然这是我设想的方法,但我总是对其他逻辑持开放态度,尤其是如果它更有效的话。

这是实际代码:

Get-Content c:\path\to\testhostlist.txt | Foreach-Object {
Get-WmiObject Win32_Product | 
Where-Object { $_.Name -f "'C:\path\to\testauthapplist.txt'" | 

ConvertTo-Html name,vendor,version -title $name -body "<H2>Unauthorized Applications.</H2>"}} |

Set-Content c:\path\to\unauthapplisttest.html  

【问题讨论】:

  • 我不明白你的代码。 Where-Object 过滤器未测试条件。 $_.Name -f "'C:\path\to\testauthapplist.txt'" 没有意义,因为 $_.Name 不是格式字符串。也许有一个复制/粘贴错误? $_.Name-f 之间似乎缺少一些东西。另外,如果您只列出一次,如何再次遇到主机文件的第一行?这似乎不是一个需要退出条件的无限循环。 Foreach-Object 不会无限重复。也许只是因为代码被破坏而卡住了。
  • 请说明您要使用Where-Object { $_.Name -f "'C:\path\to\testauthapplist.txt'" | 完成的任务。我怀疑问题在于这不是您尝试做的任何事情的正确语法。
  • 我怀疑它会终止。它只是非常缓慢。 Get-WmiObject Win32_Product 非常慢,您正在为输入文件中的每一行执行此操作。您应该在开始时执行一次并将结果保存在列表中。我同意 Adi 的观点,即你的 where-object 很奇怪。我认为你需要退后一步,重新设计整个事情。

标签: windows powershell windows-7 scripting


【解决方案1】:

我看不出第二次遇到主机文件的第一行(我推断您的意思是 testhostlist.tx),因为您只列出了一次。这似乎不是一个需要退出条件的无限循环。 Foreach-Object 不会无限重复。

在我看来,问题不在于循环没有条件退出,而是语法无效。

  1. Where-Object通过仅传递满足特定条件的对象来过滤管道,但随后的脚本块不执行布尔测试。
  2. 事实上,脚本块的内容本身并不有效。 -f是格式运算符,左操作数是格式字符串,但$_.Name不是格式字符串。

根据您的描述,我在这里猜测一下,这个想法是为 Name 属性未列在 中的对象过滤 Get-WmiObject Win32_Product 的结果testauthapplist.txt (我认为这就是您所指的“排除列表”)。如果是这样,这是正确的语法:

Get-Content c:\path\to\testhostlist.txt | %{
  Get-WmiObject Win32_Product | ?{
    (Get-Content 'C:\path\to\testauthapplist.txt') -notcontains $_.Name
  } | ConvertTo-Html name,vendor,version -title $name -body "<H2>Unauthorized Applications.</H2>"
} | Set-Content c:\path\to\unauthapplisttest.html

(请注意,%{}?{} 分别只是 Foreach-ObjectWhere-Object 的缩写。)

【讨论】:

    【解决方案2】:

    如果我对您的理解正确,您是在尝试完全停止您的脚本吗?如果是这样,您是否尝试过Break? 如果您只想跳过一个循环,请使用continue

    【讨论】:

      【解决方案3】:
      $hostlist = Get-Content c:\path\to\testhostlist.txt 
      $a = @()
      Foreach($item in $hostlist)
      {
          $a += "<style>"
          $a += "BODY{background-color:gray;}"
          $a += "TABLE{margin: auto;border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
          $a += "TH{border-width: 1px;padding: 4px;border-style: solid;border-color: black;background-color:yellow}"
          $a += "TD{border-width: 1px;padding: 4px;border-style: solid;border-color: black;background-color:white}"
          $a += "h2{color:#fff;}"
          $a += "</style>"
      
          Get-WmiObject Win32_Product | select name,vendor,version | sort name | ConvertTo-Html -head $a -body "<Center><H2>Unauthorized Applications.</H2></Center>" | Out-File c:\path\to\$item"-applist.html"
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-15
        • 2014-03-24
        • 2011-12-08
        • 1970-01-01
        • 2018-07-01
        相关资源
        最近更新 更多