Calling a Powershell script with the "-command" parameter instead of "-file" - powershell

What is the difference between calling a powershell script like this:
powershell.exe -file "myfile.ps1"
and like this (which also works):
powershell.exe -command "myfile.ps1"
thanks, robert

Running powershell.exe -File will return the exit code set by the script, whereas running powershell.exe -Command will return 1 if the script terminated with a non-zero exit code, or 0 otherwise.
C:\>type "C:\path\to\test.ps1"
exit 5
C:\>powershell.exe -command "C:\path\to\test.ps1"
C:\>echo %errorlevel%
1
C:\>powershell.exe -file "C:\path\to\test.ps1"
C:\>echo %errorlevel%
5

powershell.exe -file "myfile.ps1" — that means: start PowerShell and execute file myfile.ps1 (file name considered to be relative to current directory) in global scope.
powershell.exe -command "myfile.ps1" — that means: start PowerShell and execute command myfile.ps1, and PowerShell allows you to execute script files by typing their names in command line.
Differences:
In absence of dot source operator . myfile.ps1 PowerShell create new scope when command resolved to be script file.
PowerShell does not look in current directory as source of commands. So if file myfile.ps1 resides in current directory, and current directory not in PATH environment variable, then PowerShell fail to find myfile.ps1 command.
If file myfile.ps1 can be found in any directory mentioned in PATH environment variable before current directory, then myfile.ps1 command will be resolved to that file rather then to file myfile.ps1 in current directory.
You can create alias in you profile like New-Alias myfile.ps1 DoSomethingElse, and in this case myfile.ps1 command will be considered as reference to that alias rather then to myfile.ps1 file.

Related

How to execute powershell code in current directory from terminal?

I run a powershell command like this
powershell.exe -File C:\GitHub\project\test\run.ps1 "foo bar"
And my current directory is already C:\GitHub\project\test. How can I make the -File argument just start from the current directory?
Thanks
Simply omit the directory path altogether (powershell.exe -File run.ps1 "foo bar") or prefix the script file name with .\ (powershell.exe -File .\run.ps1 "foo bar") in order to run a script located in the current directory.
Note that in cases where you need to use -Command rather than -File, the .\ prefix is required, because PowerShell then treats the CLI arguments as PowerShell code, and for security reasons PowerShell doesn't permit running scripts in the current directory by file name only - see this answer.
See also: about_PowerShell_exe, the documentation of the Windows PowerShell CLI (for PowerShell [Core] v6+, whose executable file name is pwsh, the relevant topic is about_pwsh.)

Attempt to run a PowerShell script from a batch file is failing

