Powershell - 意外返回管道数据的功能

时间:2018-02-21 16:32:02

标签: powershell

背景 我们公司使用一个非常古老的软件,我们的数据库程序员每周执行一次维护。当他们执行维护时,他们必须在维护之前在远程计算机上结束该过程,否则会导致损坏。通过快速识别运行该进程的计算机,然后让它们远程杀死它,可以尝试使用此脚本来帮助维护它们。

代码我遇到了以下问题:

function Query-Processes ([System.Collections.ArrayList]$Computerlist)
{


    Foreach ($Computer in $Computerlist)
    {
        Invoke-Command -ComputerName $Computer -AsJob -ScriptBlock {Get-Process | Where-Object {($_.ProcessName -eq 'ntvdm') -or ($_.ProcessName -eq 'Runform')}}

    }

    $arrJob_Results = @()
    While ((Get-Job).Count -gt 0)
    {
        Get-Job | Where-Object {$_.State -eq 'Failed'} | Remove-Job
        Get-Job | Where-Object {($_.State -eq 'Completed')} | ForEach-Object {
        If ($_.HasMoreData -eq $False) {Remove-Job -Id $_.Id | Out-Null}
        ElseIf ($_.HasMoreData -eq $True) {$arrJob_Results += Receive-Job -Id $_.Id}
        }
    }
    return $arrJob_Results

}

旁注:是的,它正在检查NTVDM,因为我们有一个使用16位DOS的关键软件,欢迎来到我们的噩梦

如何在我的主脚本中调用该函数

$arr_RAVM = Test-Computers $arr_RAVM
$RAVM_Process = @(Query-Processes -Computerlist $arr_RAVM.Live)

问题 当函数返回主脚本时,$ RAVM_Process变量具有Get-Process作业的结果,但显然还有一些仍在管道中的Get-Job输出。

在ISE中调试脚本时,我放了两个断点,一个在返回$ arrJob_Results行,另一个在我在主脚本中设置的垃圾变量。 In function variable value

Main script function variable

备注 在主脚本中,$arr_RAVM = Test-Computers $arr_RAVM部分采用我从AD查询的初始计算机名称数组,然后通过我使用的Test-Computers函数运行它们。该函数然后返回一个具有三个数组的对象:$ arr_RAVM.Dead(失败的ping测试),$ arr_RAVM.WinRMFailed(失败的WinRM测试),$ arr_RAVM.Live(可ping的远程可管理的计算机)。所以,如果这些线路上存在混淆,那就是我正在做的事情

我知道Powershell对于返回值可能很棘手,并且return $arrJob_Results行更能告诉函数它可以停止而不是实际只返回该值。所以似乎问题是我没有将函数中的所有输出都捕获到变量中,但我无法弄清楚这是做什么的。我的想法是:While (Get-Job)行正在这样做,所以我尝试用其他方法创建一个循环来处理作业失败。

我尝试过While循环的几个变体,例如 Get-Job | Where-Object {$_.State -eq 'Failed'} | Remove-Job Get-Job | Where-Object {($_.State -eq 'Completed') -and ($_.HasMoreData -eq $True)} | Receive-Job | Foreach-Object {$arrJob_Results += $_} Get-Job | Where-Object {($_.State -eq 'Completed') -and ($_.HasMoreData -eq $False)} | Remove-Job 但仍然收到相同的结果。当我进入函数断点时,如果我执行任何类似“Get-Job”的操作,它将为null。我最初只将While条件设为While (Get-Job),但此处的.Count部分只是尝试随机内容的一部分。

非常感谢任何帮助。这是脚本中的第一个实例,我实际上需要处理后台作业的结果(之前主要用于“看看它是否失败了”),所以似乎有一些关于工作的东西我我不理解我读过的东西。

免责声明:我不是程序员,而是更多来自“Sys / Network Admin,它们一直在黑客攻击更复杂的脚本”方面。我没有正式的编程教育,所以我可能正在做的事情不是一个好习惯,但我的目标是了解我做错了所以我可以改进。

1 个答案:

答案 0 :(得分:1)

您在输出中看到的PSJob个对象可能来自Invoke-Command循环中的foreach

取消Invoke-Command的输出,就像之后使用Remove-Object

一样
Invoke-Command -ComputerName $Computer -AsJob -ScriptBlock { ... } |Out-Null