Execute a Powershell script in CMD.EXE from a path with spaces - windows

I have a ps file that I would like to execute from cmd.exe in windows server 2008 from a path with spaces.
I have the ps file in a path with blank spaces, suppose: "C:\My powershell Files"
so from within this path I need below cmd command to work when I execute:
c:\My powershell Files\powershell.exe %CD%\AddValuesRegistry.ps1"
I have powershell v2.0 so I want to it to work on this version.
I have checked below commands but without success:
c:\My powershell Files\powershell.exe -file '%CD%\AddValuesRegistry.ps1'
c:\My powershell Files\powershell.exe -Command "& {& '%CD%\AddValuesRegistry.ps1'}"
Any ideas?

Related

What registry commands allow me to run PowerShell 5 / CMD as admin from the right click context menu from a folder that has an apostrophe in it?

I am trying to set up my right click context menu to launch both CMD and PowerShell5 at the current directory. My PowerShell 7 commands work fine.
This is what I got:
The registry command to open PowerShell5 as Admin is as follows:
PowerShell -Command "Start-Process cmd -ArgumentList '/s,/k,pushd %V && start PowerShell -NoExit && exit' -Verb RunAs"
The registry command to open the Command Prompt as Admin is as follows:
pwsh -noprofile -windowstyle hidden -Command "Start-Process cmd.exe -ArgumentList '/s,/k,pushd,%V' -Verb RunAs"
The registry command I have to open the Node command prompt is this:
cmd.exe /s /k "pushd "%V" & "C:\Program Files\nodejs\nodevars.bat""
(I couldn't figure out how to open the node prompt as admin).
Today, I realized that all of these commands fail if the directory I'm opening to has an apostrophe in the path or folder name. I've tried so many different registry commands and combinations of quotes and escape characters and nothing is working. It's getting enormously frustrating.
Does anyone know of any working commands to open both CMD and PowerShell 5 in directories that have an apostrophe?
Any help at all would be greatly appreciated.
The keys to the solution are:
Launch via cmd.exe and pipe (|) the literal folder path being passed via %V to powershell.exe:
cmd /c <NUL set /p="%V" is a trick that echoes the value of %V without double quotes, even if the value contains cmd.exe metacharacters (it also echoes without a trailing newline, but that is not a problem here).
In the powershell.exe command line being piped to, the folder path can then be referenced indirectly, via the automatic $input variable, which provides access to the stdin (piped) input.
This prevents problems that would arise if %V were embedded directly in the command line, notably with respect to paths containing $ and ` characters.
Also, the PowerShell command can perform string replacement on the value of $env:_dir in order to double embedded ' chars, which allows embedding the value in a verbatim '...' string.
Nested "..." quoting for PowerShell requires intricate escaping using \ as the escape character.
Note: The commands invariably cause creation of a auxiliary, transitory console window, which the PowerShell commands hide as quickly possible and which then auto-closes. This will cause some brief visual disruption.
Avoiding this would require an additional, GUI-subsystem helper executable for launching the command lines without a visible (initial) console window. This extra level of indirection would further complicate quoting and escaping.
Note:
The following commands are designed to be placed verbatim in the registry. Doing so programmatically complicates escaping further.
The commands use powershell.exe, the Windows PowerShell CLI, but they should also work with pwsh.exe, the cross-platform, install-on-demand PowerShell (Core) 7+ CLI; depending on how you installed the latter, you may have to use its full path in the commands below.
You can test-drive the commands as follows:
Replace %V with the literal path of a folder of interest.
Submit via the Windows Run dialog (WinKey-R).
Commands for elevated sessions (run as admin):
A powershell.exe (Windows PowerShell) sesssion:
cmd /c <NUL set /p="%V" | powershell.exe -WindowStyle Hidden -NoProfile -Command "Start-Process -Verb RunAs powershell.exe -ArgumentList ('-NoExit -Command \"Push-Location -LiteralPath ''{0}''\"' -f $input.Replace(\"'\", \"''\"))"
A cmd.exe session:
cmd /c <NUL set /p="%V" | powershell.exe -WindowStyle Hidden -NoProfile -Command "Start-Process -Verb RunAs cmd -ArgumentList \"/k pushd \"\"$input\"\"\""
A cmd.exe session with the Node.js environment set up:
cmd /c <NUL set /p="%V" | powershell.exe -WindowStyle Hidden -NoProfile -Command "Start-Process -Verb RunAs cmd -ArgumentList \"/k pushd \"\"$input\"\" ^& \"\"C:\Program Files\nodejs\nodevars.bat\"\"\""
Note: If you wanted to use environment-variable %ProgramFiles% instead of hard-coding C:\Program Files as part of the Node.js initialization-batch file path for increased robustness, you'd have to define the registry value as REG_EXPAND_SZ.
Running wt.exe (Windows Terminal), as discovered by you, with the notable need to escape ; chars. in the path as \;, because ; is a metacharacter on the wt.exe command line).
cmd /c <NUL set /p="%V" | powershell.exe -WindowStyle Hidden -NoProfile -Command "Start-Process -Verb RunAs wt.exe -ArgumentList (\"-d \"\"{0}\" -f $input.Replace(';','\;'))"
Note: This approach is shell-agnostic. That is, Windows Terminal itself sets the working directory and then runs whatever shell is configured to be its default.
Commands for non-elevated sessions:
The need for nested invocation of PowerShell then falls away, which simplifies the commands.
However, for opening a PowerShell session special considerations apply:
A different approach for passing the folder path verbatim is required: an auxiliary environment variable, _dir is set, which the PowerShell commands can access as $env:_dir.
The visual disruption by an auxiliary, transitory console window, you have two options with the following tradeoffs:
Avoid the disruption, which has the disadvantage that cmd.exe's console-window settings are applied (and that the initial cmd.exe process used to launch the PowerShell session stays alive as the PowerShell process' parent process; they terminate together, however).
Live with the disruption (as is inevitable with elevation), which has the advantage that the usual console settings associated with the PowerShell executable are used.
No visual disruption, but use of cmd.exe's console-window settings even for PowerShell:
A powershell.exe session:
cmd /c title Windows^ PowerShell & pushd "%V" & powershell.exe
A cmd.exe session (append & "C:\Program Files\nodejs\nodevars.bat" for the Node.js initialization):
cmd /k pushd "%V"
Visual disruption, but use of PowerShell's console-window settings:
A powershell.exe session:
cmd /c pushd "%V" & start powershell.exe
Note:
The above will use PowerShell's usual console-window settings, but show the full executable path as the window's title.
While you could change the title with start "Windows PowerShell" powershell.exe, for instance, default settings then apply - you could customize them, however.
An alternative is to change the window title from inside PowerShell (however, the change won't take effect until PowerShell is fully loaded):
cmd /c pushd "%V" & start powershell.exe -NoExit -Command [Console]::Title='Windows PowerShell'
Finally, if you invoke pwsh.exe by its full path and that path contains spaces, you need to double-quote the spaces individually, because double-quoting the path as a whole would cause it to be being mistaken for the window title argument (if you explicitly pass an (of necessity double-quoted) title argument, no extra work is needed); e.g.:
:: Note the individually quoted space (" ")
cmd /c pushd "%V" & start C:\PowerShell" "7\pwsh.exe

How can I set location to current working folder?

I have a powershell script located in "register" folder which I want to use to execute and exe file in "app" subfolder also located in "register" folder dynamically. Each time I run the script I get path not found error but I want the powershell to maintain the current working folder location so that it can work each time I copy to another drive.
Below is the review of my code
"cmd.exe /c PowerShell.exe -windowstyle hidden Start-Process '.\Register\App\record.exe'"
Thanks.
It's not clear where your command is being executed, but I believe the surrounding double quotes are causing everything within to be treated as the executable file name instead of just cmd.exe.
If I open Command Prompt at %UserProfile% and copy %SystemRoot%\system32\calc.exe to %UserProfile%\Register\App\record.exe, then the following work for me:
Command Prompt without surrounding double quotes: cmd.exe /c PowerShell.exe -windowstyle hidden Start-Process '.\Register\App\record.exe'
PowerShell without surrounding double quotes: PowerShell.exe -windowstyle hidden Start-Process '.\Register\App\record.exe'
Both of these...
Command Prompt with surrounding double quotes: "cmd.exe /c PowerShell.exe -windowstyle hidden Start-Process '.\Register\App\record.exe'"
PowerShell with surrounding double quotes: "PowerShell.exe -windowstyle hidden Start-Process '.\Register\App\record.exe'"
...result in...
The system cannot find the path specified.
Also, just in case it's not clear, you are attempting to run cmd.exe to run powershell.exe to run record.exe. At the very least, the cmd.exe /c is unnecessary; just run PowerShell directly.

Using a cmd command in powershell script?

I am trying to make a powershell script that automatically sets up this program and requires to use a cmd command to run do it.
I know that the cmd command work and I tried cmd.exe.
cmd.exe /c "java -jar fitnesse-standalone.jar -p 9090"
Error Message:
cmd.exe : The term 'cmd.exe' is not recognized
You can use start-process
Start-Process -FilePath "cmd.exe" -ArgumentList '/c "java -jar fitnesse-standalone.jar -p 9090"'
The /c and everything following it is just part of the one set of parameters being passed to cmd. If you want powershell to wait for the the Java app to close, add the -wait parameter.
There's also no real need to use CMD at all in this case (since your giving it /c to exit immediately anyway), you can call java directly:
Start-Process -FilePath "java.exe" -ArgumentList '-jar fitnesse-standalone.jar -p 9090'
and it should be the same.
Note: you'll need Java in your path or the current working directory, and fitnesse-standalone.jar in the current directory for either of these to work.

How to start PowerShell script from BAT file with proper Working Directory?

I'm trying to create bat script that can start PowerShell script named the same as bat file in proper working directotry.
This is what I got:
#ECHO OFF
PowerShell.exe -NoProfile -Command "& {Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File ""%~dpn0.ps1""' -WorkingDirectory '%~dp0' -Verb RunAs}"
PAUSE
Passing working directory this way does not work.
How to make script that will pass proper working directroy and also command line arguments?
The -WorkingDirectory parameter doesn't work when using -Verb RunAs. Instead, you have to set the working directory by calling cd within a -Command string.
This is what I use: (cmd/batch-file command)
powershell -command " Start-Process PowerShell -Verb RunAs \""-Command `\""cd '%cd%'; & 'PathToPS1File';`\""\"" "
If you want to make a "Run script as admin" right-click command in Windows Explorer, create a new registry key at HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\Run with PowerShell (Admin)\Command, and set its value to the command above -- except replacing %cd% with %W, and PathToPS1File with %1 (if you want it to execute the right-clicked file).
Result: (Windows Explorer context-menu shell command)
powershell -command " Start-Process PowerShell -Verb RunAs \""-Command `\""cd '%W'; & '%1';`\""\"" "
EDIT: There's an alternative way to have the script be run as admin from Explorer, by using the "runas" sub-key: https://winaero.com/blog/run-as-administrator-context-menu-for-power-shell-ps1-files
If you want to run your script as admin from an existing powershell, remove the outer powershell call, replace %W with $pwd, replace %1 with the ps1 file-path, and replace each \"" with just ".
Note: The \""'s are just escaped quotes, for when calling from the Windows shell/command-line (it's quote-handling is terrible). In this particular case, just \" should also work, but I use the more robust \"" for easier extension.
See here for more info: https://stackoverflow.com/a/31413730/2441655
Result: (PowerShell command)
Start-Process PowerShell -Verb RunAs "-Command `"cd '$pwd'; & 'PathToPS1File';`""
Important note: The commands above are assuming that your computer has already been configured to allow script execution. If that's not the case, you may need to add -ExecutionPolicy Bypass to your powershell flags. (you may also want -NoProfile to avoid running profile scripts)
A workaround is to let the PowerShell script change the directory to it's own origin with:
Set-Location (Split-Path $MyInvocation.MyCommand.Path)
as the first command.
As per mklement0s hint: In PSv3+ use the simpler:
Set-Location -LiteralPath $PSScriptRoot
Or use this directory to open adjacent files.
$MyDir = Split-Path $MyInvocation.MyCommand.Path
$Content = Get-Content (Join-Path $MyDir OtherFile.txt)

Troubles with spaces in file paths powershell via .bat file

set x=%CD%
runas /netonly /user:server_name\test "powershell.exe -NoExit %x%\deploy.ps1 server_name\MSSQL2012 %x%\_RetainALL.xmla
Problem: i need to run PS script as user from server and give arguments in this script. Just simple clicking on one file(.bat actually) for easy deployment ssas solution in server by another IT team.
For this i use runAs command from .bat file. Here some complication: i can't use quotes for evade problem with spaces in file paths in powershell becose i use .bat for runAs(first double quotes will be interpreted as end of runAs.
Also i thought about using Credential instead runAs, but it also have same problem.
runas /netonly /user:server_name\test "cmd /c powershell.exe -NoExit \"%cd%\deploy.ps1\" server_name\MSSQL2012 \"%cd%\_RetainALL.xmla\" "
Escape the quotes in the runas command and run it inside a cmd instance.

Resources