Difference between running command in PS shell and CMD shell - powershell

I don't use powershell often, so this may be an obvious question but my google-fu is failing me.
What is the difference between running the following commands, on a Windows platform?
In cmd prompt:
C:\> powershell cd d:\foo
and in powershell prompt:
PS C:\> cd d:\foo
The latter changes drive and directory as expected. The former does nothing.

Basically, when you run powershell cd d:\foo it opens a separate Powershell and runs the cd command. As opposed to the second one, you are actually in the Powershell session. So it, the first one, does open a Powershell process > change the directory and then it closes the process.

Related

Executing scripts is the same as dot sourcing?

I saw some surprising behavior in powershell recently.
Consider the script c:\scripts\tst1.ps:
Set-location c:\
Now from powershell:
C:\scripts PS> .\tst1.ps1
C:\ PS>
Why does the calling shell change to “C:\” according to “set-location”? shouldnt the “set-location” run from a subshell according to normal scripting rules for other shells like bash?
I thought that you had to “dot source” the script to get this type of behavior??? That is: “. .\tst1.ps1”? What is happening here.
is my powershell misconfigured on my host computer or is this the actual behavior of powershell these days?
Is there a way to reconfigure powershell to get the old behavior that I expect that is similar to bash shell where the script runs in a sub shell and exits and the current directory is uneffected?
You can run your script with the new instance of powershell:
C:\scripts PS> powershell .\tst1.ps1

Executing two commands one after another in the same powershell session

For context, I’m trying to activate a virtual environment, and then run my python script from within that venv, all in one powershell session. I’m doing this in a .bat file that I will later start as a service (The whole point of this is to run main.py in the venv as a windows service)
I tried this:
powershell -noexit -file C:\MyPythonProject\venv\Scripts\Activate.ps1; python C:\MyPythonProject\main.py
This doesn’t seem to work. Only the first command (to activate the venv) works. What am I doing wrong?
use & to chain commands:
powershell -noexit -file C:\MyPythonProject\venv\Scripts\Activate.ps1 & python C:\MyPythonProject\main.py
https://superuser.com/questions/1079403/how-to-run-multiple-commands-one-after-another-in-cmd/1079420

How To Use A Windows Environment Variable Independent Of Shell?

I have a need within a .bat file to change to a certain directory which is referenced by an environment variable. Something along these lines:
cd %TMP%
And this works fine from Windows CMD shell. However if I try to run the bat within a Powershell terminal window, it appears that the command simply doesn't work. This does though:
cd $Env:TMP
So I'm trying to figure out how to keep things to one .bat file but still allow users to run it under both the CMD prompt and the PS prompt. I can think of some hacky ways to check to see if I'm under CMD (as opposed to PS) but I'd like to know if there's a better solution.
One thing I noticed is that the PROMPT environment variable is present with CMD but not with Powershell but, as I say, that seems a bit hacky and potentially error-prone.
I'm not trying to pad my rep so if this has already been asked and answered, please point me to it. I just want to find something less hacky than trying to figure out which shell the bat is being run in and changing the cd command to suit it.
By the way, since it may make a difference, I'm running under Powershell 4. I could probably use a .cmd file if that would make any difference but I'd be surprised if it did.
EDIT:
I guess maybe I wasn't as clear as I could be. I'm trying to figure out if there's a way to get the value of an environment variable that will work within a .bat file that will work regardless of whether or not the .bat file is run under the cmd shell or the powershell shell.
Running batch files from PowerShell works just fine. However, since the batch files run in a different interpreter (running .\your.bat is basically the same as running cmd /c .\your.bat), changing the working directory via cd %TMP% in the (CMD) child process doesn't change the working directory for the (PowerShell) parent process.
The syntax you use for variables in batch files is always %variable%.
Demonstration:
PS C:\> $PWD.Path
C:\
PS C:\> Get-Content .\test.bat
#echo off
echo before: %CD%
cd %TMP%
echo after: %CD%
PS C:\> .\test.bat
before: C:\
after: C:\Users\me\AppData\Local\Temp
PS C:\> $PWD.Path
C:\
The batch file echoes the path of the current working directory (%CD%) before and after changing the working directory to %TMP%. The working directory of the parent process (PowerShell) remains unchanged ($PWD.Path).

Running CMD command in PowerShell

