为什么ScriptBlock中的命令不起作用?

时间:2019-06-06 22:32:07

标签: powershell

我想从cmdlet中测量经过的时间

Invoke-ASCmd

我以下列方式使用它

$elapsedTime = [system.diagnostics.stopwatch]::StartNew()
$j = Start-Job -ScriptBlock {
    Invoke-ASCmd –InputFile $XMLF -Server "$Server[-1]" >$output_file
}
do {
    write-progress -activity "Syncing..." -status "$([string]::Format("Time Elapsed: {0:d2}:{1:d2}:{2:d2}", $elapsedTime.Elapsed.hours, $elapsedTime.Elapsed.minutes, $elapsedTime.Elapsed.seconds))" 
    #-percentcomplete ($_/10);
    Start-Sleep -milliseconds 250
} while ($j.State -eq 'Running')
Receive-Job -Job $j

$elapsedTime.stop()

但是,我在控制台上看到的只是一个闪烁的蓝色进度条,它似乎根本没有浪费时间...而且坦白地说,我什至不认为脚本块根本没有被执行(Invoke cmdlet)

那是为什么?

image

似乎持续了1秒钟

image2

我知道脚本块不起作用,因为同步应该花费至少20秒,所以出了点问题

此外,我想获取百分比(圆圈动画/进度),这不起作用

-percentcomplete ($_/10);

最后一件事,我想将最终经过的时间保存到变量$FinalTime中,我将在循环内还是循环外进行?

我在这里将这两个答案结合在一起,并根据自己的需要进行修改:

https://stackoverflow.com/a/9813370/8397835

https://stackoverflow.com/a/8468024/8397835

1 个答案:

答案 0 :(得分:3)

是的,进度很快,因为在出​​错之前,PowerShell需要1秒钟来加载模块。我们可以通过Receive-Job查看错误消息:

PS C:\> Receive-Job $j
InputFile "" not found
    + CategoryInfo          : InvalidData: (:) [Invoke-ASCmd], FileNotFoundException
    + FullyQualifiedErrorId : DataValidation,Microsoft.AnalysisServices.PowerShell.Cmdlets.ExecuteScriptCommand
    + PSComputerName        : localhost

InputFile "" not found表示变量为空。它们为空,因为您不能直接在脚本块内部引用变量。使用Start-Job,必须将其作为参数传递到脚本块中,并作为参数接收到脚本块中。像这样:

$j = Start-Job -Arg $XMLF, $Server, $output_file -ScriptBlock {
    Param($XMLF, $Server, $output_file)
    Invoke-ASCmd –InputFile $XMLF -Server "$Server" >$output_file
}

关于进度,由于没有“直接”方法来衡量进度达到100%的程度,因此我们“伪造”它。因为我们知道执行大约需要20秒,所以我们只是让进度使用0到20的时间作为0到100的进度来做一些数学运算:

[Math]::Min(100*($elapsedTime.Elapsed.Seconds / 20),100)

基本上在20秒内将$elapsedTime用于0到100%。该20秒可以更改为接近执行时间的任何数字。使用[Math]::Min,我们确保如果花费的时间超过20秒,进度将显示为100%,但状态将继续显示时间。所以看起来像这样:

do {
    write-progress -activity "Syncing..." -status "$($elapsedTime.Elapsed.ToString())" -percentcomplete ([Math]::Min(100*($elapsedTime.Elapsed.Seconds / 20),100));
    Start-Sleep -Milliseconds 250
} while ($j.State -eq 'Running')