我在 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
最佳答案
我看不出主机文件的第一行(我推断你的意思是 testhoSTList.tx)会被第二次遇到,因为你只列出了一次。这似乎甚至不是需要退出条件的无限循环。 Foreach-Object 不会无限期地重复。
在我看来,问题不在于循环不会无条件退出,而是语法无效。
- Where-Object 通过仅传递满足特定条件的对象来过滤管道,但随后的脚本 block 不执行 bool 测试。
- 事实上,脚本 block 的内容本身似乎是无效的。 -f 是格式运算符,左操作数是格式字符串,但是
$_.Name
不是格式字符串。
根据你的描述,我在这里猜测一下,这个想法是过滤Get-WmiObject Win32_Product
的结果。对于 Name 属性未在 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-Object 和 Where-Object 的缩写。)
关于windows - 在 PowerShell v2 中打破 foreach 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21125853/