I am having a bunch of issues with getting a PowerShell command to run. All it is doing is running a command that would be run in a CMD prompt window.
Here is the command:
"C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\i386\CmRcViewer.exe" PCNAME
I have tried the following with no success (I have tried many iterations of this to try and get one that works. Syntax is probably all screwed up):
$TEXT = $textbox.Text #$textbox is where the user enters the PC name.
$CMDCOMMAND = "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\i386\CmRcViewer.exe"
Start-Process '"$CMDCOMMAND" $TEXT'
#iex -Command ('"C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\i386\CmRcViewer.exe"' $TEXT)
The command will just open SCCM remote connection window to the computer the user specifies in the text box.
Try this:
& "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\i386\CmRcViewer.exe" PCNAME
To PowerShell a string "..." is just a string and PowerShell evaluates it by echoing it to the screen. To get PowerShell to execute the command whose name is in a string, you use the call operator &.
To run or convert batch files externally from PowerShell (particularly if you wish to sign all your scheduled task scripts with a certificate) I simply create a PowerShell script, e.g. deletefolders.ps1.
Input the following into the script:
cmd.exe /c "rd /s /q C:\#TEMP\test1"
cmd.exe /c "rd /s /q C:\#TEMP\test2"
cmd.exe /c "rd /s /q C:\#TEMP\test3"
*Each command needs to be put on a new line calling cmd.exe again.
This script can now be signed and run from PowerShell outputting the commands to command prompt / cmd directly.
It is a much safer way than running batch files!
One solution would be to pipe your command from PowerShell to CMD. Running the following command will pipe the notepad.exe command over to CMD, which will then open the Notepad application.
PS C:\> "notepad.exe" | cmd
Once the command has run in CMD, you will be returned to a PowerShell prompt, and can continue running your PowerShell script.
Edits
CMD's Startup Message is Shown
As mklement0 points out, this method shows CMD's startup message. If you were to copy the output using the method above into another terminal, the startup message will be copied along with it.
For those who may need this info:
I figured out that you can pretty much run a command that's in your PATH from a PS script, and it should work.
Sometimes you may have to pre-launch this command with cmd.exe /c
Examples
Calling git from a PS script
I had to repackage a git client wrapped in Chocolatey (for those who may not know, it's a package manager for Windows) which massively uses PS scripts.
I found out that, once git is in the PATH, commands like
$ca_bundle = git config --get http.sslCAInfo
will store the location of git crt file in $ca_bundle variable.
Looking for an App
Another example that is a combination of the present SO post and this SO post is the use of where command
$java_exe = cmd.exe /c where java
will store the location of java.exe file in $java_exe variable.
You must use the Invoke-Command cmdlet to launch this external program. Normally it works without an effort.
If you need more than one command you should use the Invoke-Expression cmdlet with the -scriptblock option.

VB equivalent to powershell

I am very new to powershell and sometimes this question may be so simple
Can please anybody please tell me what is the equivalent to the following(vbscript) in PowerShell
set obj = wscript.createobject( wscript.shell )
Obj.Run $smCmnd
What is the use of wscript.shell.
After a bit of search I found first line can be presented as;
$obj = New-Object -ComObject WScript.Shell
But have have no idea how to call Run method ($obj.run(...)???)
If I run cmd.exe with some commands as the smCmnd, How can I keep cmd.exe without close and to run another command later in same console??
EDIT
I am writing PS script and it will be call from another application. Basically it will do some folder creations and file coping etc. I would like to open CMD.exe and show all the commands running on that. How to use same cmd prompt through out my whole script.
Is smCmnd a string of shell commands? If so, you can call them directly from PowerShell, without trying to get a wscript.shell COM object to run them against like you'd need to do in VBScript.
VBScript wasn't a shell. Powershell is. You can write shell commands directly in .ps1 or .ps2 files, just like in a batch file.
I'm not a powershell expert here, but try doing
& $smCmnd
Try running $smCmnd directly. If that fails, use Invoke-Expression $smCmnd.
If you do need to use CMD.EXE (possibly because you want to run pre-existing BAT file), and you want all of the output in a single CMD window you can pipe all the input into cmd at once like this:
# Powershell script to execute existing BAT file
cmd.exe /k "cd c:\batchfiles & firstone.bat & second.bat & echo that's all folks"
# CMD will remain open (/k). User will have to type exit to return to powershell
# Or if you want user just to hit any key to leave CMD prompt:
cmd.exe /c "c:\batchfiles\mybatchfile.bat & pause"
# /C means CMD should close after is has executed the commands on the command line
However if you want to have something execute in CMD, then make a decision in your Powershell script about what to execute next in CMD then do something similar to the answer at the following link which pipes input and output between a powershell script and CMD.exe.
How to run interactive commands in another application window from powershell