【问题标题】:How does one execute a powershell script from another powershell script, with capability to wait and get error codes?如何从另一个 powershell 脚本执行 powershell 脚本,并具有等待和获取错误代码的能力?
【发布时间】:2022-04-13 15:15:02
【问题描述】:

我需要从另一个 powershell 脚本调用一个 powershell 脚本。有问题的 powershell 脚本 myrobocopy.ps1 是一个通用模块,只是针对我们的特定需求进行了调整。我需要从另一个脚本调用它并获取它返回的错误代码。

尝试:

我用 Invoke-Expression 试过了,像这样:

$source = "C:/sourcefolder"
$destination = "C:/destinationfolder"
$filename = "filename /LOG+:log.txt"
$arguments = "-source $source -destination $destination -file $filename"
$robocopyscript = "myrobocopy.ps1"
Invoke-Expression "$robocopyscript $arguments"
    if ($LASTEXITCODE -ne 1){
        $problems = 1
    }

我认为问题在于我们不能强制进程等到 myrobocopy.ps1 完成。另外,老实说,我什至认为 $LASTEXITCODE 在这里不起作用,因为 Invoke-Expression 不是一些全局错误处理工具。我是 Powershell 的新手,所以是的,它很愚蠢,只是在这里展示我的工作。

下一次尝试如下所示:

$robocopy = "C:\testfolder\myrobocopy.ps1"
$source = "C:\testfolder"
$destination = "C:\testdestination"
$filename = "test.bat"
$arguments = "-source $source -destination $destination -file $filename"
$p = Start-Process $robocopy $arguments -Passthru -Wait
$code = $p.ExitCode

据我所知,这应该可以,但是当这个脚本运行时,它只是在记事本中打开 myrobocopy.ps1。我已经看到了一些关于如何将 ps1 文件与 powershell 本身相关联的其他答案,但我不相信(这里可能会误会)这是这里的问题。

最后,我读到我需要实际启动 powershell 本身,然后调用 ps 脚本。我不太确定该怎么做,所以我尝试了以下方法:

$robocopy = "C:\testfolder\myrobocopy.ps1"
$source = "C:\testfolder"
$destination = "C:\testdestination"
$filename = "test.bat"
$arguments = "-source $source -destination $destination -file $filename"
$p = Start-Process "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -File $robocopy -ArgumentList $arguments -PassThru -Wait
$code = $p.ExitCode

这会返回以下错误:Start-Process : A positional parameter cannot be found that accept argument 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe'

所以是的,我有点迷路了。我确定我只是不知道如何做到这一点的语法。非常感谢您的帮助,谢谢!

编辑:只是为了添加更多信息,myrobocopy.ps1 接受 3 个字符串参数,并在运行 robocopy 后显式返回 $LASTEXITCODE。

回答:

使用调用运算符完成了这项工作,您使用 $LASTEXITCODE 检索退出代码。

$robocopy = "C:\testfolder\myrobocopy.ps1"
$source = "C:\testfolder"
$destination = "C:\testdestination"
$filename = "test.bat"
& $robocopy $source $destination $filename
Write-Output $LASTEXITCODE

【问题讨论】:

  • 脚本通常没有退出代码 - 二进制文件有。 myrobocopy.ps1 运行 robocopy 后是否返回 $LASTEXITCODE
  • @MathiasR.Jessen 是的。我将更新我的原始帖子以反映这一点。感谢您帮助使我的问题更清楚。

标签: powershell


【解决方案1】:

如果您的 "C:\testfolder\myrobocopy.ps1" 将结果代码放在管道上,调用运算符应该可以解决问题:

$result = & "C:\testfolder\myrobocopy.ps1"

【讨论】:

  • 这就是我所做的。现在添加问题的完整答案。
【解决方案2】:

运行 robocopy 并获得正确退出代码的另一种方法是将 Invoke-Expression$global:LASTEXITCODE 一起使用:

Function Start-Robocopy {
    Param (
        [Parameter(Mandatory)]
        [String]$Source,
        [Parameter(Mandatory)]
        [String]$Destination,
        [Parameter(Mandatory)]
        [String]$Switches,
        [String]$File
    )

    Try {
        $result = [PSCustomObject]@{
            Source         = $Source
            Destination    = $Destination
            File           = $File
            Switches       = $Switches
            RobocopyOutput = $null
            ExitCode       = $null
            Error          = $null
        }
        
        $global:LASTEXITCODE = 0 # required to get the correct exit code
        
        $expression = [String]::Format(
            'ROBOCOPY "{0}" "{1}" {2} {3}', 
            $Source, $Destination, $File, $Switches
        )
        $result.RobocopyOutput = Invoke-Expression $expression
        $result.ExitCode = $LASTEXITCODE
    }
    Catch {
        $result.Error = $_
    }
    Finally {
        $result
    }
}

$startParams = @{
    Source      = '\\contoso\FolderA'
    Destination = '\\contoso\FolderA' 
    Switches    = '/MIR /Z /R:3 /W:10 /NP /MT:16'
}
Start-Robocopy @startParams

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-07
    • 1970-01-01
    • 2021-10-10
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-06
    相关资源
    最近更新 更多