Run a PowerShell script and automatically set Unrestricted similar to Bash shell hash bang

Viewed 866

I want to run a PowerShell ps1 script in a command line environment by typing the name of the script and ALWAYS have it run without dealing with run level restrictions and DO NOT want to type powershell. This allows a typical user in a Windows command-line environment to run the script as if it is any other program and not know that PowerShell is involved. I understand that I may not get complete solution in response to my post, but at this point I am trying to solve problems one at a time.

I do not want to change global restriction policy to Unrestricted. I want it to happen temporarily for the script because it is a simple operation, such as listing some files, filtering, etc.

In Linux bash, I might use hash bang like the following, or use the bypass option:

#! powershell -ExecutionPolicy Unrestricted
#
# Is there a start-up option like this that can be put into a `ps1` file? 

However, I am dealing with users that don't have any linux-like environment installed and it should not be a requirement. If Linux (MinGW, Cygwin, Git Bash, etc.) is available, a user can run the bash version of the script, which works great. I'm trying to implement an equivalent Windows solution.

I can also create a cmd file that calls powershell with option like the above, but now I am mixing old command shell programming with PowerShell and have to distribute a cmd and ps1 as part of the solution. It would be great just to move to PowerShell, especially in cases where cmd does not provide what is needed. Being able to implement a solution to run a script either in PowerShell or cmd window would be great... with ONE script.

Someone is probably going to ask me to post code. Let's say I want to do a directory listing and return the first file in the list. A simple script would be equivalent to something like the following, using Windows dir and linux head, but obviously I want a Windows-only solution (and I want to be able to write other PowerShell scripts to do other tasks).

dir /n /b | head -1

Finally, I would love to migrate old bat scripts to ps1, but barriers to easy command line use for non-programmer and non-admin users is a constraint to doing that.

Follow up

I accepted the answer below. I did not ultimately use a PowerShell solution because I found a way to implement in a *.cmd file. Here are my take-aways:

  1. PowerShell is powerful but not very usable by itself to the average user (and those of us supporting those users) due to the execution policy complexities and general confusion around that.
  2. Distributing a .cmd file with the .ps1 file is a possible solution to help start PowerShell with appropriate execution policy and can shield the average user from the policy complexities, but of course this introduces another file to develop and maintain and the PowerShell configuration still needs to work.
  3. Where a Linux environment is available as part of the target system (such as Git Bash, Cygwin, MinGW, Windows Bash), it is easier to write the code as a bash script, especially if admin privileges are not required or are handled by other components (database logins, etc.).
  4. For simple tasks on Windows, if at all possible, figure out how to use a .cmd file. Sorry PowerShell, but I am not (yet) an advocate and will continue to muddle through by building on snippets of *.cmd script code that I have figured out, no matter how ugly or esoteric that code is.
1 Answers

Unfortunately:

  • On Windows, you fundamentally cannot avoid being subject to PowerShell's execution policies.

    • On Unix-like platforms, in the cross-platform, install-on-demand PowerShell (Core) edition, execution policies do not apply.
  • Invoking the PowerShell CLI (powershell.exe for Windows PowerShell, pwsh.exe for PowerShell (Core) 7+) with an -ExecutionPolicy argument can override the effective policy unless it is set via Group Policy.

Assuming your Group Policy doesn't prevent (unsigned) script execution:

  • From within PowerShell, no extra effort is needed: .ps1 files are treated like any other executable by PowerShell and actually execute in-process (you needn't specify the .ps1 extension).

  • If you also need to make .ps1 files executable from outside PowerShell:

    • Create a companion .cmd file alongside each such .ps1 file, with the following content:

      @powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dpn0.ps1" %*
      
Related