Searched for this, and couldn't seem to find anyone who'd already asked, so here goes.

I'm starting to switch over to IPython as my go-to shell on Windows 7, and I'd like to configure it so that the bang magic (`!cmd`) to pass a command to the system shell uses PowerShell instead of cmd.exe, so that I can take advantage of the enhancements MS has made, but without having to change my `%COMSPEC%` to PowerShell (my company still uses several CMD-based .BATs for automation, and I don't want to break those).

I'll post my questions here at the top, since the answer may not require any of the information below:

1. Am I missing something? Is there a way to use a configuration file in IPython to specify the system command interpreter?
2. If !1, is there a way that I'm missing to launch a child process from within PowerShell with a Machine-scope environment variable that's local to that process?

Investigation/Testing
---------------------

Looking through the IPython code, I see that it's using `os.system()` to send the command to the shell, rather than `subprocess.call()`. That makes things somewhat more complicated, since os.system\* just uses COMSPEC, where with subprocess\*, you can specify the executable to use.

I tried loading PowerShell, setting the `$env:comspec` variable, then starting IPython from within that shell, but even though COMSPEC appears set, even within IPython, it looks like CMD is still being used:

```
[PS] C:\> $env:comspec
C:\Windows\system32\cmd.exe
[PS] C:\> $env:comspec = 'powershell.exe'
[PS] C:\> $env:comspec
powershell.exe
[PS] C:\> & 'C:\Python33\Scripts\ipython3.exe'
Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:03:43) [MSC v.1600 32 bit (Intel)]
Type "copyright", "credits" or "license" for more information.

IPython 1.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: import os; os.getenv('comspec')
Out[1]: 'powershell.exe'

In [2]: !gci
'gci' is not recognized as an internal or external command,
operable program or batch file.

In [3]: os.system('gci')
'gci' is not recognized as an internal or external command,
operable program or batch file.
Out[3]: 1

```

That looks like the locally-modified COMSPEC is being passed to IPython (as a child of the PowerShell process that made the local change), but `os.system` looks to still be using the persistent setting.

I tried something similar, using `[Environment]::SetEnvironmentVariable("ComSpec", 'powershell.exe', [System.EnvironmentVariableTarget]::User)`, in case I could get away with only changing a User-scope environment variable, but that didn't work, either (same results as above - `os.getenv('ComSpec')` shows powershell, but !-ed commands are sent to CMD).

Changing the Machine-scope environment variable seems to do what I want it to, but isn't a valid solution to me, for reasons mentioned before.

```
[PS] C:\> $env:comspec
C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe
[PS] C:\> [Environment]::GetEnvironmentVariable('ComSpec','User')
[PS] C:\> [Environment]::GetEnvironmentVariable('ComSpec','Machine')
C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe
[PS] C:\> & 'C:\Python33\Scripts\ipython3.exe'
Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:03:43) [MSC v.1600 32 bit (Intel)]
Type "copyright", "credits" or "license" for more information.

IPython 1.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: !gci env:ComSpec

Name                           Value
----                           -----
ComSpec                        C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe

```

Since that's not a viable ongoing solution, I tested some more by tinkering with settings in ConEmu\*. I was able to do this without changing the global variable by setting the *Explicit executable* and *Set ComSpec environment variable for child processes to selected value*\* flags in *Settings > Startup > ComSpec*, and providing the path to powershell.exe, but I'm not sure if that will have a negative impact on CMD consoles opened using ConEmu, since that setting is global (within ConEmu). This is what led me to ask Question 2, above, since I'm not sure how to set process/child-local, Machine-scope environment variables in PowerShell (if such a thing is even possible).

In the end, my dream goal would be for IPython to support specification of a command-shell interpreter via a config file, but to do that, `os.system()` can't be what's used. I'm planning to tinker with replacing it with `subprocess.call()` in my local copy (a'la this [Python Doc](http://docs.python.org/3.3/library/subprocess.html#replacing-os-system)) to test, but if anyone's already played with that, or if there's a sufficient advantage to the current model over using `subprocess` that I'm not aware of, I'd be glad to hear of it. It looks like this is already being done for non-Windows systems ([GitHub](https://github.com/ipython/ipython/blob/master/IPython/core/interactiveshell.py#L2236-L2264)), but I'm new enough to Python on this scale that I can't say for certain that nothing else would break if that change were used on the Windows side of the conditional, as well.

Footnote
--------

Gah! Have to have 10+ reputation to properly document questions, apparently. Here are the links that I wasn't allowed to post above:

* os.system - docs.python.org/3.3/library/os.html#os.system
* subprocess - docs.python.org/3.3/library/subprocess.html
* ConEmu - code.google.com/p/conemu-maximus5/