The following batch-file is generating the exception:
& : The term '.\Run-Regression.ps1' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again.
At line:1 char:3
+ & '.\Run-Regression.ps1' -InputCSV '..\Desktop\tests\V10MWB.csv' -CAR ...
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (.\Run-Regression.ps1:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
What am I doing wrong? and/or how do I resolve this issue?
I do want to preserve relative paths because powershell has additional dependencies.
#ECHO OFF
:: Enable PowerShell script execution
PowerShell Set-ExecutionPolicy Unrestricted
:: Navigate to the 'Common' directory (preserves relative paths)
PUSHD %~dp0\..\Common
:: Prepare the 'logs' directory
IF NOT EXIST ..\logs (MD ..\logs)
DEL /Q ..\logs\*.log 1>NUL 2>&1
:: Execute script
PowerShell "& 'Run-Regression.ps1' -InputCSV '..\Desktop\tests\%1.csv' -CARS_ID 0 -RunOnDesktop -Log -Email -Progress -Archive 2>&1" 1>"..\logs\%1.log";
:: Navigate back to original directory
POPD
According to the error message, it can't find the script in the current directory as you are invoking it. Either change to the correct directory, or invoke it with the fully-qualified path.
Working with relative paths there can be a misunderstanding with what is a startup folder where your batch file is started.
If your batch and PowerShell scripts located in the same folder and you don't want to care about startup folder, try %~dp0 instruction - it'll point to the folder, where batch file is located.
For example, this will execute Run-Regression.ps1 script located in the same folder with bat\cmd file without taking into account execution policy and startup folder.
PowerShell.exe -ExecutionPolicy Bypass -File %~dp0Run-Regression.ps1
You can find more useful thing in this thread: What does %~dp0 mean, and how does it work?
Your error message does not match the actual invocation command that is part of your batch file:
PowerShell "& 'Run-Regression.ps1' ..." ...
fails, because PowerShell by design does not permit running executables and scripts by mere file name from inside PowerShell (whether invoked directly or via &, the call operator).
Instead, you must prepend .\ to explicitly signal the intent to run a script from the current directory.
PowerShell "& .\Run-Regression.ps1 ..." ...
If your *.ps1 isn't actually in the current directory, but in the batch file's, see Vladimir Dronov's helpful answer
However, consider using the -File CLI parameter instead of the (implied) -Command parameter, in which case the .\ prefix isn't needed and which simplifies the syntax in general:
PowerShell -File Run-Regression.ps1 -InputCSV ..\Desktop\tests\%1.csv -CARS_ID 0 -RunOnDesktop -Log -Email -Progress -Archive 2>&1 1>"..\logs\%1.log";
Note:
There are many subtle differences between using -File and -Command; for more information, see this answer.
PowerShell [Core], whose executable name is pwsh.exe, defaults to -File, not -Command, a change that was needed to support scripts with shebang lines on Unix-like platforms.
Thank you all for your responses, because they helped me bring together the following solution which is working very well for my situation:
PUSHD %~dp0..\Common
...
PowerShell "& '%CD%.\Run-Regression.ps1' ...
POPD
Thanks again,
Allan G.

Call .ps1 from cmd file give the error: : The term '.\setup.ps1' is not recognized as the name of a cmdlet, function, script file

Via VS 2017 calling Setup.cmd which contains:
#echo off
chcp 65001
powershell -ExecutionPolicy Unrestricted .\setup.ps1 "%*"
The file is called, and this error appear:
Active code page: 65001
.\setup.ps1 : The term '.\setup.ps1' is not recognized as the name of a cmdlet,
function, script file, or operable program. Check the spelling of the name, or
if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ .\setup.ps1 -SkipDbInstall:0 -SkipPandoSupportInstall:0 -SkipSearchServiceInstal ...
+ ~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (.\setup.ps1:String) [], Command NotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
setup.ps1 exist in the same level like setup.cmd.
What can be the problem?
Most likely your working directory is not what you think it is. You can verify that by adding a line echo %CD% to the batch file.
To change the working directory to the folder in which the scripts reside add a line cd /d "%~dp0". You also need to remove the quotes from %*, otherwise all arguments to your batch script will be passed as a single string argument to the PowerShell script. And I'd recommend using the parameter -File with powershell.exe, so that you'll get a proper exit code from the PowerShell script (if it returns one).
#echo off
cd /d "%~dp0"
chcp 65001 >nul
powershell.exe -ExecutionPolicy Unrestricted -File .\setup.ps1 %*
If the PowerShell script doesn't care about the working directory you could also run it with the full path instead of changing the directory:
powershell.exe -ExecutionPolicy Unrestricted -File "%~dp0setup.ps1" %*
Sometimes you have to change the directory by yourself:
PowerShell -Command "cd \scripts; .\setup.ps1"
My problem was that windows environment variable was pointing to 2 msbuild file locations on the file system, so when I ran the command msbuild in cmd - the wrong msbuild was called.
Deleting the wrong one and leaving the good one, in the windows environment variable - did the trick!

put a powershell script on path through powershell commands.

I have a powershell script that I want to run from cmd/ps any location by putting it in path.
What is the command that can achieve that ?
I m basically looking for a UNIX equivalent of putting your script in bashrc and thus available from anywhere to run.
echo 'export PATH=$PATH:/path/to/script' >> ~/.bashrc && source ~/.bashrc
In windows you also have the system variable PATH that's used for defining where to locate executables.
You could do the following that should be equivalent assuming you're only using Powershell:
$newPath = "c:\tmp\MyScriptPath";
[Environment]::SetEnvironmentVariable('PATH', "$($env:Path);$newPath", [EnvironmentVariableTarget]::User);
# Update the path variable in your current session; next time it's loaded directly
$env:Path = "$($env:Path);$newPath";
You can then execute your script directly in Powershell with just the name of the script.
However_ : this will not work under cmd because cmd doesn't know how to handle the ps1 script as an executable. Normally one would execute the script from cmd by calling the following:
Powershell.exe -executionpolicy remotesigned -File C:\Tmp\Script.ps1
If this is "unacceptable" for you, the easiest way is to create a bat script along with your ps1 script (same path) and add the following content :
Script.bat (Assuming you have Script.ps1 in the same folder):
#ECHO OFF
PowerShell.exe -Command "& '%~dpn0.ps1'"
PAUSE
This will create the wrapper needed to Invoke Script anywhere in your cmd as batch files can be executed from cmd

Need to call powershell script from batch file

I have a batch file which is in a folder called script. The script folder also contains folder called powershell which has a script called IE-Settings.ps1.
I want to execute the powershell script from the batch file and I am unable to give powershell script path in the command. What I tried is
call %windir%\system32\WindowsPowerShell\v1.0\powershell.exe -File "& '%~dp0IESettings\IE-Settings.ps1'"
But it doesn't recognize the path
call is for running other batch files in a way that they return to the current batch file after they terminate, and per your question the subdirectory name is powershell, not IESettings. Also, when using the parameter -File you just specify the path to the file.
powershell.exe -File "%~dp0powershell\IE-Settings.ps1"
The call operator (&) is used when running PowerShell code via the -Command parameter, e.g.:
powershell.exe -Command "& { Write-Host 'foo' }"