简体   繁体   中英

PowerShell 2.0 - Running scripts for the command line call vs. from the ISE

After writing deployment scripts from within the ISE, we need our continuous integration (CI) server to be able to run them automatically, ie 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 catch Write-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.

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 :)

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 parameter

    will output "Error occurred" and stop

  • From the command line without the -File parameter

    will output "Failed" followed by "Success" (ie not caught)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM