How to determine if I'm in powershell or cmd? - powershell

I've been playing with OpenSSH on Windows and it looks like the normal Unix aliases are missing. I'm not sure whether it's starting powershell or cmd when I log in to a Windows machine via SSH. What's the correct way to see the currently running shell on Windows?

All credit goes to PetSerAl, this had to be posted as an aswer:
(dir 2>&1 *`|echo CMD);&<# rem #>echo PowerShell
Within Win32-OpenSSH this command also works, and outputs CMD.
NB : Win32-OpenSSH seems a bit limited, cd is not recognized on my system.

I'd like to expand on #sodawillow's answer to also distinguish between using Powershell (powershell.exe) known as Desktop and PWSH (pwsh.exe) known as Core.
(dir 2>&1 *`|echo CMD);&<# rem #>echo ($PSVersionTable).PSEdition
# Returns one of: CMD, Core, Desktop
This works in all instances where a sub-shell is not instantiated. What that means is that it does not work from opening a default sub-process in Python, as it always uses CMD when interacting with windows. This is actually set by the Windows environment variable: ComSpec always pointing to C:\Windows\system32\cmd.exe.
For example:
(Starting the python interpreter from a pwsh shell.)
>>> import os, subprocess
>>> c="(dir 2>&1 *`|echo CMD);&<# rem #>echo($PSVersionTable).PSEdition"
>>> subprocess.call(c,shell=True)
CMD
For other Python shell detection schemes, please see this good post.
UPDATE: 2020-05-01
I managed to get the above working, but with the obnoxious side effect of always loading the powershell profile, before executing. The trick was to specify execute=<path-to-powershell-exe> like this:
(Start a python CLI.)
import os, subprocess
c="(dir 2>&1 *`|echo CMD);&<# rem #>echo($PSVersionTable).PSEdition"
e="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"
subprocess.call(c, shell=True, executable=e)
# output:
# <blah blah from profile>
# Desktop
# 0
I have not been able to circumvent the powershell profile issue. But apparently it is something being worked on. See here and here.

Related

Why I can run less, grep and find in Windows Powershell?

A friend told me that Windows PowerShell doesn't have these Unix-style commands. Well, I tried and saw that I can in fact run these.
Now I'm wondering why is that. Could it be because I have installed NodeJs on this Windows machine?
If they are not by default usable in Windows PowerShell, is there a way to find out what exactly has brought them into use in this Windows installation?
Running Windows 8.1.
For those that are interested, based on the chosen answer, I found out that installing Git on this machine has brought those commands to use:
PS C:\Users\myusername> where.exe grep
C:\Users\myusername\AppData\Local\Programs\Git\usr\bin\grep.exe
PS C:\Users\myusername> where.exe less
C:\Users\myusername\AppData\Local\Programs\Git\usr\bin\less.exe
You can try this
where.exe find
where.exe less
where.exe grep
They'll return the path to the exe file if those tools exist on your PC. You can always run find because there's find.exe, although it's not Unix find but a tool for searching text. less and grep won't be available by default but if you have Cygwin, MSYS or Gnu32 installed then they'll be ready in path. Git on Windows runs on MSYS so unsurprisingly you can run less, grep or other Unix tools
Note that you need to use where.exe command instead of only where command like on cmd.exe because where on powershell has a different meaning
If you wonder why you can see them, you can run the Get-Command command, which will tell you where the files are being called from (also a great tool to find the underlying VBS scripts which get called when you run commands from time to time)
For instance, the LS command works in PowerShell, but it isn't actually the same binary used in Bash.
_>Get-Command ls
CommandType Name Version Source
----------- ---- ------- ------
Alias ls -> Get-ChildItem
We can see here that in this case, running LS is actually a PowerShell alias which calls the Cmdlet (that is to say, the native PowerShell command) of Get-ChildItem.
If you run this on the other commands you can determine why you see them. Maybe you install cygwin at some point, or installed Python / Ruby (some installers package Bash binaries).

Perl Scripts on Windows 10 run from Explorer but not Command Prompt

I've installed ActiveState Perl on my new Windows 10 PC. I've installed the same exact version of Perl on several of my own PC's, and it's installed on 100's of other users' PC's in my company. Same exact install, created by me.
This is the first time trying this on Windows 10. The basic actions of double-clicking a Perl script (*.pl) in Explorer cause a console window to open and Perl to run the script.
Also, in Windows Command Prompt, I can type perl.exe script.pl, and the script runs fine. But, when I just type script.pl, nothing happens. No output, no errors, no perl.exe processes visible in Task Manager.
The first time I ran a Perl script (from Windows Command Prompt, I believe, using just the script.pl syntax), Windows popped up a window asking me what program I wanted to use to open this file. Perl was the default, and I clicked OK.
I've never seen that window in Windows 7 or 8, so I'm thinking it's something specific to Windows 10, and that it's the thing that's somehow preventing me from just typing script.pl. Because, when launching script.pl, I'm requiring the file associations to pick the right program, but when I type perl.exe script.pl, perl.exe is being launched directly. But, that Windows 10 "pick your default program" thing is getting in the way when running from the command prompt by messing up the file associations.
Not 100% sure why it works from Explorer, though, but I'm pretty sure that I need to clear that default program thing. I removed the registry entry for .pl files under HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts, but that didn't help.
This seems to be a more generic problem with Windows 10, or possibly just my installation of it, or a Group Policy I'm not aware of.
The following commands (run in a Admin command prompt) work fine in Windows 8.1 but not Windows 10:
assoc .foo=Foobar
ftype Foobar=C:\WINDOWS\system32\foo.bat %1
echo #echo off > foo.bat
echo echo The filename is %1 >> foo.bat
echo hi > foo.foo
foo.foo
The result should be the output:
The filename is C:\WINDOWS\system32\foo.foo
But Windows 10 does nothing. It seems to only allow built-in apps to be associated in this manner, and not BAT scripts of downloaded/installed EXEs.
Turns out that Microsoft reversed the polarity of a Registry setting in Windows 10, and this is biting other Perl programmers too. The solutions is to set HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\InheritConsoleHandles to "0".
MSDN post here: https://social.msdn.microsoft.com/Forums/en-US/f19d740d-21c8-4dc2-a9ab-d5c0527e932b/nasty-file-association-regression-bug-in-windows-10-console
Make sure your PATHEXT environment variable has .pl in it.

