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

2

4

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 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.

Manama answered 24/5, 2010 at 3:48 Comment(2)
What do you expect this command will produce? try { remove-item nonexisting -ea 0 } catch { 'err occured' } and what if I change -ea to 2? IMHO write-error is not trapped in catch block.Advancement
Thanks for your help stej. Your example worked as I expected, which means the behaviour I mention might be the result of specific calls. I have added a real sample as a separate entry to be more legible than a comment.Manama
A
2

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

Advancement answered 24/5, 2010 at 8:53 Comment(3)
Thanks! You're right, the first two calls seem to do the exact same thing, both regarding error handling and pSake. Regarding modules, workarounds are hard because in a lot of cases the functions belong to internal libraries or third party modules. If you have the option though, your suggestion to rename the module to PS1 and then dot source it worked fine! I wonder if it's a safer choice to always use -File though, so the behaviour is consistent with what you get while developing in the ISE.Manama
As a note, I just found out about this other difference: When using powershell.exe .\script.ps1 or -Command "& script.ps1", the Set-StrictMode commandlet will not catch any syntax errors in the modules you import. When using -File script.ps1 or -Command ". script.ps1", it will catch everything, just like in the ISE.Manama
Yea, Set-StrictMode sets "something", as well as $errorActionPreference = ... It is the same pattern - set something, but it is not used in the module function. Modules are sometimes quite tricky, but in this case I don't know what's going on.Advancement
M
0

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" (i.e. not caught)

Manama answered 24/5, 2010 at 6:57 Comment(1)
It would be better I think to put this in your original Q.Alvarez

© 2022 - 2024 — McMap. All rights reserved.