'How does one execute a powershell script from another powershell script, with capability to wait and get error codes?
I need to call a powershell script from another powershell script. The powershell script in question, myrobocopy.ps1, is a generalised module, just tuned to our specific needs. I need to call this from another script and get the error code it returns.
Attempts:
I tried it with Invoke-Expression, like this:
$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
}
I think the issue with this is that we can't force the process to wait until myrobocopy.ps1 is finished. Additionally, if I'm honest with you, I don't even think $LASTEXITCODE works here, since Invoke-Expression isn't some global error handling tool. I'm new to Powershell, so yeah, its dumb, just showing my work here.
Next attempt looked like this:
$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
For all I know, this should work, yet when this script runs, it just opens myrobocopy.ps1 in notepad. I've seen some other answers regarding how to associate ps1 files with powershell itself, but I don't believe (could be mistaken here) that is the issue here.
Finally, I read that I need to actually start powershell itself, and then call the ps script. I'm not really sure how to do that, so I tried the following:
$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
This returns the following error: Start-Process : A positional parameter cannot be found that accepts argument 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe'
So yeah I'm slightly lost. I'm sure I just don't know the syntax on how to do it. Help would be greatly appreciated, thank you!
EDIT: Just to add more info, myrobocopy.ps1 accepts 3 string parameters and explicitly returns the $LASTEXITCODE after running robocopy.
ANSWER:
Using the call operator made this work, and you use $LASTEXITCODE to retrieve the exit code.
$robocopy = "C:\testfolder\myrobocopy.ps1"
$source = "C:\testfolder"
$destination = "C:\testdestination"
$filename = "test.bat"
& $robocopy $source $destination $filename
Write-Output $LASTEXITCODE
Solution 1:[1]
If your "C:\testfolder\myrobocopy.ps1" put the result code on the pipeline, the call operator should do the trick:
$result = & "C:\testfolder\myrobocopy.ps1"
Solution 2:[2]
Another way to run robocopy and get the correct exit code would be to use Invoke-Expression with $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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | ExcèsRefusé |
| Solution 2 | DarkLite1 |
