How to run PowerShell scripts “from Explorer”

This is a popular question because after installation of PowerShell its scripts (.ps1 files) are not associated with PowerShell.exe, as one may expect. I believe there are many good security reasons for this approach. But in my case this is not suitable for many other good reasons. I want to invoke my scripts from Explorer by mouse double clicks, just like I invoke .bat, .cmd, .js, .vbs, .pl and other script files.

I tried quite a few ways of doing this and I am going to describe just one which is in active use for several years. The PowerShell script below should be invoked once to install the association (actually under the covers it calls Cmd to make the job done by FType):


Install-Association.ps1

<#
.SYNOPSIS
    Associates .ps1 files with PowerShell.exe
#>

cmd /c @"
FType Microsoft.PowerShellScript.1=$PSHOME\powershell.exe -NoExit . "'%1'" %*; Exit
"@

Description

Basically the command tells to start PowerShell.exe and invoke a script (%1) by dot-sourcing it (operator .) with optional arguments (%*). But the command line also contains two contradicting exit related instructions: switch -NoExit for PowerShell.exe and instruction Exit for PowerShell. Why?

  • If a script succeeds its console window is closed due to the Exit statement in the end. Of course, scripts with screen output to look at should not be invoked in this way.
  • If a script fails its console window is not closed because of -NoExit switch and not yet executed due to a failure Exit statement.

After a failure one can:

  • Read the output and error messages.
  • Investigate the variables, environment and etc. Note: a script is dot-sourced (invoked by .), that often makes more variables available in the global scope after failures.
  • Fix transient problems and re-run the script in its still opened console with a full set of original parameters simply by typing r immediately or by r 1 after any command invoked.

"'%1'" would be enough for invoking scripts from Explorer. But due to %* the association also works in other scenarios with extra arguments passed in a script. For example in Cmd or Run window it is enough to provide a script path and a few simple (!) arguments, PowerShell.exe can be omitted.


Limitations

  • This approach does not work if a script full path contains '. But I do not really suffer from this limitation because my scripts are never in such paths. As for other scripts, I do not invoke them from Explorer, for mentioned safety reasons, too.
  • %* (extra arguments) does not work (directly) with not trivial arguments with spaces and $ or ` symbols. For such scenarios there is yet another approach with -File parameter of PowerShell.exe. But an association command with -File does not provide described above flexibility of exit.

Disclaimer

If you use this then responsibility is all yours. Do not invoke unknown or not trivial scripts via association, results may be unwanted. But in trivial cases the described approach really helps to save seconds here and there.


Advertisements
  1. #1 by Andrea Endrizzi on June 19, 2015 - 7:00 am

    You save me the day, Thanks !

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: