Powershell捕获循环输出到变量

时间:2013-05-17 04:22:05

标签: powershell nested-loops

嗨,大家好我正在解决如何捕获对变量的ping响应的问题,如果这是有道理的。因为我希望能够通过响应输出回csv。当然,我很有可能以完全错误的方式接近这个!

$PingMachines=import-Csv -path C:\temp\pcs.csv -Header cn,operatingsystem,LastLogonDate

foreach ($pc in $pingmachines.cn) {
    $PingStatus = Gwmi Win32_PingStatus -Filter "Address = '$pc'" | `
    Select-Object StatusCode

    If ($PingStatus.StatusCode -eq 0){ 
        Write-Host $pc "up"
    }     
    Else {
        Write-Host $pc "down"
    }
}

在一个理想的世界中id喜欢能够保存输出,即pc,pingstatus.statuscode返回变量,但我正在努力与逻辑以及如何增加变量而不是仅仅拥有最后一个对象。

提前致谢。

3 个答案:

答案 0 :(得分:0)

我重写了你的代码;这对我有用:

$machines = import-csv -path machines.csv -header ip,os,LastLogonDate

foreach ($machine in $machines)
{
    $ip = $machine.ip
    $status = gwmi win32_PingStatus -filter "Address = '$ip'"

    if ($status.StatusCode -eq 0)
    { Write-Host $ip 'up' }
    else
    { Write-Host $ip 'down' }
}

我在文件machines.csv上测试了它,如下所示:

"127.0.0.1","linux","2012-1-1"
"192.168.1.93","minux","2012-2-10"
"192.168.1.254","xenix","2012-3-20"
"192.168.1.66","dynix","2012-4-5"

当我运行它时,输出看起来像这样:

PS C:\Users\dharmatech\Documents> C:\Users\dharmatech\Documents\check-machine-status.ps1
127.0.0.1 up
192.168.1.93 up
192.168.1.254 up
192.168.1.66 up

答案 1 :(得分:0)

使用Win32_PingStatus WMI对象,因为它已包含您需要的数据。将gwmi结果传递给Select-Object时,除了StatusCode之外的其他所有内容。

考虑

$PingStatus = Gwmi Win32_PingStatus -Filter "Address = '$pc'" | Select-Object StatusCode
$PingStatus # Contains only StatusCode

输出:

StatusCode
----------
0

而WMI类包含更多成员:

$PingStatus = Gwmi Win32_PingStatus -Filter "Address = '$pc'" 
$PingStatus # Contains a lot more

输出:

Source Destination IPV4Address  IPV6Address  Bytes  Time(ms)
------ ----------- -----------  -----------  -----  --------
MyPC   Server      10.0.0.1     {}           32     1

答案 2 :(得分:0)

使用带有ForEach-Object的管道而不是foreach(in)构造。使用ForEach-Object将命令作为管道的一部分运行,这将允许您将输出捕获为变量。

$PingMachines=import-Csv -path C:\temp\pcs.csv -Header cn,operatingsystem,LastLogonDate

$PingMachines.cn | ForEach-Object {
  $PingStatus = Gwmi Win32_PingStatus -Filter "Address = '$_'" | `
    Select-Object StatusCode

  If ($PingStatus.StatusCode -eq 0){ 
    Write-Host $_ "up"
  }     
  Else {
      Write-Host $_ "down"
  }
}

你可以想到管道版本的$ _自动变量,如下所示:

foreach( $_ in $PingMachines.cn) {
  #code that uses $_
}

一旦你有一个管道,你需要输出一个对象,而不是只使用Write-Host打印到屏幕上:

$PingMachines=import-Csv -path C:\temp\pcs.csv -Header cn,operatingsystem,LastLogonDate

$PingResults = $PingMachines.cn | ForEach-Object {
  $PingStatus = Gwmi Win32_PingStatus -Filter "Address = '$_'" | `
    Select-Object StatusCode,Address
    #I added the Address property above so you would have the machine name in the output object

  If ($PingStatus.StatusCode -eq 0){ 
    Write-Host $_ "up"
  }     
  Else {
      Write-Host $_ "down"
  }

  #Send the $PingStatus object out on the pipeline, which will end up in $PingResults
  Write-Output $PingStatus
}

June Blender最近发表了一篇关于powershell.org的好文章,内容涉及输出对象与Write-Host以及创建自定义对象,因此我不想在此处详细介绍。