微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我可以传递一个函数并在 PSJobs 脚本块中调用它,然后接收返回值吗?

如何解决我可以传递一个函数并在 PSJobs 脚本块中调用它,然后接收返回值吗?

当我运行 get-job | receive-job -keep 我没有得到任何结果,也无法验证我的函数是否通过并正常工作。我可以将这样的函数传递给 psjob 吗?之后如何捕获返回值?

$servers = @("xxxx","xxxx")
$jobs = New-Object System.Collections.ArrayList;
foreach ($server in $servers)
{
    $jobName = $server + "_job";
    $scriptBlock = 
    {
    
        param($server)
        param($portNumber)
        
        Function testPort ($server,$portNumber)
        {
            $testPort = New-Object System.Net.sockets.TCPClient # -ArgumentList $server,3389;
            $testPort.SendTimeout = 3;
            try
            {
                $testPort.Connect($server,3389);
            }
            catch
            {
                #do nothing;
            }
            $result = $testPort.Connected;
            $testPort.Close();
                    
            return $result;
        }
    
        testPort -server $server -portNumber 3389; sleep 10;    
    }
    $portNumber = "3389";
    
    #Start-Job -Name $jobName -ScriptBlock {$scriptBlock} -ArgumentList $server,$portNumber;

    $jobs.Add((Start-Job -Name $jobName -ScriptBlock {$scriptBlock} -ArgumentList $server,$portNumber | Out-Null));

}

$jobsReturnValues = New-Object System.Collections.ArrayList;
foreach ($job in $jobs)
{
    $jobsReturnValues.Add(($job | Wait-Job | Receive-Job | Out-Null));
}

解决方法

如果您转到 docs,您会看到有一系列可用于 Jobs 的 cmdlet。

$job = Start-Job...

$data = $job | Wait-Job | Receive-Job

Wait-Job 等待作业,直到它不处于 Running 状态。

Receive-Job 返回作业的输出。

更新

在您更新代码后,我可以说以下内容:

Start-Job -Name $jobName -ScriptBlock {$scriptBlock} -ArgumentList $server,$portNumber | Out-Null

为什么要将其通过管道传输到 Out-Null?这会使 Start-Job 的输出消失,并且您仅将空值附加到 $job 中。将管道移入 Out-NullStart-Job 返回一个 System.Management.Automation.PSRemotingJob 对象,您需要它以便稍后引用它。

此外,您在这里也做同样的事情:$job | Wait-Job | Receive-Job | Out-Null。这会使作业的输出消失。

Start-Job -Name $jobName -ScriptBlock {$scriptBlock}

必须

Start-Job -Name $jobName -ScriptBlock $scriptBlock

基本上,您使用第一种方法将脚本块放入脚本块中。

我认为你应该先用一些基本的例子进行测试,直到你掌握工作的工作原理。

,

代码几乎没问题,您没有太多错误。主要问题是 Out-Null 的使用,{ } 上的 -ScriptBlock {$scriptBlock}param( ) 块在您的函数中定义了 2 次。我也对你的功能做了一些修改:)

$servers = @('google.com','twitter.com')
$jobs = New-Object System.Collections.ArrayList;
$testPort = 80

foreach ($server in $servers)
{
    $jobName = $server + "_job";
    $scriptBlock = {
        param(
            [string]$server,[int]$portNumber
        )
        
        Function testPort ($server,$portNumber)
        {
            $testPort = New-Object System.Net.Sockets.TCPClient # -ArgumentList $server,3389;
            $testPort.SendTimeout = 3;
            try
            {
                $testPort.Connect($server,$portNumber);
            }
            catch
            {
                #do nothing;
            }
            
            $result = $testPort.Connected;
            $testPort.Close();
                    
            [pscustomobject]@{
                ServerName = $server
                Port = $portNumber
                TestConnection = $result
            }
        }

        testPort -server $server -portNumber $portNumber
    }

    $jobs.Add((Start-Job -Name $jobName -ScriptBlock $scriptBlock -ArgumentList $server,$testPort)) > $null;

}

$jobsReturnValues = New-Object System.Collections.ArrayList;
foreach ($job in $jobs)
{
    $jobsReturnValues.Add(($job | Receive-Job -Wait -AutoRemoveJob)) > $null;
}

看起来像这样:

PS C:\> $jobsReturnValues|select * -ExcludeProperty RunspaceID|ft

ServerName  Port TestConnection
----------  ---- --------------
google.com    80           True
twitter.com   80           True

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。