How can I change directory directly from the windows run prompt? - windows

How can I change the current directory from the the windows run prompt when we initialize powershell as powershell. For eg: powershell --someArgs

You can use Set-Location or Cd
Powershell.exe -noexit -Command "CD 'C:\Test\'"
Powershell.exe -noexit -Command "Set-Location 'C:\Test\'"

Launch cmd.exe and use the builtin start command's /d flag to launch powershell.exe with a specific working directory:
cmd /c start /d "C:\working\directory\goes\here" powershell.exe
This will set the working directory of the powershell.exe process to C:\working\directory\goes\here, in turn causing PowerShell's $PWD to change to that directory

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

Elevate rights in current directory with PowerShell

For example I'm in C:\Users\User\Desktop\Tools and I'm trying to stay here as admin.
I tried this way, gluing together different commands:
"C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe -noexit" & -windowstyle hidden -Command Start-Process powershell -ArgumentList '-NoExit', '-Command cd %V' -Verb runAs""
The PATH changes to C:\WINDOWS\system32 why? How to elevate rights in current directory via simple command?
Use $PWD from the calling process to change the location on startup:
Start-Process powershell -ArgumentList '-NoExit', "-Command cd '$pwd'; & .\actual\script\you\want\to\run.ps1" -Verb runAs

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)

Wrapping a PowerShell Program in a Batch File and Using "Set-Location" Returns Root

The following code worked perfectly-
$ScriptLocation = Get-Location
Set-Location "$ScriptLocation"
...until I created a batch file to kick the script off. I understand that by opening the script via the batch file the location will be the root directory.
My question is, how can I set the current directory to the directory where the script is when launching the script from a batch file?
My batch file has the following code-
#ECHO OFF
SET ScriptDirectory=%~dp0
SET ScriptPath=%ScriptDirectory%FilePush_V0.1.ps1
PowerShell -NoProfile -ExecutionPolicy Unrestricted -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Unrestricted -File ""%ScriptPath%""' -Verb RunAs}";
set-Location $PSScriptRoot
cd..
See the following for your version of powershell.
whats-the-best-way-to-determine-the-location-of-the-current-powershell-script

Resources