#!/bin/bash equivalent in windows / specify interpreter for executable script IN the script

I don't really know which part of the described technology stack the behaviour i'm describing is actually a property of - linux, or bash/sh? but it does not really matter i guess.
Anyway, on linux, in a bash or sh shell, i can run a script marked as executable in the file system without specifying the interpreter on the shell or somewhere global, but right in first line of the file,
e.g.
#!/bin/bash
#!/usr/bin/python
or even
#!/usr/bin/gcl -f
for a common lisp implementation.
Is there a general windows, powershell or cmd.exe equivalent to this?Specifically, specifying the interpreter/command line to run the script with in the script itself, rather than on the command line or in the windows registry.
If not, what are similar options? The most similar thing I know about are shortcuts. Is there something more similar?
In Windows the file extension specifies, which programs is used to Interpret a script.
You can also specify the Interpreter like "cmd": CMD /c "c:\temp\script.cmd" or with Powershell: powershell.exe script.ps1
What you can do (in Powershell) is, to specify the Version, which is used to run the script. Use #Requires -version 3.0 in first line and it will throw error on v4 cmdlets etc.

interactive powershell from Cygwin

I cannot run PowerShell.exe interactively in a Cygwin rxvt or mintty terminal. Seems any session using a /dev/tty? or /dev/pts? pseudo terminal device. An instance using the junky windows console device /dev/console or /dev/cons? will work.
cygstart /bin/bash -li
launches the console version in the cruddy Windows Command Prompt which is the only place I can get an interactive PowerShell.
Works. Rxvt doesnt:
Nor does mintty:
I've tried all the echo -e | powershell.exe and powershell.exe </dev/null
I'm assuming when I see answers on Stackoverflow on this they are using Console's ... or am I missing something?
Why I cannot run PowerShell 2 from Cygwin? seems to run fine, just gets powershell v3 when he wants v2 ... wish I had that problem.
I've developed a powershell wrapper to call powershell scripts and commands from a Cygwin terminal session but cannot get the interactive option to work (if you give the wrapper no script or commands then you want to go interactive). see https://bitbucket.org/jbianchi/powershell/wiki/ for info on the wrapper script. It works for most powershell.exe calls and even acts like a "she-bang" if used in the first line of the ps1 script.
Today, typing powershell at a Cygwin bash prompt just works.
If you need to run powershell inside cygwin/babun, follow https://code.google.com/p/mintty/issues/detail?id=56#c64 . Bascilly, downloard or compile https://github.com/rprichard/winpty, copy it to your $PATH and then run
console.exe powershell
This also works with batch scripts that invoke powershell inside.
The solution I've found is to use http://sergeybelous.com/ (main site) Proxy32 proxywinconsole.exe program. If this program is in the path, my poweshell.bash wrapper will call it which will let you work interactively with PowerShell.
First Install cygwin in your system.
After that type bash on powershell terminal and you can access cygwin terminal.
PS C:\Users\username\1and1> bash
username#LWMT-14R25Q2:/mnt/c/Users/username/1and1$
I'm afraid I can't answer your question, but maybe I can help you a little further on your way with this:
I believe this is related to this issue, as discussed on the MinTTY Issue #56.
It goes into great detail as to how common cmd.exe shell applications work and interact, so much as they detail how common unix applications using their TTY abstraction layer work differently than Windows command line applications.
Script for running powershell on Cygwin minty:
blahblah#blahblahbin $ cat pwrshl
#!/usr/bin/bash if [[ ! -f "$1" ]] then
echo "Usage: $0 <PowerShellScriptFile>"
exit fi
echo "\n" | powershell -Command "& {$(<$1)}"

How can I run the regedit.exe from a Perl script on Windows 2008 Server?

I have yet another subtle problem on Windows :(
The following one-line perl script doesn't work:
perl -e "system('regedit.exe /s C:\my.reg');"
It really runs regedit.exe tool (I'm sure since I tried to run it w/o "/s" and saw confirmation dialogs), but it doesn't create a key in the registry.
I tried to run
regedit.exe /s C:\my.reg
in from windows shell (cmd.exe) and it works fine.
The original command works fine on Windows XP, but doesn't work on 2008 server.
So I suspect that this is system-related issue.
Are you executing this with an elevated cmd prompt (i.e. admin privileges)? Regedit requires this.