问题
After writing deployment scripts from within the ISE, we need our continuous integration (CI) server to be able to run them automatically, i.e. from the command line or via a batch file.
I have noticed some significant differences between the following calls:
powershell.exe -File Script.ps1
powershell.exe -Command "& '.\Script.ps1'"
powershell.exe .\Script.ps1
Some simple examples:
- When using
-File
, errors are handled in the exact same way as the ISE. - The other two calls seem to ignore the
$ErrorActionPreference
variable, and do not catchWrite-Error
in try/catch blocks.
When using pSake:
- The last two calls work perfectly
- Using the ISE or the
-File
parameter will fail with the following error:
The variable '$script:context' cannot be retrieved because it has not been set
What are the implications of each syntax, and why they are behaving differently? I would ideally like to find a syntax that works all the time and behaves like the ISE.
回答1:
Not an answer, just a note.
I searched for explanation of -file
parameter. Most sources say only "Execute a script file.". At http://technet.microsoft.com/en-us/library/dd315276.aspx I read
Runs the specified script in the local scope ("dot-sourced"), so that the functions
and variables that the script creates are available in the current session. Enter
the script file path and any parameters.
After that I tried to call this:
powershell -command ". c:\temp\aa\script.ps1"
powershell -file c:\temp\aa\script.ps1
powershell -command "& c:\temp\aa\script.ps1"
Note that first two stop after Get-Foo
, but the last one doesn't.
The problem I describe above is related to modules -- if you define Get-Foo
inside script.ps1, all the 3 calls I described stop after call to Get-Foo
.
Just try to define it inside the script.ps1 or dotsource the file with Get-Foo
and check it. There is a chance it will work :)
回答2:
Here is a concrete example of the behaviour I described.
MyModule.psm1
function Get-Foo
{
Write-Error 'Failed'
}
Script.ps1
$ErrorActionPreference = 'Stop'
$currentFolder = (Split-Path $MyInvocation.MyCommand.Path)
Import-Module $currentFolder\MyModule.psm1
try
{
Get-Foo
Write-Host "Success"
}
catch
{
"Error occurred"
}
Running Script.ps1:
From the ISE, or with the
-File
parameterwill output "Error occurred" and stop
From the command line without the
-File
parameterwill output "Failed" followed by "Success" (i.e. not caught)
来源:https://stackoverflow.com/questions/2894641/powershell-2-0-running-scripts-for-the-command-line-call-vs-from-the-ise