Scriptblock用作Invoke-Command,但不用作Start-Job

时间:2014-08-01 13:36:59

标签: powershell invoke-command start-job

我编写了一个ScriptBlock,用于将文件上传到自定义http服务器并将响应保存到磁盘。它旨在用于测试所述服务器,除了检查正确的响应之外,我还想并行运行它来加载服务器。

ScriptBlock中的代码是作为单独的ps1脚本构建的并且有效。然后我使用Start-Job将其移植到框架脚本中,以管理作业并最终呈现整体结果。

不幸的是,在移植后它不起作用。

症状是使用Start-Job作业永远不会完成。为了测试我已切换到Invoke-Command。一个简单的Invoke-Command有效,InvokeCommand -AsJob没有。

使用:

Invoke-Command -Scriptblock $ScriptBlock -ArgumentList $Name,"C:\Projects\DCA\CCIT\ServiceBroker4\Java\eclipse-workspace\XFAWorker\testdata","P7-T"

不要工作:

Invoke-Command -AsJob -Computer localhost -Scriptblock $ScriptBlock -ArgumentList $Name,"C:\Projects\DCA\CCIT\ServiceBroker4\Java\eclipse-workspace\XFAWorker\testdata","P7-T"
Start-Job -Name $Name -ScriptBlock $Scriptblock -ArgumentList $Name,"C:\Projects\DCA\CCIT\ServiceBroker4\Java\eclipse-workspace\XFAWorker\testdata","P7-T"

使用的ScriptBlock相当长。它首先声明参数:

$Scriptblock = {
    Param (
        [string]$JobName,
        [string]$path,
        [string]$BASEJOBNAME
    )

进一步使用HttpWebRequest和其他一些.NET类:

$url = "http://localhost:8081/fillandflatten"
[System.Net.HttpWebRequest] $req = [System.Net.WebRequest]::create($url)
...
$xfabuffer = [System.IO.File]::ReadAllBytes("$path\$BASEJOBNAME.xml")
...
$header = "--$boundary`r`nContent-Disposition: form-data; name=`"xfa`"; filename=`"xfa`"`r`nContent-Type: text/xml`r`n`r`n"
$buffer = [Text.Encoding]::ascii.getbytes($header)        
...
[System.Net.httpWebResponse] $res = $req.getResponse()

正如使用Start-JobInvoke-Command -AsJob时所描述的那样,启动的子作业将永远保持在Running状态。

什么可能导致这种行为?什么可以用来调试它?如果有一些错误,我可以强制终止子作业并告诉我它不喜欢什么吗?

我在Windows XP上使用PowerShell 2.0。

在我提出的框架中,我做了Start-Job(目前只有其中一个,但我打算提高压力测试的数量)。然后我有一个循环等待它们全部终止:

do {
    $Jobs = @(Get-Job | Where { $_.State -eq "Running" -and $_.Name.StartsWith($BASEJOBNAME) }); 
    $n = $Jobs.Count
    if ($n -gt 0)
    {
        Log -message "Waiting for $n jobs to finish..."    
        Get-Job | Where { $_.Name.StartsWith($BASEJOBNAME) } | Format-Table -AutoSize -Property Id,Name,State,HasMoreData,Location

        start-Sleep -Seconds 3
    }
} until ($n -eq 0) 

这会产生以下形式的输出:

2014-08-01 18:58:52 - Waiting for 1 jobs to finish...

Id Name     State HasMoreData Location
-- ----     ----- ----------- --------
2 XFA001 Running        True localhost

永远。

完整的最小测试用例是:

# Code for the Jobs:
$Scriptblock = {
    [System.Net.HttpWebRequest] $req = [System.Net.WebRequest]::create("http://locahost/index.html")        
    return "done"       
}

# Start a job. Three variants, The Job-based ones hang.

# Invoke-Command -Scriptblock $ScriptBlock
#Invoke-Command -AsJob -Computer localhost -Scriptblock $ScriptBlock
$Job = Start-Job -Name $Name -ScriptBlock $Scriptblock

## The rest of the code is only applicable for the Start-Job-Variant

# Wait for all Jobs to finish
do {
    $Jobs = @(Get-Job | Where { $_.State -eq "Running" }); 
    $n = $Jobs.Count
    if ($n -gt 0)
    {
        Write-Host "Waiting for $n jobs to finish..."    
        Get-Job | Format-Table -AutoSize -Property Id,Name,State,HasMoreData
        Start-Sleep -Seconds 3
    }
} until ($n -eq 0) 

# Get output from all jobs
$Data = ForEach ($Job in (@(Get-Job | Where { $_.Name.StartsWith($BASEJOBNAME) } ))) {  
    Receive-Job $Job
}

# Clean out all jobs
ForEach ($Job in (@(Get-Job | Where { $_.Name.StartsWith($BASEJOBNAME) } ))) {  
    Remove-Job $Job
}

# Dump output
Write-Host "Output data:"
$Data | Format-Table
Write-Host ""

这对我来说很重要。如果我注释掉创建WebRequest对象的那一行就可以了。

谢谢。

1 个答案:

答案 0 :(得分:0)

当您运行Get-Job时,该作业是否已成为" HasMoreData"属性是"真" ?

如果是,请检查作业的输出:

Receive-Job <JobName or JobID> -Keep