如何解决我可以传递一个函数并在 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-Null
。 Start-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 举报,一经查实,本站将立刻删除。