【问题标题】:if statement in Start-Job scriptblockStart-Job 脚本块中的 if 语句
【发布时间】:2018-03-23 18:01:33
【问题描述】:

我正在尝试使用 PowerShell 创建一个简单的网络扫描程序,并且我希望它并行运行多个“ping(或在本例中为测试连接)”。

Start-Job 似乎是完成这种多线程场景的最佳方式。

这是我正在尝试做的一个简化示例。

$list=@("192.168.1.1", "192.168.1.2", "192.168.1.3", "192.168.1.4")

ForEach ($item In $list) {
  Start-Job -ScriptBlock {
    if (Test-Connection $item -Quiet -Count 1) {
      Add-Content -value "$item found" -Path C:\logs\test.txt
    }
  }
}

然而,这没有任何作用。 如果我删除 Start-Job 部分,它确实可以工作,但会丢失它的多处理。 如果我删除 if 语句,则写入文件部分有效。

所以问题似乎是在作业的脚本块中使用 if 语句时。

我缺少关于 start-job 命令的某些内容。 或者有没有更好的方法来创建这种脚本?

【问题讨论】:

  • 嗯,我看到的第一个问题是您尝试写入的文件可能会发生文件锁冲突。
  • 我创建了一个带有 for 循环 (1-1000) 的脚本,该脚本创建了写入文件的作业并且它可以工作。所以不要认为这是问题。
  • 我并不是说这是问题所在。我是说这是编写代码的不好方法。它不是线程安全的。使用 1-1000 循环执行此操作根本不是相同的情况,并且是线程安全的。
  • 好吧,1-1000 如果不能保证线程安全,但它产生冲突的可能性要小得多。
  • Start-Job 的问题在于范围。您需要将 IP 传递到脚本块中

标签: powershell if-statement start-job


【解决方案1】:

$item 在 scriptblock 范围内不可用,因此您需要将值作为参数传入。

$list=@("192.168.1.1", "192.168.1.2", "192.168.1.3", "192.168.1.4")

ForEach ($item In $list) {
  Start-Job -ScriptBlock {
    param($item)
    if (Test-Connection $item -Quiet -Count 1) {
      Add-Content -value "$item found" -Path C:\logs\test.txt
    }
  } -argumentlist $item
}

【讨论】:

  • 由于潜在的文件写入冲突,仍然不是一个好的实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-17
  • 1970-01-01
  • 2013-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多