Repository: microsoft/terminal (language: cpp)

Issue:
[Question] Configuring Windows Terminal profile to always launch elevated
Hi! Is there a way to configure a profile so that the `commandLine` it launches always starts with elevated (admin) permissions? 

Currently, you can launch the entire application as Administrator, but then every single `commandLine` runs as Administrator, which is not ideal.


Discussion / hints:
There is not. I don't think we plan on supporting mixed elevated and unelevated tabs, because it's a bit of a security hole. 

Yes I know `sudo` is a thing, but we've had lots of discussions with the security team about the creation of a `sudo` for Windows. The main problem is due to the fact that any unelevated processes can send keystrokes to any other unelevated windows.

If you had an elevated commandline running in an unelevated window, an untrusted bad actor could execute an elevation-of-privilege attack by driving the unelevated windows that's running the elevated commandline. 

(as a matter of linking related threads, #146)

<hr>

EDIT (Feb 14 2020)
Okay, so this comment didn't age super well. Originally, there was _no_ plan to support this, since it wouldn't work with the single `HWND` we had. We're working on designing a solution that _might_ support this in the future, but we can't commit to anything until we're sure that we can come up with an appropriately secure solution, that ensures that a lower privileged process can't drive a higher privilege terminal. 
Seems reasonable. I think having something like a combination of #576 (Open as Admin in the jump list), and maybe some kind of hotkey to launch an Admin session of the Terminal would solve most of my pain here.
What about having a standard and elevated Terminal open in a single window but separate tabs?
@mdtauk I think that unfortunately falls under the same category. Since all the tabs are under the same HWND, the root HWND is what would need to be elevated to prevent non-elevated apps from driving the window.
From a security standpoint (ignoring Windows Terminal's design, single root HWND etc.), how "less secure" is Terminal running mixed-elevation tabs compared to running, say, one elevated PowerShell instance next to one non-elevated one in the current UX? The fact the console apps are hosted in Terminal tabs doesn't make a difference to me...
On a similar note: How is having a non-elevated window more secure even if I open a remote PS session where I may now have admin privileges on a remote server that a non-elevated could now drive. For me this seems much worse than gaining local admin access, so I don't think that running a tab as admin is any different than remoting / ssh-ing into other servers. In both cases, I need to feel comfortable enough with my system to do it. It's an "I'm old enough and I understand the risks" thing.
Whenever I try to run the Terminal app with an administrator account, right click -> run as administrator, the UAC pops up twice and an error occurs saying:
"Windows cannot find (path\WindowsTerminal.exe) Make sure you typed ...".

The path exists and the app works correctly for the non admin user that built the app, but the other administrator user is unable to run it.
If I login to the admin user the terminal app is not present in either the settings or the start menu, as if it was never installed on the system.

Is there a way to build the app so that it installs for all users? Or does the root of the project have to be on a non user specific directory?
@

> Whenever I try to run the Terminal app with an administrator account, right click -> run as administrator, the UAC pops up twice and an error occurs saying:
> "Windows cannot find (path\WindowsTerminal.exe) Make sure you typed ...".
> 
> The path exists and the app works correctly for the non admin user that built the app, but the other administrator user is unable to run it.
> If I login to the admin user the terminal app is not present in either the settings or the start menu, as if it was never installed on the system.
> 
> Is there a way to build the app so that it installs for all users? Or does the root of the project have to be on a non user specific directory?

I'm seeing the same issue happening also. 

Windows version 18922.1000




Right, so running store apps as admin or different user is not working (by design BTW). Many of us are logged in (to PC) as a normal non-elevated account. We run powershell/cmd/etc as an admin to do certain tasks.

If the final choice is to deploy this app is the Windows store, it is useless to me without some way to open elevated tabs. My 2 cents.
"Useless" is maybe a bit harsh, but indeed we **do** need a way to use the new terminal **both** for non-elevated and for elevated console apps / shells. And for me the best UX would be to support a mix of elevated and non-elevated tabs in the same Windows Terminal instance. Less preferable: support zero to many (typically one) elevated instances (each with one to many tabs) alongside zero to many (typically one) non-elevated instances.
ConEmu is able to mix elevated and non-elevated tabs in the same window. Can't something like that be done here?
Could we have an elevated Terminal launch non-elevated tabs? I still need to launch elevated BUT I can open a new tab that's "protected".
If we want to go very Windows-specific and ignore other platforms that may eventually see Terminal, perhaps usage of Windows Containers or virtualized processes could help this pain point for some. I personally am just fine with current solution but getting console apps to run as a isolated processes by default wouldn't be such as bad idea from security point of view.
Mixed elevation in one window is a must, for me at least.
Could it be an optional feature to be toggled in settings?
@pratnala With ConEmu it only _looks_ like it's doing that, but it's not really doing that at all. The elevated and unelevated "tabs" are just views into two completely separate, isolated root windows/processes. It does this by scraping the windows' contents among other things and proxy/broker elevation helpers etc . Sure, it's technically possible, but what ConEmu does is actually kinda unsafe. It's one thing for a third party program to do this and have people opt into the risk by downloading ConEmu, but quite another for Microsoft to officially endorse this by doing this itself. If I want to hide my front door keys under the doormat, then fine - that's my dumb risk to take. But what if every door you bought put a set of keys under the doormat? 
But see, I develop in C++ (and C#, PowerShell, Ruby, Python, GoLang, pretty much anything that comes my way.)  I have ConEmu and TakeCommand installed, along with mingw.  I know which way to hold the scissors while I run.

PowerShell _is_ a security hole.  A very useful automation tool, allowing all sorts of unexpected access.   And what we're asking for (mixed modes) is certainly safer than the alternative (all elevated.)  Really this (terminal) is a power tool for power users, most of whom probably understand the security landscape extremely well... and understand pragmatic compromise.

Zero-trust only works when it's not debilitating.  
@robomac If we could convince the security team (who has told us on multiple occasions to not even venture remotely close to mixed elevation) that only people who know how to hold their scissors the right way and not run with them would _use_ this project, we'd probably do it. I don't know if I believe it myself. Here's why:

Like as not, if Terminal is running in mixed elevation (from a Medium-IL host to a High-IL client), it can still be forced to receive input by anything else running as that user. Even if the person behind the keyboard is a saint and only elevates for the ten seconds she needs to elevate for, _any application running under her user account can impersonate the administrator without an additional elevation prompt_. Likely entirely undetected, even.
@DHowett-MSFT I thank you for responding.  You make an assumption that we are allowing malicious processes running anyhow.  We restrict permissions out of "Best Practices" mantras we do with our downward-facing-dog pose every morning, but if you really have a concern that a few hours, even, of elevated terminal access puts you at risk _on your own system that you're developing on_ ...

1. You shouldn't be running Terminal and
2. You should wipe and start over.

I'll grant you that a (computer) virus researcher shouldn't risk this in a vector path... but even early on we were sandboxing them in VMs.   But "Terminal" isn't for your unsavvy relatives; it's a power tool.

There is a standard way of dealing with the risk.  Brought to you by the browser world.  When you go to the advanced flags, you receive a warning of, roughly, "Here be dragons".  (I think it's precisely that in Pale Moon... which is the serious hard-core security browser.)  Add the (non-UAC, additional) warning, but let the user decide.  

One other question: Would two distinct sessions of Terminal, one elevated, one not, behave as expected?  Or would both be vectors for any sessions?
I don't disagree that people should be able to opt into something like this. :smile:

> two distinct sessions

Oh, yeah, that should absolutely work today -- and not be a vector (the elevated one is fully running on the High-IL side of the world and cannot be driven by any other Medium-IL process)

> that should absolutely work today

In the same spirit, can't 2 tabs run in different processes and thus enable mixed elevation in the same window?
@DHowett-MSFT  So why can't the two distinct sessions be hosted in the over-arching app?  It really isn't hard to do.
I think I understand the security implications of having elevated console apps in the first place, but what I can't grasp is why having two types of tabs (elevated and non-elevated) within Windows Terminal would be _more risky_ than what Windows has supported for ages i.e. running elevated and non-elevated CMD's / PowerShell's side-by-side. Can someone shed some light on this?
@robomac
[1] It is trivial when you are _hosting traditional windows_ with traditional window handles. That works very well in the conemu case, or in the tabbed shell case, where you can take over a window in an elevated session and re-parent it under a window in a non-elevated session.

When you do that, there's a few security features that I'll touch on in [2]. Because of those, you can parent it but you can't really force it to do anything.

There's a problem, though. The Terminal isn't architected as a collection of re-parentable windows. For example, it's not running a console host and moving its window into a tab. It was designed to support a "connection" -- something that can read and write text. It's a lower-level primitive than a window. We realized the error of our ways and decided that the UNIX model was right the entire time, and pipes and text and streams are _where it's at._

Given that we're using Xaml islands to host a modern UI and stitching a DirectX surface into it, we're far beyond the world of standard window handles anyway. Xaml islands are fully composed into a single HWND, much like Chrome and Firefox and the gamut of DirectX/OpenGL/SDL games. We don't **have** components that can be run in one process (elevated) and hosted in another (non-elevated) that aren't the aforementioned "connections".

Now, the obvious followup question is _"why can't you have one elevated connection in a tab next to a non-elevated connection?"_ This is where @sba923 should pick up reading (:smile:). I'm probably going to cover some things that you (@robomac) know already.

[2] When you have two windows on the same desktop in the same window station, they can communicate with eachother. I can use `SendKeys` easily through `WScript.Shell` to send keyboard input to any window that the shell can see.

Running a process elevated _severs_ that connection. The shell can't see the elevated window. No other program at the same integrity level as the shell can see the elevated window. Even if it has its window handle, it can't really interact with it. This is also why you can't drag/drop from explorer into notepad if notepad is running elevated. Only another elevated process can interact with another elevated window.

That "security" feature (call it what you like, it was probably intended to be a security feature at one point) only exists for a few session-global object types. Windows are one of them. Pipes aren't really one of them.

Because of that, it's trivial to break that security. Take the terminal as an example of that. If we start an elevated connection and host it in a _non-elevated_ window, we've suddenly created a conduit through that security boundary. The elevated thing on the other end isn't a window, it's just a text-mode application. It immediately does the bidding of the non-elevated host.

Anybody that can _control_ the non-elevated host (like `WScript.Shell::SendKeys`) _also_ gets an instant conduit through the elevation boundary. Suddenly, any medium integrity application on your system can control a high-integrity process. This could be your browser, or the bitcoin miner that got installed with the `left-pad` package from NPM, or really any number of things.

It's a small risk, but it _is_ a risk.

---

Other platforms have accepted that risk in preference for user convenience. They aren't wrong to do so, but I think Microsoft gets less of a "pass" on things like "accepting risk for user convenience". Windows 9x was an unmitigated security disaster, and limited user accounts and elevation prompts and kernel-level security for window management were the answer to those things. They're not locks to be loosened lightly.
@DHowett-MSFT Thank you so much for the clarification. I think we'll have to get used to running one elevated instance of Windows Terminal and one non-elevated instance side-by-side, much like we're doing with console apps these days. 
Fascinating. Thank you.  Terminal being more a connection-renderer than a window does make sense.  Does that give PowerShell, already rather pipe/connection focused, any additional control over previously in a windowed console?

Are separate Terminal sessions fully isolated from each-other?

I'd be entirely satisfied with just having an indication that I'm in an elevated session.  Like "Administrator: \<whatever\>"
I'm missing that pretty bad right about now.
![image](https://user-images.githubusercontent.com/14316954/62808749-dd837800-baad-11e9-882d-b7fcc3f72e33.png)


???
"Run as different user" is a thing all windows admins need! This would be very helpful if it is available. The best option would be to have it with a flag in the config for each profile.

 
BTW, speaking of window isolation, let me quote the latest ctfmon vulnerability report

 > The obvious attack is an unprivileged user injecting commands into an Administrator's console session, or reading passwords as users log in. Even sandboxed AppContainer processes can perform the same attack.

@ecki That is quite a disturbing piece of news alright. I'm sure Tavis is off partying tonight after that one. 
@DHDHowett-MSFT
As many here have written, if the new terminal is not able to start with option "run as different user" than for a big number of users it is not very usable, also it is not compatible with Microsoft’s “Active Directory administrative tier model” if you for example have an AD user with default rights, and run PS Scripts with an Adminuser on a domain controller. 

I don’t have many cases where I start a terminal with my currently logged in user… so I ask you, what is the use case of this Terminal than? Ping, nslookup etc,.. if that is the intention than why are you putting so much work into all this? 

With “run as Administrator” you have some valid points, but why other Consoles like (PS6/7) still support these functions, if it is that insecure?

I always thought the new Terminal App will replace all the separate cmd/PS/… windows, but as it seems it is not usable in many real world scenarios. This is kind of sad tbh...


@Fisico your experience is not universal, and I’d encourage you to consider that when asking somebody to justify their project’s very existence.
To your overarching point about "run as different user" not existing/not working: that's a platform limitation that we're trying to get lifted. It's not through malice or incompetence that we do not support it.

As for why other console applications _do_ support it, it is not insecure when they do because they are specifically **not** hosting different elevation levels in the same window. That's the core issue here. Because they are hosted in standalone processes with standalone windows, they are free from the restriction on cross-integrity-level manipulation.
@DHowett-MSFT
Sorry if I offended you with my post, it was not my intention, I put too much emotion into it.
I think the Terminal is a great idea and has a very big potential and I’m glad you are developing it with the community to get the most out of it.

At this point there is so much confusion on what is implemented and what not.
“Run as Administrator” for the whole app is working at the moment, is this here to stay?

As I understand, “Run as Administrator” for each tab/profile is not something you want to implement. I think this ok for most of us.

“Run as different user” is not possible because Windows does not support it for apps, and you/we have to wait until Windows supports it? If so are we speaking of years?

“Run as different user” per tab/profile is also something you do not want to implement?

> @DHDHowett-MSFT
> As many here have written, if the new terminal is not able to start with option "run as different user" 
> than for a big number of users it is not very usable, ...  I always thought the new Terminal App will 
> replace all the separate cmd/PS/… windows, but as it seems it is not usable in many real world scenarios. This is kind of sad tbh...

I don't agree.  This is a huge advance over what we had before.  Unfortunately, most of us probably have gotten in the habit of running our shells elevated because of lack of a more granular approach... and we still can.  We can't _mix_  them... but we never did.   Seriously, at the _last three_ companies I've been at, the Developer Wiki has doing all builds/tests in an elevated VS prompt.  We implement security through real-time scans, aggressive active firewalls and knowing that our developers seldom screw up.  The _non-developers_ never run elevated, because (1) we can't trust them and (2) they don't need to.

So I, for one, am appreciative of this new Terminal.  It's not perfect, but neither is Take Command / TCC.  At least this is standard.


> > @DHDHowett-MSFT
> > As many here have written, if the new terminal is not able to start with option "run as different user"
> > than for a big number of users it is not very usable, ...  I always thought the new Terminal App will
> > replace all the separate cmd/PS/… windows, but as it seems it is not usable in many real world scenarios. This is kind of sad tbh...
> 
> I don't agree. This is a huge advance over what we had before. Unfortunately, most of us probably have gotten in the habit of running our shells elevated because of lack of a more granular approach... and we still can. We can't _mix_ them... but we never did. Seriously, at the _last three_ companies I've been at, the Developer Wiki has doing all builds/tests in an elevated VS prompt. We implement security through real-time scans, aggressive active firewalls and knowing that our developers seldom screw up. The _non-developers_ never run elevated, because (1) we can't trust them and (2) they don't need to.
> 
> So I, for one, am appreciative of this new Terminal. It's not perfect, but neither is Take Command / TCC. At least this is standard.

elevated != run as different user.
I run PowerShell more with other AD users, then with my own one.
I’m with you that you often run a cmd or PS as admin even if you don’t have to, but there are so many cases where you have to run it as admin. Most sysadmin tasks require admin rights or a different user with some sort of privileges.
Sure if you need to run cmd’s in user context it is all ok.

I understand that "elevated != run as different user".  I just don't believe "run as different user" is nearly as common as you claim.
> I understand that "elevated != run as different user". I just don't believe "run as different user" is nearly as common as you claim.

If you have something to do with the Microsoft universe than you absolutely need it.
It is not the best idea to login to windows machines with domain admin rights for example.
Running PS scripts with a user that has domainadmin rights or some other rights is very common.

@Fisico why not use the [New-PSSession](https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Core/New-PSSession) command then?
Automated scripts that require some type of specific elevation for a service typically require 'run as different user'. Whether that applies to Terminal is a different story. You can always change your login once in a CMD or PS session using the `runas `command. This would not change the elevation state of the tab as it's utilizing the underlying login, which is your regular user. Also any scripts you'd run using Task Scheduler or a cron job won't require Terminal to run unless you're utilizing it to get a functionality that somehow doesn't exist in a normal console session. If that's the case, the utilization of parameters to run that script with Terminal, which launches as a background process would be the solution. 

Therefore mixed elevation for tabs isn't necessary. We have a workaround and it's easy enough to copy the specific runas commands you need to a txt file that you can copy/paste into the Terminal and then fill out your password (you should never save your password to anything that's unencrypted). 
@SamuelEnglard 
i don't want to connect to a remote host, to run a script.

@WSLUser yea it is a option to use runas, but it is much more convenient to simply run the terminal or PS as a different user. I don't see why this should be a problem. 
@Fisico `New-PSSession` doesn't need to connect to a remote computer, see the ~~second~~first syntax entry.
> @SamuelEnglard
> i don't want to connect to a remote host, to run a script.
> 
> @WSLUser yea it is a option to use runas, but it is much more convenient to simply run the terminal or PS as a different user. I don't see why this should be a problem.

It is pretty standard operation for a user to pin PowerShell to taskbar and Right-Click to run as Admin or in some environments RunAs OtherUser as an elevated account is needed to run and enterprise level script. To say not possible for terminal is like the environments that leverage PSLockDown and force RunAs Admin just to load the shell or VSCode
IMHO
If you really need to have a tab run as a different user you could have a profile that runs `New-PSSession -Credential | Enter-PSSession` at start.

**DISCLAIMER**: I take no responsibility for computers ruined from doing this.
> If you really need to have a tab run as a different user you could have a profile that runs `New-PSSession -Credential | Enter-PSSession` at start.
> 
> **DISCLAIMER**: I take no responsibility for computers ruined from doing this.
-----------------------
Sure, or the "security" standing here could be re-considered. Again, I pin PowerShell to my Task bar, from there I can launch PowerShell non-elevated; I can right-click that and choose "Run As Administrator" and if in a corp environment I can Right-Click on the icon, then Shift-Right-Click on "Windows PowerShell" and select "Run as Different User" to launch PowerShell with alternate credentials. No sessions, no RDP'ing to another host to obtain those creds.

> Sure, or the "security" standing here could be re-considered. Again, I pin PowerShell to my Task bar, from there I can launch PowerShell non-elevated; I can right-click that and choose "Run As Administrator" and if in a corp environment I can Right-Click on the icon, then Shift-Right-Click on "Windows PowerShell" and select "Run as Different User" to launch PowerShell with alternate credentials. No sessions, no RDP'ing to another host to obtain those creds.

Yes, and I can also do that with Windows Terminal. Agreed. I don't see how that helps those who want to have a mix of tabs that are running as different users (or different elevation).
"mixed tabs" aside, I just want to clarify, you CANNOT do that with (the released preview) Windows Terminal due to the design of Windows Store apps. You can only run as the user that installed that app and logged in as that same user.

All I want is to be able to do what I do today, log onto the PC as normal user and run elevated shells. If Windows Terminal is released as is, it is little use to me.
Very good point. This limitation doesn't exist with private (non-store) builds of Windows Terminal.
> "mixed tabs" aside, I just want to clarify, you CANNOT do that with (the released preview) Windows Terminal due to the design of Windows Store apps. You can only run as the user that installed that app and logged in as that same user.
> 
> All I want is to be able to do what I do today, log onto the PC as normal user and run elevated shells. If Windows Terminal is released as is, it is little use to me.

I just opened 2 instances of the store build of Windows Terminal - one elevated, and one not. So I don't know why is it not working for you.
Ok, I have to believe you are a local admin on your PC. To be clear, maybe I should clarify. I am never a local admin on my workstation. So when I go to 'run as admin' I am prompted for user/password.

The 'admin' account I use is different from my normal malware/email reading account. So technically what I do is run as different user. This is the Windows Store app limitation. The solution (and maybe they will do this) is to release this as a Windows component that won't have those limitations.

![image](https://user-images.githubusercontent.com/10732022/63192025-a40fb700-c02f-11e9-8297-c92d2260502f.png)



********[URGENT] ALL I HAVE FOUND A SOLUTION TO THIS ISSUE!***********


By following this guide
https://www.maketecheasier.com/access-windowsapps-folder-windows-10/
you are able to make the windows app folder your own!

once you've done this you can locate the **Microsoft.WindowsTerminal._blahblahYourVersion_** folder. Once inside, locate **WindowsTerminal.exe** Shown below
![image](https://user-images.githubusercontent.com/43893055/63569821-8d41f680-c540-11e9-80fb-626f983c9fae.png)

 Once you have found it, Create a shortcut of this file and place it wherever you'd like. After doing so, set it to run as administrator. You can do this by right clicking and going to _Properties>Advanced>Run as administrator_ After that click okay and you are all set!


Personally I needed this because I use the shortcut in my taskbar so that I can just hit _Windows+1_ to launch it as admin. Not the long way of navigating through my start menu to run it correctly.
You could also just unzip the bundle we put on the releases page. It’s just a ZIP file. Please note, we _do not officially support_ unpackaged execution!
But this still means there's no _supported_ way to run elevated! I think this is a must-have feature.
![image](https://user-images.githubusercontent.com/18356694/63591081-5933f900-c573-11e9-980c-5a27c9e1f166.png)
![image](https://user-images.githubusercontent.com/18356694/63591111-681aab80-c573-11e9-8665-b8ff8c7a5249.png)

Indeed, I stand corrected.

What _is_ missing is the "run as administrator" entry in the taskbar shortcut's right-click menu.

Talked to a few people yesterday at a meetup and a few people said they mainly launch powershell with Windows+X and would love to have terminal / terminal as admin in there.
Very good point!
That's exactly my point! This is the solution for running it from taskbar
with admin privileges!

On Sun, Aug 25, 2019, 1:08 AM Stéphane BARIZIEN <notifications@github.com>
wrote:

> Very good point!
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <https://github.com/microsoft/terminal/issues/632?email_source=notifications&email_token=AKO4CP6JWWDNLGCHWNIJGFTQGIOULA5CNFSM4HL5EE72YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5CNA6Q#issuecomment-524603514>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AKO4CPZ6YRX5V3ERW4L2GWLQGIOULANCNFSM4HL5EE7Q>
> .
>

> Indeed, I stand corrected.
> 
> What _is_ missing is the "run as administrator" entry in the taskbar shortcut's right-click menu.

In the taskbar right-click twice. Once on the icon to make the context menu come up, then a second time on app name. e.g. "Windows Terminal (Preview)" and choose "Run as Administrator"

![image](https://user-images.githubusercontent.com/627993/63861074-2ffed880-c978-11e9-9ec1-e080bcd29903.png)

I feel confused.

Blushing.

Ashamed.

How come I didn't think of this?

Thanks anyway for sharing with us all!

Let's look at the problem from the other end...
Windows lets non-elevated processes control other non-elevated processes, sending keystrokes, capturing their UI, etc... but prevents non-elevated process from doing that to a window of an elevated process.
The Windows Terminal is designed to be also used to manage remote servers, through ssh, PowerShell remoting, etc...
This means the Windows Terminal becomes a security hole as soon as it is used for administration, as a local malware could wait for a Windows Terminal session to spy on what the user is doing, and as soon as it detects a remote shell, try to inject commands to infect the server using admin rights.

Preventing the Windows Terminal from being run as admin doesn't seem like a security improvement at all, as running it as admin would instead protect the user from non-elevated processes hijacking their remote shell sessions. Running it as admin should be recommend to the user whenever they use a tool that gives them an elevated command prompt, locally or remotely.

And about sudo for Windows, doesn't running the sshd service and then connecting to localhost from a non-elevated shell exhibit the same security issue?
> This means the Windows Terminal becomes a security hole as soon as it is used for administration, as a local malware could wait for a Windows Terminal session to spy on what the user is doing, and as soon as it detects a remote shell, try to inject commands to infect the server using admin rights.

While it's true that the remote system could be infected (assuming the remote process has admin rights), that doesn't mean we should also let it infect the local system too.

> Preventing the Windows Terminal from being run as admin doesn't seem like a security improvement at all, as running it as admin would instead protect the user from non-elevated processes hijacking their remote shell sessions. Running it as admin should be recommend to the user whenever they use a tool that gives them an elevated command prompt, locally or remotely.

Nothing is stopping you from running the Windows Terminal with admin rights right now. The issue at hand is about having mixed elevated and non-elevated tabs.
@SamuelEnglard spot on response.

To add, what we're trying to do is avoid adding _new_ security holes. The original console was the same problems w.r.t. remote server management. Nothing we can do about that unfortunately. Users doing remote server management are always running their consoles/terminals elevated, and that will give them some additional security (though I'm no security expert and I wouldn't construe that statement as advice)

Idea for progress on this issue: Try to run the entire _app_ as elevated, and if that succeeds, add a button next to each "open" button with the icon of a UAC shield, and add a prefix keybind for opening an elevated tab: <kbd>Ctrl</kbd><kbd>Shift</kbd><kbd>E</kbd>. (I checked and this was unbound.) It only works for the next tab open.

Anyway, the opened tabs have a UAC icon before their regular icon, and are ran as administrator. (Remember, programs can't send this keys anymore. We ran the app as administrator.)

The app should try to auto-elevate, and if that fails, run normally, and ignore this entire thread. 
> > Indeed, I stand corrected.
> > What _is_ missing is the "run as administrator" entry in the taskbar shortcut's right-click menu.
> 
> In the taskbar right-click twice. Once on the icon to make the context menu come up, then a second time on app name. e.g. "Windows Terminal (Preview)" and choose "Run as Administrator"
> 
> ![image](https://user-images.githubusercontent.com/627993/63861074-2ffed880-c978-11e9-9ec1-e080bcd29903.png)

Just noticed that the UAC prompt one gets in that case says "Unknown program."

Rather unexpected if you ask me...
@sba923 that's #2289 :smile:
@DHowett-MSFT thanks for the info; good to know that's (already) tracked.
The best answer to this I can think of is to have the option to have a profile the must be elevated and if the current windows is not elevate, start a new elevated instance with that profile. (Think how private browsing sessions work)
Very good idea 
I used this way to add the Terminal in the Win+X menu:
Create a new shortcut with the target: 

C:\Windows\explorer.exe shell:appsFolder\Microsoft.WindowsTerminal_xxxxxxxxxxxx!App

edit:
Sorry, this won't work if you want to run the App as Admin.
Instead you can use nircmd and create a shortcut with
`cmd.exe /q /c nircmd elevate "shell:appsFolder\Microsoft.WindowsTerminal_8wekyb3d8bbwe!App"`

(the correct path for "Microsoft.WindowsTerminal_xxxxxxxxxxxx" can be find out with the PS command "Get-appxpackage \*WindowsTerminal\*", use the entry in PackageFamilyName)

This shortcut can be used to start the terminal with administrator privileges with simple an doubleclick and with WinXEditor it can be added in the Win+X menu.
Note: The terminal must be also installed in the administrator account.

![2019-10-08 10_37_19-](https://user-images.githubusercontent.com/41161605/66381713-21193600-e9ba-11e9-94ac-01936c597f75.png)
Is the idea to load every profile as Administrator or only certain ones?  Ideally I'd like to have it by individual profile.  Maybe a property that is the "runas" account and another one as "iselevated"?
As discussed at length in this thread, you can't have a mix of elevated and non-elevated in the same instance of Windows Terminal, and this will **not** be added.
> > > Indeed, I stand corrected.
> > > What _is_ missing is the "run as administrator" entry in the taskbar shortcut's right-click menu.
> > 
> > 
> > In the taskbar right-click twice. Once on the icon to make the context menu come up, then a second time on app name. e.g. "Windows Terminal (Preview)" and choose "Run as Administrator"
> > ![image](https://user-images.githubusercontent.com/627993/63861074-2ffed880-c978-11e9-9ec1-e080bcd29903.png)

FWIW, I just tested shift-and-right-click which gives the "Run as administrator" option right away - only slightly faster than the two right-clicks option which was previously my go-to.

![image](https://user-images.githubusercontent.com/18150651/66529716-56f11400-eab9-11e9-9e0f-bbbba9d8b41e.png)

Hey guys did you forgot the UAC? Application cannot click things in safe desktop.
> FWIW, I just tested shift-and-right-click which gives the "Run as administrator" option right away - only slightly faster than the two right-clicks option which was previously my go-to.
> 
> ![image](https://user-images.githubusercontent.com/18150651/66529716-56f11400-eab9-11e9-9e0f-bbbba9d8b41e.png)

You can also ctrl + shift + left-click on the icon to bring up the UAC instantly.
Terrific, thanks a bunch! How many shortcuts do we have to remember? ;-)
> To your overarching point about "run as different user" not existing/not working: that's a platform limitation that we're trying to get lifted. It's not through malice or incompetence that we do not support it.
> 
> As for why other console applications _do_ support it, it is not insecure when they do because they are specifically **not** hosting different elevation levels in the same window. That's the core issue here. Because they are hosted in standalone processes with standalone windows, they are free from the restriction on cross-integrity-level manipulation.

Definitely hope running as a different user is something that comes at some point. While not the majority of my day-to-day activity, some powershell cmdlets require elevation (and I run with different users, think a protected user admin).

It's not the end of the world, but will certainly be annoying having to drop back to the legacy shells.

In time, I guess!
There is absolutely no issue / limitation with using Windows Terminal elevated, so no need to stick with the "legacy shells" (or to be more exact: to the legacy console host).

It's just that you can't mix elevated and non-elevated **in (different tabs within) the same instance**.



> There is absolutely no issue / limitation with using Windows Terminal elevated, so no need to stick with the "legacy shells" (or to be more exact: to the legacy console host).
> 
> It's just that you can't mix elevated and non-elevated **in (different tabs within) the same instance**.

I guess I may have misinterpreted the above, but there's a platform limitation with running the terminal under a different user context altogether from what I'm reading.
> I guess I may have misinterpreted the above, but there's a platform limitation with running the terminal under a different user context altogether from what I'm reading.

Yah, this thread has been all over the board on that point. I am not an admin on my workstations so 'run as admin' merely prompts me to enter my 'elevated creds'.

We should probably simply have a new thread about that use case.

To be clear, what I mean (and I think a lot of 'admins' need) is the ability to be logged into our workstation as a normal user. Then run 'some shell' as an elevated user as in say Domain Admin to do AD work.

Right or wrong, that is what some of us do and need. All the tricks about installing the Console from the store as that user and devising clever shortcuts have not really worked for me.

And yes, I can do this in a number of ways and maybe I should be restricting some of these activities to a protected workstation but reality is, as a normal user, I don't need a shell generally.

IMVHO the confusion stems from the fact people are (hold pre-Vista habits dying hard) more or less interchangeably using the terms "elevated" and "as another [domain] [admin] user."

Running as another user is **not** the same thing as running elevated.

1. Some of the people on this thread have the need, when logged on as an admin user, to run Windows Terminal workloads with elevation.

2. Some other people have the need, when logged on as a normal (or non-domain-admin) user, to run Windows Terminal workloads as another, admin user, typically with elevation.

3. One could also consider the case where people are logged on as normal user A and want to run Windows Terminal workloads as user B without elevation.

In #2 and #3, the Windows Store based deployment makes the story more complex, because Windows Terminal will not run as the logged on user, where the "store apps" are deployed for that user.

Hope I understand the situation correctly. If I do, I hope this clarifies the matter a little bit.
You got it right exactly.
Just FYI, that exact issue, unable to elevate ("Run As Administrator", as opposed to running as another administrative user, "Run As Different User") when the account you are logged in with is not a local administrator on the system, as per best practices), was briefly covered in another issue: [https://github.com/microsoft/terminal/issues/1538](https://github.com/microsoft/terminal/issues/1538).  That was closed with an explanation of it being a Windows problem, not a Terminal problem, as it seems to be a limitation of Store apps.

Without getting into a debate as to whether this should have been released as an MSI install instead of using the Store, there is a workaround in that thread I've used; log in briefly as your admin account, install the app from the Store, and then log back out again.  Run As Administrator then worked for my normal user account (until the next update, when it'll have to  be done again).
Yes there should be a MSI available. My new employer disallows (public) Store installs so the only way I'll be able to use Windows Terminal will be to build from source... 
Disappointed to see you can't run Windows Terminal "as administrator " without errors and then having to implement a workaround. I'd say a lot of companies implement a separation of privilege approach for identities (with ICT employees having a privileged and non-privileged account). So, being able to accommodate this requirement by providing an optional MSI deployment as per @sba923 suggestion would be a neat approach until such time store bundled apps can cope with privilage seperation ?

This is a PREVIEW not even 1.0 release...
I feel this topic has been fairly well discussed at this point, but there's one perspective I haven't understood yet: why can we not create a Windows shortcut to this app? That's the typical workaround to "always launch as administrator" - the typical workaround is to create a shortcut and change the shortcut to use elevated access as default.

Can someone please explain to me why we can't create a shortcut to this app? This is probably more related to the inner workings of Windows than the inner workings of Terminal, but I feel we are beating around the bush if I don't ask it directly.

Thanks.
I keep nircmd in my c:\utils folder along with a lot of other commonly used tools.
I added a profile that looks like this:

```
        {
            "name": "Admin Terminal",
            "startingDirectory": "c:\\utils\\",
            "commandline": "cmd.exe /q /c nircmd elevate \"shell:appsFolder\\Microsoft.WindowsTerminal_8wekyb3d8bbwe!App\"",
            "hidden": false
        },
```

It brings up a UAC elevation request, then opens up an admin instance of Windows Terminal. It's a decent workaround for the moment.

I'd be fine with the ability to tag sessions as Elevated and have them open in a new window, honestly.
I came here looking for a neat solution but as it does not seem to exist so I'll just share my hacky-ish solution. I added a profile for running powershell elevated:
```
{
...
  "commandline" : "powershell.exe -Command \"Start-Process PowerShell -Verb RunAs\"",
...
}
```
It pops up in a seperate window but it gets the work done.
> I feel this topic has been fairly well discussed at this point, but there's one perspective I haven't understood yet: why can we not create a Windows shortcut to this app? That's the typical workaround to "always launch as administrator" - the typical workaround is to create a shortcut and change the shortcut to use elevated access as default.
> 
> Can someone please explain to me why we can't create a shortcut to this app? This is probably more related to the inner workings of Windows than the inner workings of Terminal, but I feel we are beating around the bush if I don't ask it directly.
> 
> Thanks.

@aaronsteers, you're right that it's more about Windows than it is about Terminal. The main issue here is that we're distributed and installed as a "modern application package." They've got a number of restrictions and accidental limitations compared to native applications, but it's necessary for Terminal because it's also the least difficult way to use components of the "modern Windows API" (WinRT). It's terrifically frustrating to everybody on the team almost all the time. :smile:

We're trying to turn that frustration, and the community's frustration, into advancement for the platform. I'll apologize, though, that change isn't quick over here in Windows!
@DHowett  I'm really trying to understand, because I 2/3 like Terminal, but it's not doing some basics I'm accustomed to with TakeCommand or ConEmu, etc.

I can't mix elevations in the various tabs.  If I'm understanding, that's because you're a different kind of app and aren't really hosting the shell?

The scrollback buffer never clears, in any of the three environments (cmd, PowerShell, wsl bash.)  It does in my normal shells.  Again, because of how it's hosted?

And it would be quite nice to have a context or drop-down menu more accessible.  For example, to clear that scrollback, considering even the console escape trick didn't work for me.

The integration of the environments, and how well it picks up WSL Linux shells, is really nice.  But it's costing a lot of usability through the elevation and scrollback issues, so I seldom use it.
@robomac There's a great post by @DHowett-MSFT [here](https://github.com/microsoft/terminal/issues/632#issuecomment-519375707) that explains why we can't mix elevated and unelevated tabs in the same unelevated window. 

The tl;dr is: If we allowed users to connect to elevated commandlines from an unelevated Terminal window, then that creates a giant security hole, where other unelevated applications could effectively drive the elevated process, via the Terminal window. 

I don't know how ConEmu mitigates this risk, if they do at all. It's entirely possible that it's a security hole that conemu creates which we're not comfortable shipping as a part of the Windows Terminal.

The rest of your concerns are all issues that are tracked elsewhere in this repo, I suggest searching for them to track their progress individually. We'd prefer keep this thread on the single topic of "mixed elevation of tabs"/"having a profile that launches elevated"

<hr>

On topic: I do want to experiment with the "launch another instance elevated" route for "elevated" profiles. If the user experience isn't too bad, then that's a possible route forward here, at least as an option. 
ConEmu does not mitigate this risk.  They pass that risk onto their users.  (I'm not even sure they are documenting this risk.)

On the "launch another instance elevated" topic:  I wouldn't mind this behavior as long as it can use the *same* elevated instance of Terminal for these tabs and not launch a new instance each time I invoke an "elevated" profile.  
In my opinion, the "giantness"of the that security hole is a bit overstated. It is not normal to have a malware on one's computer that sits and waits for a chance to get elevated, so sacrificing convenience for security does not feel right.

On the other hand, if the end goal is to have WT to be shipped with Windows as a default terminal, that would increase the attack surface dramatically. But again, in this case, I personally would mitigate a risk by using an unpopular alternative that is unlikely to be a target for such attack and provides the required convenience (assuming detecting the presence of an elevated tab in a terminal is non-trivial enough to be terminal-specific).
Some of this is tl;dr for me, but if you take and dump the package, you can run wt outside of sandboxing, meaning elevation, and run as different user works without issue. I had talked to MSFT at ignite about this and was told to submit a pull request, but my VS skills are pretty weak. What would be easy enough to do is sign it properly (had to do this with my own internal pki so I could run on applocker) and put it in an MSI or MSIX distributable format. There is the odd bug here or there that may be specific to running it this way but overall it works really nicely. For now I just have a function to extract, sign and replace/update a program files based version from the store based version.
I understand the risk of that feature of "plugging" elevated tabs into an unelevated process, but isn't it possible to go the other way around?
Meening for people how need this, let the Terminal itself also run as Elevated and allow to start unelevated Tabs? 
Of course, that have other disadvantages, but for me (and I think for others also) they are acceptable.
(sure, that could be "interesting" as the terminal is a windows store app, not sure if that works)

Ps. Sorry for reopen this issue (also if another person already made that suggestion and I "read over" that).
Thanks to @EmTschi, I made simple and 100% convenient solution
It uses context menu and acts pretty the same as PowerShell 7 does
https://github.com/nt4f04uNd/wt-contextmenu
There you can find a guide how to implement it and all needed files

Thanks for the tip, I will try out that later.
Currently I'm working with two shortcuts at my desktop, that are mapped to the keys Ctrl+Alt+T and Ctrl+Alt+Shift+T for an elevated terminal, it's also ok as an workaround, but... not as nice as it could be and miles away from something like sudo.
> @
> 
> > Whenever I try to run the Terminal app with an administrator account, right click -> run as administrator, the UAC pops up twice and an error occurs saying:
> > "Windows cannot find (path\WindowsTerminal.exe) Make sure you typed ...".
> > The path exists and the app works correctly for the non admin user that built the app, but the other administrator user is unable to run it.
> > If I login to the admin user the terminal app is not present in either the settings or the start menu, as if it was never installed on the system.
> > Is there a way to build the app so that it installs for all users? Or does the root of the project have to be on a non user specific directory?
> 
> I'm seeing the same issue happening also.
> 
> Windows version 18922.1000

Just installed on Win10 update 1909, and I have the same issue with trying to run as Administrator
Same problem here. Can't use windows terminal now because I always need to run docker and then I always need to be admin in the terminal...
I have a hack-around solution for anyone who wants it:

1. download the msixbundle from the release page
2. unzip that, in there, find the msix that is for your platform (typically the x64 one)
3. unzip that into a folder somwhere
4. copy that folder wherever you please and run WindowsTerminal.exe elevated or however you please

A lot of this failing seems to come from the convenience of having this as a store app. There's a discussion about this on #1386 and someone there has mentioned perhaps installing with Scoop, which automates the above extraction process.

It would be nice if the following were treated as first-class citizens:
1. Portable installations (zip files -- even if the config isn't portable yet, as it lives under AppData\Local when running out of the windows store installation area)
2. A regular old .exe installer (or, if you must, .msi) for people who don't want the Store or to use the Store Installer

Both are not that tricky to implement from the current build procedure, as evidenced by the Scoop automation. And now that Windows Terminal is getting Really Rather Good, I'd like to be able to use it like I can any other terminal.
While we're at it: unless there are API incompatibilities, it would be great to have the option to install Windows Terminal without the Store (even the "portable" way) on earlier versions of Windows 10 (my employer blocks us at 1809/RS5, and installing from the Store is blocked). 
@sba923 if we didn’t rely on APIs that only exist in 1903, we would not require 1903.
Sure... was my guess 😜

Will have to lobby for upgrading company-wide, probably will hit a wall...
This is so stupid.

> Let's make a new unified terminal for command prompt, powershell, and bash for windows.
> Can I run cmd.exe as admin?
> No.

Guess I'll just keep my cmd.exe and powershell icons preset to run as admin on my taskbar indefinitely then.

![image](https://user-images.githubusercontent.com/195216/72673316-93c49380-3a36-11ea-8d77-83ce560adca0.png)

Dumb stuff like this is why my main work machine is still a Macbook.
> This is so stupid.
> 
> > Let's make a new unified terminal for command prompt, powershell, and bash for windows.
> > Can I run cmd.exe as admin?
> > No.
> 
> Guess I'll just keep my cmd.exe and powershell icons preset to run as admin on my taskbar indefinitely then.
> 
> Dumb stuff like this is why my main work machine is still a Macbook.

I agree in this case. I want a single Windows Terminal window that houses all the terminal tabs I need, where each terminal tab can be one of the multiple installed terminal hosts, and be elevated or not.

It really seems like this mixed elevation feature is being held back by the technical design decision to host all tabs on a single HWND handle.
1) Can you run the new terminal as Admin? *YES* (There are issues doing so depending on how you installed it/launch it but there is no desire for this to not work). (If you do not know how to do this, see multiple posts above on how.

2) Can you have one tab with elevated while another isn't? *No*. See https://github.com/microsoft/terminal/issues/632#issuecomment-519375707 for why.

Can people please remember that this issue is about mixed elevation tabs?!? If you want to launch the whole process elevated and cannot please open a new issue.

@DHowett-MSFT Could we rename this issue to be about mixed elevation tabs?
Whatever way this gets handled or not, elevated terminals or tabs should have some kind of indicator. Now if I start new terminal with Run as administrator, there's no way to easily notice my cmd tabs have elevated access compared to ones in the next window.

EDIT after @SamuelEnglard 's comment: Obviously I hastily chose `cmd` as a bad example. Yes, `cmd` shows 'Administrator:' in tab title. But WSL Ubuntu bash on my default tab overwrites whatever there might be in it's tab title. I guess `bash` doesn't know (or even care) about the elevation of Windows Terminal, so that info cannot be used when updating title from within `bash` (there's of course `sudo` situation, but that's a different thing).

In Terminal's `profiles.json`, there's
    `"showTabsInTitlebar": false`
but with this setting Terminal's title bar doesn't signal the elevation.

@janilahti do elevated CMD tabs not look like 
![image](https://user-images.githubusercontent.com/1119883/72739789-65e46980-3b72-11ea-93ce-dd8fc6916ca8.png) for you?

Security is a moot point if no-one wants to use your tool...
Ya'll should just make a sudo command for windows that works in both cmd.exe and powershell. That would save me the trouble of having a shortcut for both set to run as admin.
FYI, I wrote a `sudo for windows`, called `gsudo`: https://github.com/gerardog/gsudo

It supports to elevate `cmd`/`powershell`/`pwsh` commands or the whole shell. It's easy to install and use and should resemble the original *nix sudo. There are others `sudo` implementations in the wild but IMHO, `gsudo` is the most versatile and easy to use.

You can use it, for example, to create a WT profile that calls `gsudo cmd`/`gsudo pwsh` or `gsudo WhateverShell` to launch elevated tabs. Install `gsudo` and add a WT profile:
```
    {
      "hidden": false,
      "name": "PowerShell Core elevated",
      "commandline": "gsudo.exe pwsh"
    }
```

It's a C# client-server app that acts as a client when non-elevated, and launches itself elevated as a server. Both instances communicates via secured named pipes. Other windows sudos in the wild are mostly like PowerShell 'runas' scripts that pop-up a new window, but being a full app allowed me add far more features.

I've read the thread and the security of a sudo command has been discussed and some valid points are made. I've taken all security measures that I could think of and I am open (and planning) to introduce more of them. At this point it should be as secure/insecure as if you open a remote admin PS session or if you do `ssh root@server` from a non-elevated console. (eg. vulnerable to keystrokes or screen scrapping, and correct me if I'm wrong but my understanding is that *nix sudo is also vulnerable in this way). There is also the credentials cache, which reduces the amount of UAC popups during a 5 minutes session (inspired in *nix sudo), which clearly is an attack vector, that can be disabled via config. For those worried about security I am planning to add a very easy way to tighten it (by disabling features like the credentials cache) with a simple command or via an enterprise group policy/registry setting.

One interesting point made in [this comment](https://github.com/microsoft/terminal/issues/632#issuecomment-519375707) is that Microsoft cannot afford "accepting risk for user convenience". If that is the final word from MS, then at least this looks like a decent (fully-functional) workaround, and all feedback/[issues](https://github.com/gerardog/gsudo/issues) or ideas on how to improve security are welcomed.
Can't be something I have to install that isn't official supported. Kills any ability to use it in a corporate environment.
Then @hparadiz you would have to wait until a new version of windows is released with a new security design that allows an official sudo (or mixed elevations tabs) without security risks. Looks like it won't happen soon. Your best shot is to wait until the whole WT can be launched as admin, tracked in #4217, likely to be released sooner.
Found a nice hack from a blog:

http://nuts4.net/post/windows-terminal-run-as-admin
@gerardog do you have a scoop bucket for `gsudo`? or is it in one of the known one? I'm currently on a linux box, so can't check.
@fluffynuts It's in scoop's main repo. So just 'scoop install gsudo'. Also other instalation methods are listed in https://github.com/gerardog/gsudo . But lets keep this discussion on the WT topic. 😉
Open question: if it is a security risk to mix elevated and unelevated tabs, then is that risk present in [ConEmu](https://conemu.github.io/)? Because it can do exactly that. Or is ConEmu implementing that feature in a different way than you would in Terminal? And more broadly I would note that many of the features being requested here (in this thread and others) are already extant in other terminals, ConEmu being just one example, so when Terminal devs suggest these features would either never be implemented or not implemented for a very long time, you're implicitly just confirming that we shouldn't use Terminal.

>if we didn’t rely on APIs that only exist in 1903, we would not require 1903.

@DHowett-MSFT Is there any public documentation available regarding what APIs these are and why they are necessary? Because as an outside observer, when I see this decision and the decision to use UWP, I don't see the value add. I just see obstacles towards adding what many enterprise users consider to be basic functionality.
@dadpolice See https://github.com/microsoft/terminal/issues/632#issuecomment-518888895 for what ComEmu does.
I thought "UAC isn't a security barrier" according to Microsoft? It was treated like one in Vista. Then we were told it wasn't one and any issues like this were a joke in Windows 7. Now it is one again today?

Maybe you need to review the design of File Explorer and the UAC whitelist in this case. :)

Or does it just depend on whether or not it's an excuse to take a shortcut in designing something that normal developers aren't allowed to do (File Explorer) or not implement an essential feature (in this case)?
> not implement an essential feature (in this case)?

I want to make it clear - we're not trying to _not_ implement this feature. It's certainly an important feature that we _want_ to implement. It's something that I'm running into daily right now - having a second elevated window is _okay_ but it's not _good_.

It's just going to take a while for us to be able to design an appropriately secure solution, then also do the engineering effort to actually implement it. It's something we whiteboarded for a while this week even. 
@zadjii-msft 

> [...] 
I don't think we plan on supporting mixed elevated and unelevated tabs, because it's a bit of a security hole.
[...]
> 
> (as a matter of linking related threads, #146)

Weird that people were under the impression the feature will not be implemented. *sarcasm sign*
@kort3x There's a difference between "No Plan" (aka we're not promising it) and not wanting to and doing what they can do find a way implement it.

As @zadjii-msft put it:

> It's just going to take a while for us to be able to design an appropriately secure solution, then also do the engineering effort to actually implement it. It's something we whiteboarded for a while this week even.

As long as they don't have a secure solution they won't plan (aka promise) to support mixed elevation tabs. I'm willing to be though that the second that do have a secure solution they will add it to the plan (though I can't promise anything).
> I thought "UAC isn't a security barrier" according to Microsoft? It was treated like one in Vista. Then we were told it wasn't one and any issues like this were a joke in Windows 7. Now it is one again today?

As I understand it's a security barrier if configured as "Always notify", otherwise it's not.
Well, this is disappointing. I like the terminal (which is saying a lot, as I'm pretty enamored with non-MS tools generally), but the inability to smoothly elevate is a real barrier to me doing more work on this OS.
LOL okay yea, I can see how that's confusing. I originally wrote that comment days after we first announced, when there wasn't a plan. After a few months of discussing, I've certainly come around to the idea this might be possible, with more effort. I'll go update the comment to reflect that. @SamuelEnglard is right though, it's hard to _commit_ to doing this until we _know_ that it's possible to do correctly. 
This is encouraging to hear.  Is it possible to extend this enthusiasm to other teams, so #3581 can actually be fixed?  
It'd be nice if the tabs were allowed to be different processes (similar to how chrome manages it) in the first place because then I wouldn't have to restart all tabs after grouping them nicely just to get an updated environment in a single cmd tab...
Once the Windows Terminal is just a manager it could run in a non-elevated mode while still holding elevated command prompts. That would be nice. (well, having the wt run elevated while holding non-elevated terminals would be ok for me too)
@rapus95 technically the tabs are, in that the "console" is a different process. Windows Terminal is just a manager already
> EDIT (Feb 14 2020)
> Okay, so this comment didn't age super well. Originally, there was _no_ plan to support this, since it wouldn't work with the single `HWND` we had. We're working on designing a solution that _might_ support this in the future, but we can't commit to anything until we're sure that we can come up with an appropriately secure solution, that ensures that a lower privileged process can't drive a higher privilege terminal.

Aside some other points, that's the main reason why I'm still using `ConEmu`. And I bet I ever will.
https://conemu.github.io/ @Maximus5

> This is so stupid.
> 
> > Let's make a new unified terminal for command prompt, powershell, and bash for windows.
> > Can I run cmd.exe as admin?
> > No.

> Dumb stuff like this is why my main work machine is still a Macbook.

@hparadiz  Have a look at ConEmu :-D No issues running multiple Shells as tabs in ONE Window; even running elevated Powershell and cmd.exe sessions aside non elevated ones.
@tmeckel are we sure conemu doesn't have the security vulnerabilities that the terminal team is worried about?  users often pick less secure software because it does what they want, but at their own peril.
@drdamour @tmeckel It does. I asked the same question above, it's answered in another thread: https://github.com/microsoft/terminal/issues/632#issuecomment-518888895

I've been pretty critical of Terminal so far, but to be fair, ConEmu and ConsoleZ and other similar tools already exist. There's little value in Microsoft simply copying them, but there's great value in recreating those features in a way that's secure. That said I do still think it's very silly to build a terminal emulator as a Store-only UWP app, especially now that Microsoft seems to be moving away from UWP (e.g. the new Edge is a Win32 app).
> That said I do still think it's very silly to build a terminal emulator as a Store-only UWP app, especially now that Microsoft seems to be moving away from UWP (e.g. the new Edge is a Win32 app).

To be clear, the Terminal is not Store-only ([there are .msix's available here](https://github.com/microsoft/terminal/releases)), nor is it a UWP application. It's a Win32 application using UWP XAML as its UI framework.
> @rapus95 technically the tabs are, in that the "console" is a different process. Windows Terminal is just a manager already

Well then, why is it that the environment isn't updated for a new cmd instance? I always need to open a new Windows Terminal which in some sense reduces the overall usability of having multiple tabs...
@rapus95 while I'm not positive (I'd have to go digging through the code) I'm pretty sure each sub-process is launched with its parent's environment not a new one.
that doesn't seem like making sense for a terminal manager 🤔 
@rapus95 It's actually a bug we're tracking over here: #1125
> To be clear, the Terminal is not Store-only ([there are .msix's available here](https://github.com/microsoft/terminal/releases)), nor is it a UWP application. It's a Win32 application using UWP XAML as its UI framework.

That just sounds like UWP with extra steps. Whatever it is that makes it so I can't right click on Terminal and run it as a different user, as I can with any normal Win32 application, that was a strange choice.
It's not a UWP app nor a Store-only app.
It just happens that one of the distribution methods is the Store, which requires a UWP package.
Only those who installed it using the store are not able to `Right click -> Run As Admin`.
Uninstall and use the [`msix`](https://github.com/microsoft/terminal/releases) or via [scoop](https://scoop.sh/)
> Uninstall and use the [`msix`](https://github.com/microsoft/terminal/releases) or via [scoop](https://scoop.sh/)

Or [`chocolatey`](https://chocolatey.org/packages/microsoft-windows-terminal).

@gerardog I didn't say run as admin, I said run as different user. 
Doesn't `Shift`+`Right Click` work for you?
![image](https://user-images.githubusercontent.com/3901474/76432610-fd578300-6391-11ea-8aab-f9fcd1a37890.png)
(Please note I've installed using `scoop`)
No. I've installed using the msix package and that option is not there. 
I installed as chocolatey and do not have run as admin either



> > To be clear, the Terminal is not Store-only ([there are .msix's available here](https://github.com/microsoft/terminal/releases)), nor is it a UWP application. It's a Win32 application using UWP XAML as its UI framework.
> 
> That just sounds like UWP with extra steps. Whatever it is that makes it so I can't right click on Terminal and run it as a different user, as I can with any normal Win32 application, that was a strange choice.

Same here, I have tried both msix and store app. I still don't have the "Run as different user" option.
What about making all elevated tabs background color red so it's obvious that it's elevated?
I'd rather has this configurable: background color, tab title...
https://github.com/gerardog/gsudo works nicely as a temporary solution
Maybe implement something like `wt elevated` that opens a new elevated window with the current shell with the same environment. 
EDIT: or #3158 but as new window and elevated
I don't get why would you do not copy the way Linux does it.

To my understanding or the Linux world (correct me if I'm wrong), the terminal apps (gnome-terminal, mate-terminal...) do not need to be elevated even if you type su or sudo and execute command as the root user. The terminal app's only mission is to run a shell in a different process (bash, ksh...) that is or is not elevated, and to redirect the shell input and output so that we can interact with the shell.

If you type "su" or begin a command with "sudo" in a linux terminal, it does not open a different window.
@gabsoftware I am unsure about the security of this even on Linux. It's possible to send keystrokes to X windows in Linux as well, and my guess is that it's possible to send keystrokes to terminal clients running in an X window even if the running terminal is elevated with sudo or su. It may even be possible to send keystrokes to elevated X windows, but I really don't know for sure.
> > > To be clear, the Terminal is not Store-only ([there are .msix's available here](https://github.com/microsoft/terminal/releases)), nor is it a UWP application. It's a Win32 application using UWP XAML as its UI framework.
> > 
> > 
> > That just sounds like UWP with extra steps. Whatever it is that makes it so I can't right click on Terminal and run it as a different user, as I can with any normal Win32 application, that was a strange choice.
> 
> Same here, I have tried both msix and store app. I still don't have the "Run as different user" option.

I can't "Run as a different user" by shift-right-clicking the tile in the start menu, but I can if I shift-right-click WindowsTerminal.exe
> @gabsoftware I am unsure about the security of this even on Linux. It's possible to send keystrokes to X windows in Linux as well, and my guess is that it's possible to send keystrokes to terminal clients running in an X window even if the running terminal is elevated with sudo or su. It may even be possible to send keystrokes to elevated X windows, but I really don't know for sure.

I've done some experiments, and now I am rather sure of the *insecurity* of this on Linux. I'm not a security expert, so I'm not sure about the implications of this (anyone?). Turns out it's really easy to send keystrokes to X windows that have just run sudo and are open to new sudo commands without asking for a password. Blog post [here](https://wensveen.wordpress.com/2020/03/28/exploiting-the-sudo-password-timeout/), sorry for the shameful plug...

My conclusion would be that unless there's a way to disallow sending keystrokes to mixed-elevation windows, this should only be implemented as an option for users willing to accept the risk (big fat warning signs, etc.).

As a side note, how does Windows' on-screen keyboard send keystrokes to elevated windows?
I've released `gsudo` v0.7 and is relevant to this thread:

EDIT: For context: `gsudo` is a sudo for windows, and allows to elevate a simple command or a shell in the current console. When invoked from a Cmd/Pwsh within WT, it elevates the tab. Also, you can edit your profile, name it 'Elevated Powershell' and your change your command to `gsudo Powershell` and voilá, you got an elevated tab profile. See [here](https://github.com/microsoft/terminal/issues/632#issuecomment-582782751).

But since gsudo, or any sudo for windows, jumps over the UAC isolation, it has been labeled 'insecure'. What follows is a more complicated workaround that allows you to do mixed elevations of tabs while keeping security. /END EDIT

`gsudo` can now launch applications with any integrity level. For example we can launch `Windows Terminal` with *MediumPlus integrity level*, this means a 'semi-elevated' mode: no-admin rights but isolated, unreacheable from other regular (Medium Integrity) processes. (a UAC popup will appear)

So, first step should be to always launch WT with: **`gsudo -i MediumPlus WT`**
(You may change your WT shortcut). This protects WT from malicious processes, screen-scrapping, sendkeys, dll-injection, etc.
(EDIT: if it doesn't work use: `gsudo -n -i MediumPlus cmd /c cmd /c start wt`)

**Then you can use `gsudo` safely within WT to elevate commands, or even create an elevated profile with: `"commandline": "gsudo cmd.exe"` in profiles.json**

> My conclusion would be that unless there's a way to disallow sending keystrokes to mixed-elevation windows... this should only be implemented as an option for users willing to accept the risk (big fat warning signs, etc.).

Done, and done. (I've added security warnings to gsudo).

Also, since I've learned that *if the user is invoking gsudo from a regular/Medium integrity process*, then gsudo's credentials cache (the feature to show less UAC popups) can't ever be fully protected... So, now the credentials cache must be explictily enabled via `gsudo cache on/off` or `gsudo config cachemode auto`. 
Turns out `"Changing your WT shortcut"` is not trivial at all: Given the MSIX/AppStore model, you ran into #4217 and #4459.

The following powershell script workaround those issues to create a Windows Terminal shortcut on the desktop and associates it with Ctrl+Alt+T hotkey:

``` powerhell
$shortcutPath = [Environment]::GetFolderPath("Desktop") + "\Windows Terminal Isolated.lnk"

# Use this if installed via Scoop. 
$wtPath = "$home\scoop\apps\windows-terminal\current\WindowsTerminal.exe"

# Use this if installed via Chocolatey or Ms Store
$wtPath = (Get-Command 'wt.exe').Path

$cmdPath = (Get-Command 'cmd.exe').Path
$gsudoPath = (Get-Command 'gsudo.exe').Path

$WshShell = New-Object -comObject WScript.Shell
$link = $WshShell.CreateShortcut($shortcutPath)
$link.TargetPath = $gsudoPath
$link.Arguments = "-n -i MediumPlus cmd /c cmd /c start $wtPath"

#Optional, set global Keyboard Hotkey
$link.Hotkey="Alt+Ctrl+T"

# Optional, download icon.
$icoPath = [IO.Path]::GetDirectoryName($wtPath) + "\wt.ico"
Invoke-RestMethod -Method Get -Uri "https://raw.githubusercontent.com/microsoft/terminal/master/res/terminal.ico" -OutFile $icoPath
$link.IconLocation="$icoPath,0"

$link.Save()
```

Once you've started WT as MediumPlus (i.e. Ctrl+Alt+T), you can use gsudo as mentioned [above] (https://github.com/microsoft/terminal/issues/632#issuecomment-613751789) to elevate commands in what AFAIK should be safe.
My workaround to this is using [Luke Samson](https://github.com/lukesampson/)'s [_Sudo for Windows_](http://blog.lukesampson.com/sudo-for-windows). Profile config is:
`"commandline": "pwsh.exe -Command sudo.ps1 pwsh.exe",`
When starting a new tab with that profile, UAC pops up and then you end up in an elevated Powershell Core. Also works with any other terminal.
`"commandline": "powershell.exe -Command sudo.ps1 powershell.exe",`
`"commandline": "powershell.exe -Command sudo.ps1 cmd.exe",`
If you don't use [scoop](https://scoop.sh/), I am sure the concept can be extracted and used independently. Check out the source code here: https://github.com/lukesampson/psutils/blob/master/sudo.ps1
I'm using the schtasks workaround to run Windows Terminal as Administrator and bypass UAC:

1. Start Task Scheduler.
2. Create a new task. Give it a name and check the "Run with highest privileges" checkbox.
![image](https://user-images.githubusercontent.com/1370973/79784728-592b0980-834b-11ea-8fc9-6514736d7fae.png)
3. On the Actions tab, select to start a program: `wt `<img src="https://user-images.githubusercontent.com/1370973/79784923-a909d080-834b-11ea-95fc-75c887b1a98f.png" width="450">

4. On the Settings tab, make sure "Allow task to be run on demand" is checked and uncheck "Stop the task if running for longer than" checkbox.
5. Create a shortcut by right clicking the Desktop and select New -> Shortcut and type `schtasks.exe /run /TN "{task name}"`
![image](https://user-images.githubusercontent.com/1370973/79785638-d7d47680-834c-11ea-81ef-93ec16a4b1e2.png)
6. Optionally change the shortcut [icon](https://raw.githubusercontent.com/microsoft/terminal/master/res/terminal.ico) and drag it to the taskbar.

Looks like I will have to stick to cmder until this is fixed.
now that there's an inkling of a plan supposedly, can we get the docs
updated to no longer say there's no current plan?

https://github.com/microsoft/terminal/blob/master/doc/user-docs/index.md#starting-a-new-powershell-tab-with-admin-privilege
@drdamour Once there _is_ a plan, I'd love to remove that section. Right now though, there's only a plan to research a way to make a plan. Once there is a real plan, and a way we can safely do it, I'll remove that section.
The method described by @KMoraz works great as a workaround for now. Thank you for posting this.
Hi people,

I was using [ConsoleZ](https://github.com/cbucher/console) until I discovered this one yesterday.
ConsoleZ has some features and one is to start a new tab as administrator using UAC (it pops the dialog of UAC).
I find it very useful because you don't need to take of the hands of keyboard to open a new elevated tab.

What if it were a configuration inside profile configuration? That's how it's done in ConsoleZ.
Hi All,

I found another Shortcut workaround that's simple and works great for those who have to enter local admin credentials when running anything As Administrator.

This link explains, but needs a full path for the wt.exe reference:  
http://nuts4.net/post/windows-terminal-run-as-admin

My full shortcut string is: `C:\Windows\System32\cmd.exe /c start /b C:\Users\myUserName\AppData\Local\Microsoft\WindowsApps\wt.exe`

UPDATE 21 May 2020:
The above used to work prior to version 1.0.1401.0.

See this new issue too: https://github.com/microsoft/terminal/issues/6013

Now Crtl-Shift click does NOT work either when you have to elevate with a local admin account.

See the below error screenshot I get after being prompted twice for elevate permissions: 
![Error](https://user-images.githubusercontent.com/16409467/82567147-f942a100-9b4a-11ea-9c1c-f54d048af2f6.png)

For information, imho gsudo is perfect for this, thx https://github.com/microsoft/terminal/issues/632#issuecomment-613751789

My config have only this profile to gain privilege : 
```
            {
                "name": "Admin Powershell",
                "commandline": "cmd.exe /c gsudo powershell.exe",
		"titleText": "Admin Powershell",
                "icon": "ms-appx:///ProfileIcons/{574e775e-4f2a-5b96-ac1e-a2962a402336}.png"
            },
```
For me the easiest way to open Windows Terminal as administrator, is to pin it as the first item on the task bar. Then `Win+Ctrl+Shift+1` opens it as admin
> For me the easiest way to open Windows Terminal as administrator, is to pin it as the first item on the task bar. Then `Win+Ctrl+Shift+1` opens it as admin

Indeed **very** convenient, but this only works for accounts that are members of the Administrators group.

If you are acting as the admin for someone else, you won't be able to run Windows Terminal as your (admin) user from their account.

I think it would be nice to have one tab setup to run cmd as administrator not everything.

> I think it would be nice to have one tab setup to run cmd as administrator not everything.

As explained elsewhere here, this is not possible with the current design.
is there a flag that can be used to run as admin? Then we could just create a shortcut for it.
If you pin Windows Terminal to the taskbar, you can launch it _elevated_ using Ctrl+Shift+click.

This will do the same as right-click on icon, right-click on "Windows Terminal", followed by "Run as administrator."

Note: Windows Terminal being a Store app, you can't run it as _another user_.
I would love to see the ability to have "mixed-integrity-level tabs" in Windows Terminal, with the integrity level as an option in each profile. This is mostly as a convenience in my normal sysadmin/devops work to minimize workflow interruptions and context switching.

I have found a simple alternative that works for me for now. This doesn't address all the scenarios presented here by other users. It doesn't depend on third party apps, shortcut files, key combinations, or Scheduled Tasks. It doesn't require identifying the location of the Windows Terminal executable. It just makes a separate entry in the Windows Terminal profile list that launches a second Windows Terminal instance elevated. This triggers a UAC prompt once. I only use this if and when I need elevation.

The result is two Windows Terminals. Anything in one is standard and anything in the other is elevated. For me, this an acceptable level of interruption and context switching. The elevated Windows Terminal also prepends each tab title with "Administrator:" which gives good visual confirmation of the difference.

Edit: I have Powershell 7 installed,

```json
            "name" : "Launch Windows Terminal Elevated",
            "commandline" : "pwsh.exe -command Start-Process -Verb RunAs wt.exe"
```
@IarwainBen-adar, I seem to recall recently reading in the new docs that you can't use the `commandline` item and and the `source` item together. Does it work as expected without the `source` item?



I tried his code and can not even get the new item to appear in the pull
down menu.


@shem-sargent sorry about that, I deleted my comment here because the extraneous `source` declaration was indeed the problem. Although, now that I have the menu entry working, unfortunately I still can't launch an elevated instance of Windows Terminal — I'm running into issue #3145 with a failure of `The file cannot be accessed by the system.`
@IarwainBen-adar Sorry, I cannot reproduce #3145. Otherwise, I would try troubleshooting on my end.
pin to task bar and shift+right click
Cheers @LordFPL and of course @gerardog , I had never heard of gsudo (https://github.com/gerardog/gsudo for others that are interested) before, but this makes elevated sessions a breeze now. Thanks! Either add it to the profile object in the settings file, or just use the `sudo` alias as you would do on a Linux system. Perfect! 
@zadjii-msft my apologies, but I don't exactly understand what the issue here is. Windows supports token manipulation and impersonation, it's how runas works isn't it? using gsudo from @gerardog i can have a low(er) integrity wt hosting a high(er) integrity shell at the same time as any other level integrity shell, be it powershell, pwsh, cmd, or any wsl shell. From my limited testing, none of the low(er) integrity shells can debug into that higher integrity shell. What is the roadblock here to having this as a builtin terminal, or even more preferable at the OS level, feature?
@smokeintheshell https://github.com/microsoft/terminal/issues/632#issuecomment-519375707

A low(er)-integrity window _receiving input and funneling it directly into a high(er)-integrity process_ opens that high(er)-integrity process up to control by other low(er)-integrity things on the system.

It means a potentially malicious process only needs a lateral move at the same privilege level to gain EoP.
> @smokeintheshell [#632 (comment)](https://github.com/microsoft/terminal/issues/632#issuecomment-519375707)
> 
> A low(er)-integrity window _receiving input and funneling it directly into a high(er)-integrity process_ opens that high(er)-integrity process up to control by other low(er)-integrity things on the system.
> 
> It means a potentially malicious process only needs a lateral move at the same privilege level to gain EoP.

yes, I read that explanation at the beginning of the thread, but I don't understand why it's okay for Linux, and probably Mac, but not OK for Windows? Windows currently protects input to elevated processes from non-elevated processes. In either this issues or a related one, someone suggested that we need a separate process per tab. I would think this is already the case since each tab has its own command to execute (eg: pwsh.exe). Is it because they are all children of the same root process under one HWND? 

Does Ubuntu's terminal suffer from the same issue with tabs if I either:
- have a tab with `su` open
- have a tab where I have elevated with `sudo` already and don't need to enter my PW again per configuration policy?

Or is Ubuntu's architecture somehow hardened against cross-process input injection attacks?
> Does Ubuntu's terminal suffer from the same issue with tabs if I either:
> 
>     * have a tab with `su` open
> 
>     * have a tab where I have elevated with `sudo` already and don't need to enter my PW again per configuration policy?
> 
> 
> Or is Ubuntu's architecture somehow hardened against cross-process input injection attacks?

If you look at my comment [here](https://github.com/microsoft/terminal/issues/632#issuecomment-605370711), I've actually reproduced / exploited the issue on Linux. Both su and sudo are probably equally "vulnerable", in that you can send keystrokes to lower-integrity windows running those commands. The sudo password timeout (not having to enter your password at the next sudo command within 15 minutes), makes this even easier. You can harden Ubuntu by disabling the X extension that is necessary for the attack. Not sure if this is possible in a Wayland environment (the attack and/or the hardening).

I completely understand the decision to not implement mixed-elevation tabs, unless there is some way to disable virtual keyboards and other software input methods.


> I would think this is already the case since each tab has its own command to execute (eg: pwsh.exe). Is it because they are all children of the same root process under one HWND?

@kbirger Yes there are separate processes for each tab, but all your mouse and keyboard inputs are still sent to Windows Terminal's window (which is low-integrity), then routed to each shell processes via standard input streams. That's how all Windows Terminal's keyboard shortcuts work.

---

I wonder if it's possible to detect if the input is forged, for example using the [GetCurrentInputMessageSource](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getcurrentinputmessagesource) API. I can't find much information about this API other than the official [example](https://github.com/microsoft/Windows-classic-samples/tree/master/Samples/IdentifyInputSource), but from the description it should be able to identify the input source (hardware/from processes with uiAccess, mostly accessibility software/from processes without uiAccess, maybe malicious)
> why it's okay for Linux, and probably Mac, but not OK for Windows?

I'm pretty sure that one of thre reasons is that Microsoft is selling security as a feature to other large corporations, or governements.

There are also a few other resons that come to my mind as to why that might not have been a problem until now:

- For a long time, and formany reasons (such as "hackers" not liking Windows, and "everyone" using Windows ^^), Windows used to be the primary (≈only) target of all kinds of malware. It needed better security (protecting elevated windows), while other didn't care that much.
- As explained earlier in this issue, it should not have been possible for malware to easily access your elevated console host on Windows, so it's likely that not many have invested in that issue (I'm no security expert, so I don't know if some have)
- Malware usually have had other ways of elevating themselves than trying to find an elevated command prompt in your OS of choice
- Only developers and sysadmins use terminals (this only reduces the target demographic of the attack; governments and large corporations are still a concern)

Now, by introducing the feature naively (as we'd all have done, i'm sure 😄) you'd be introducing a new (huge) flaw in some Windows installations. With the development being done in the open, you can be sure that everyone in need would be aware of the flaw and start coding against it.
The quick countermeasure being to ban Windows Terminal (and likely all other terminal emulators out there now that the flaw is public), you could then kiss goodbye to your dreams of using Windows Terminal in any kind of corporate environment 😟


I'm still very much hoping that a secure version of this feature wil see the light of the day, though 🤞
I see. Thanks for the explanations!
> As a side note, how does Windows' on-screen keyboard send keystrokes to elevated windows?

@mrwensveen AFAIK there are three ways to send inputs to elevated windows:

1. Elevate yourself. However you still can't send inputs to system processes (e.g. Task Manager, UAC dialog, login screen).
2. Register a Windows Service. Now your program runs as SYSTEM so you can do anything you want. I have seen some Remote Access programs do this.
2. Declare the `uiAccess` flag, digitally sign your binary, install to a location that's not writeable for current user. It's a "backdoor" for accessibility softwares, allowing them to read/write any other programs (including system processes), and displaying on top of any other windows (including Secure Desktop where UAC popups show and login screen), all without running elevated. See https://docs.microsoft.com/en-us/windows/win32/winauto/uiauto-securityoverview. 

On-Screen Keyboard (osk.exe), Narrator.exe (, and maybe other screen readers) all uses method 3.

![image](https://user-images.githubusercontent.com/1330321/86016307-32790580-ba55-11ea-93ea-ce7c6267b708.png)
(A screenshot showing the embedded program manifest of osk.exe with `uiAccess=true`)

---

Looks like the `uiAccess` flag can also protect the program from being accessed by other low-integrity programs (despite from still running unelevated), maybe we can use this "feature" to protect WT?
@yume-chan Cool, that's very interesting, thanks! Are `uiAccess` programs allowed to send keystrokes to other `uiAccess` programs? We still want OSK to be able to interact with windows terminal, and if this means other programs should at least be signed before it's allowed to send input to windows terminal, is that a high enough barrier?
> Are uiAccess programs allowed to send keystrokes to other uiAccess programs?

@mrwensveen Yes, programs with `uiAccess` privilege can access each other.

I prefer the `GetCurrentInputMessageSource` API way (https://github.com/microsoft/terminal/issues/632#issuecomment-651114562) cause this is not `uiAccess`'s intended usage. Also with the API we may still allow low-integrity programs to send keystrokes to unelevated tabs, while not to elevated ones.
Little workaround I've made here:

I've installed [PowerToys](https://github.com/microsoft/PowerToys) which has some cool features. One of them is to show the windows shortcuts and I've discovered that when you press Win + number, it opens the app in the windows bar correspondent to the number it appears in the bar.

So, I've putted the terminal in the bar as the first icon 
![image](https://user-images.githubusercontent.com/6886560/86020063-cf0fb900-b9fd-11ea-990c-e5052810c72d.png).

When I press Win + 1, the terminal opens. 

![image](https://user-images.githubusercontent.com/6886560/86020361-3299e680-b9fe-11ea-8c11-d057f0aa5b2a.png)

When I press Win + Ctrl + Shift + 1, it opens elevated.

![image](https://user-images.githubusercontent.com/6886560/86020423-45142000-b9fe-11ea-8c0d-4742b4ccb49a.png)

I'll put my [terminal configuration](https://gist.github.com/Bigous/6da7c4c581ad4c52106174a12b9d4b83) and [powershell profile](https://gist.github.com/Bigous/eca6f10e560403da6b4e9960d9a51f6d) here too if you wanna get the features of show the git branch and conda environment in the prompt and the user in red if it's an elevated terminal...

That's existed since at least Windows 7; it's not a PowerToys thing.
@Firehawke Yes, I just discovered because of PowerToys ... it's not needed thow.
Here's a profile for launching elevated that works on Windows Store & has a proper icon:
```json
{
    "name": "Windows Terminal (elevated)",
    "commandline": "pwsh.exe -command Start-Process -Verb RunAs \"shell:appsFolder\\Microsoft.WindowsTerminal_8wekyb3d8bbwe!App\"",
    "hidden": false,
    "icon": "ms-appx:///Images/Square44x44Logo.targetsize-32.png"
}
```

EDIT: Credit to @glooms, @shem-sargent, @LordFPL, and @Firehawke for different components of this snippet. As this command calls `pwsh.exe`, it looks like some people have ran into #4228 (a `0x80070002` error when launching) with this due to corrupted PATH environment variables or strange binaries in their path named `powershell.exe` or `pwsh.exe`. @zurkz fixed this by referencing `powershell.exe`, but I don't think that's reliable now. #6684 addresses this problem for Windows Terminal, and you'l find a fixed version below, following that solution, which shouldn't have this issue at all.
> Here's a profile for launching elevated that works on Windows Store & has a proper icon:
> 
> ```json
> {
>     "name": "Windows Terminal (elevated)",
>     "commandline": "pwsh.exe -command Start-Process -Verb RunAs \"shell:appsFolder\\Microsoft.WindowsTerminal_8wekyb3d8bbwe!App\"",
>     "hidden": false,
>     "icon": "ms-appx:///Images/Square44x44Logo.targetsize-32.png"
> }
> ```

@bb010g That works well! Thank you.
> Here's a profile for launching elevated that works on Windows Store & has a proper icon:
> 
> ```json
> {
>     "name": "Windows Terminal (elevated)",
>     "commandline": "pwsh.exe -command Start-Process -Verb RunAs \"shell:appsFolder\\Microsoft.WindowsTerminal_8wekyb3d8bbwe!App\"",
>     "hidden": false,
>     "icon": "ms-appx:///Images/Square44x44Logo.targetsize-32.png"
> }
> ```

@bb010g ❤💯
> Here's a profile for launching elevated that works on Windows Store & has a proper icon:
> 
> ```json
> {
>     "name": "Windows Terminal (elevated)",
>     "commandline": "pwsh.exe -command Start-Process -Verb RunAs \"shell:appsFolder\\Microsoft.WindowsTerminal_8wekyb3d8bbwe!App\"",
>     "hidden": false,
>     "icon": "ms-appx:///Images/Square44x44Logo.targetsize-32.png"
> }
> ```

@anyone Forgive my ignorance, does this get dropped in the Windows Store config? If so, can someone post the path? If not, where is this bad boy supposed to live?

TYIA! 
@Kazamario
It goes in the Windows Terminal settings.json file, in the profiles section.
It causes an error: `0x80070002` when launching. pwsh 7.1.
I changed it to: 

```json
{
    "name": "Windows Terminal (elevated)",
    "commandline": "powershell.exe -command Start-Process -Verb RunAs \"shell:appsFolder\\Microsoft.WindowsTerminal_8wekyb3d8bbwe!App\"",
    "hidden": false,
    "icon": "ms-appx:///Images/Square44x44Logo.targetsize-32.png"
}
```

and UAC prompted to elevate permissions.
> I changed it to:
> 
> ```json
> {
>     "name": "Windows Terminal (elevated)",
>     "commandline": "powershell.exe -command Start-Process -Verb RunAs \"shell:appsFolder\\Microsoft.WindowsTerminal_8wekyb3d8bbwe!App\"",
>     "hidden": false,
>     "icon": "ms-appx:///Images/Square44x44Logo.targetsize-32.png"
> }
> ```
> 
> and UAC prompted to elevate permissions.

that worked for me quite well. Thank you!
Here is how to start Windows Terminal elevated if it was pinned to Start.
https://github.com/farag2/Utilities/blob/master/Windows%20Terminal/Pin%20to%20Start.ps1
@narfanar It looks like you've ran into #4228, where Windows Terminal emits error `0x80070002` upon startup when the PATH environment variable is messed up or other binaries are floating around in the path named `powershell.exe` or `pwsh.exe`. I don't think @zurkz's snippet really fixes this, as it just shifts potential problems from `pwsh.exe` over to `powershell.exe`. #6684 fixed this for WT, so here's a snippet adjusted to that solution:

```json
{
    "name": "Windows Terminal (elevated)",
    "commandline": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -Command Start-Process -Verb RunAs \"shell:appsFolder\\Microsoft.WindowsTerminal_8wekyb3d8bbwe!App\"",
    "hidden": false,
    "icon": "ms-appx:///Images/Square44x44Logo.targetsize-32.png"
}
```
console-z does this well
Note that Cmder has this feature, which is incredible useful.  Would love to see it implemented in Windows Terminal.  Even if it has to launch a separate window for the Admin tabs or something..
my default profile is set to bash rather than powershell, and i'd like to keep it that way. the snippet above works great, but id love to be able to make it launch a new elevated terminal with the powershell profile loaded. ive spent like 3 hours trying to figure this out (not a big fan of / have much experience with powershell) and i can't figure it out -- pleaaaase help. it seems like there's some combination of single quotes, double quotes, escaping, spaces, newlines, that might make it work but i cannot get start-process and argumentlist to do what i want. ive boiled it down to : 

`Start-Process -Verb RunAs cmd.exe '/c start wt.exe -p "Windows PowerShell"'`
this works in a .ps1 file if i run it myself, i get a new elevated windows terminal with the powershell profile loaded.  but it does not work in the commandline parameter of settings.json, no matter how i try to mangle it, explicitly calling argumentlist instead of using cmd /c, various forms of escaping and quote usage, etc. 

`"commandline": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -Command Start-Process -Verb RunAs cmd.exe '/c start wt.exe -p \"Windows PowerShell\"'",`
does not work. the best i can do is get it to launch a weird hybrid of what i want. ill get an "Administrator: Ubuntu" window loaded, that looks like my bash profile but is actually running powershell. wrong font and everything. if i use that window to open a new powershell tab it will be elevated as desired. when its like this i can stick whatever garbage i want into the "Windows PowerShell" part of the profile loading and I get the exact same behavior, so I know it's not really attempting to load the profile i'm passing it.
So I'm having an issue trying to still run this as elevated, i've done every option listed above and i either get the "Can't find the file" error or this.

```
Start-Process : This command cannot be run due to the error: The system cannot find the file specified.
At line:1 char:1
+ Start-Process -Verb RunAs shell:appsFolder\\Microsoft.WindowsTerminal ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Start-Process], InvalidOperationException
    + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand
```


Anyone else having the issue still or haven't been able to get these to run just fine?
> my default profile is set to bash rather than powershell, and i'd like to keep it that way.

Me too. I run WSL most of the time, but every now and then I need to run PS elevated, and I'd like to do it in a tab of the new WT.
I was also unable to get any of the examples to work - even with correcting my file paths. I found and installed [**gsudo**](https://github.com/gerardog/gsudo) which can elevate the current tab, or be used as a profile to open an elevated tab in the same window. I am unsure if the solutions above started in a new window (some attempts I made before using `gsudo` would only start in a new window). It will open an UAC popup. 

This is the profile I am using:
``` 
{
    // Elevated Powershell using gsudo
    // https://github.com/gerardog/gsudo
    "name": "Elevated PowerShell",
    "commandline": "powershell.exe gsudo powershell.exe -nologo",
    "hidden": false,
    "icon": "ms-appx:///Images/Square44x44Logo.targetsize-32.png",
    "suppressApplicationTitle": true
}
```
I am using `supressApplicationTitle` so that the tab title not display **Administrator:** as its redundant with **Elevated**.
@ayfine If https://github.com/microsoft/terminal/issues/632#issuecomment-663686412 is indeed not working for you, could you send a transcription of the exact errors / unexpected behavior you're getting with that config? (Make sure to add in extra configuration, like `suppressApplicationTitle`, in as small as steps as possible, so that if any of your configuration is breaking WT it'll be easier to tell where & when it's happening.)

If any other configurations here got slightly further than the linked one for you, details on how those are breaking would also be appreciated.
@bb010g I am not encountering any error messages - my apologies for not being more precise in my reply. When using https://github.com/microsoft/terminal/issues/632#issuecomment-663686412 I ran in to the issue of Windows Terminal loading my WSL Ubuntu shell (my default). I had taken this originally to mean that it was not working correctly but I see now that in that new window, if I start a new (default profile) Powershell tab it is in fact elevated. Regardless, both by opening a new window and having to start a new tab within that, it's not any easier than running an elevated process from my start menu. What I described in my original reply provides with the exact behavior I was imagining. 
@ayfine - and I copied your gsudo example. That's a good-enough solution until something built-in is coded. Thanks.
@ayfine I tried the gsudo thing, but it's a pretty awful experience.  Any sort of TAB completion seems to break, and Unicode (non-ASCII) characters don't seem to display.  I'm guessing it's some sort of process that redirects input and output, and does a terrible job at it.  I think the solution with a separate window works better.
If you are having issues with gsudo please report them to @gerardog and not in this thread. Every message on this thread (this one included; sorry!) e-mails hundreds of subscribers. 

I am going to lock this thread to further non-maintainer comments, as we are reaching the point where further comments aren’t moving the discussion forward a meaningful amount.

Please file new issues if you have concerns that are **not** covered here. 

Fix patch:
diff --git a/OpenConsole.sln b/OpenConsole.sln
index 8e1ffdb2c1f..510b7a1a023 100644
--- a/OpenConsole.sln
+++ b/OpenConsole.sln
@@ -334,6 +334,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WpfTerminalTestNetCore", "s
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wt", "src\cascadia\wt\wt.vcxproj", "{506FD703-BAA7-4F6E-9361-64F550EC8FCA}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "elevate-shim", "src\cascadia\ElevateShim\elevate-shim.vcxproj", "{416FD703-BAA7-4F6E-9361-64F550EC8FCA}"
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.Settings.Editor", "src\cascadia\TerminalSettingsEditor\Microsoft.Terminal.Settings.Editor.vcxproj", "{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}"
 	ProjectSection(ProjectDependencies) = postProject
 		{CA5CAD1A-082C-4476-9F33-94B339494076} = {CA5CAD1A-082C-4476-9F33-94B339494076}
@@ -398,6 +400,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsTerminal.UIA.Tests",
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "api-ms-win-core-synch-l1-2-0", "src\api-ms-win-core-synch-l1-2-0\api-ms-win-core-synch-l1-2-0.vcxproj", "{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5}"
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utils", "Utils", "{61901E80-E97D-4D61-A9BB-E8F2FDA8B40C}"
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererAtlas", "src\renderer\atlas\atlas.vcxproj", "{8222900C-8B6C-452A-91AC-BE95DB04B95F}"
 EndProject
 Global
@@ -2759,6 +2763,43 @@ Global
 		{506FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|x64.Build.0 = Release|x64
 		{506FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|x86.ActiveCfg = Release|Win32
 		{506FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|x86.Build.0 = Release|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.AuditMode|ARM.ActiveCfg = AuditMode|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.AuditMode|DotNet_x64Test.ActiveCfg = AuditMode|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.AuditMode|DotNet_x86Test.ActiveCfg = AuditMode|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.AuditMode|x64.ActiveCfg = AuditMode|x64
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.AuditMode|x64.Build.0 = AuditMode|x64
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.AuditMode|x86.ActiveCfg = AuditMode|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.AuditMode|x86.Build.0 = AuditMode|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Debug|Any CPU.ActiveCfg = Debug|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Debug|ARM.ActiveCfg = Debug|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Debug|ARM64.ActiveCfg = Debug|ARM64
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Debug|ARM64.Build.0 = Debug|ARM64
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Debug|DotNet_x64Test.ActiveCfg = Debug|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Debug|DotNet_x86Test.ActiveCfg = Debug|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Debug|x64.ActiveCfg = Debug|x64
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Debug|x64.Build.0 = Debug|x64
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Debug|x86.ActiveCfg = Debug|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Debug|x86.Build.0 = Debug|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Fuzzing|Any CPU.ActiveCfg = Fuzzing|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Fuzzing|ARM.ActiveCfg = Fuzzing|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Fuzzing|ARM64.ActiveCfg = Fuzzing|ARM64
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Fuzzing|DotNet_x64Test.ActiveCfg = Fuzzing|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Fuzzing|DotNet_x86Test.ActiveCfg = Fuzzing|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Fuzzing|x64.ActiveCfg = Fuzzing|x64
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Fuzzing|x86.ActiveCfg = Fuzzing|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|Any CPU.ActiveCfg = Release|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|ARM.ActiveCfg = Release|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|ARM64.ActiveCfg = Release|ARM64
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|ARM64.Build.0 = Release|ARM64
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|DotNet_x64Test.ActiveCfg = Release|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|DotNet_x86Test.ActiveCfg = Release|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|x64.ActiveCfg = Release|x64
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|x64.Build.0 = Release|x64
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|x86.ActiveCfg = Release|Win32
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA}.Release|x86.Build.0 = Release|Win32
 		{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|Any CPU.ActiveCfg = Release|x64
 		{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|Any CPU.Build.0 = Release|x64
 		{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32}.AuditMode|Any CPU.Deploy.0 = Release|x64
@@ -3399,7 +3440,7 @@ Global
 		{CA5CAD1A-9A12-429C-B551-8562EC954746} = {59840756-302F-44DF-AA47-441A9D673202}
 		{CA5CAD1A-B11C-4DDB-A4FE-C3AFAE9B5506} = {BDB237B6-1D1D-400F-84CC-40A58FA59C8E}
 		{48D21369-3D7B-4431-9967-24E81292CF63} = {05500DEF-2294-41E3-AF9A-24E580B82836}
-		{CA5CAD1A-039A-4929-BA2A-8BEB2E4106FE} = {59840756-302F-44DF-AA47-441A9D673202}
+		{CA5CAD1A-039A-4929-BA2A-8BEB2E4106FE} = {61901E80-E97D-4D61-A9BB-E8F2FDA8B40C}
 		{58A03BB2-DF5A-4B66-91A0-7EF3BA01269A} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
 		{A22EC5F6-7851-4B88-AC52-47249D437A52} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
 		{A021EDFF-45C8-4DC2-BEF7-36E1B3B8CFE8} = {BDB237B6-1D1D-400F-84CC-40A58FA59C8E}
@@ -3411,10 +3452,11 @@ Global
 		{D3EF7B96-CD5E-47C9-B9A9-136259563033} = {04170EEF-983A-4195-BFEF-2321E5E38A1E}
 		{95B136F9-B238-490C-A7C5-5843C1FECAC4} = {05500DEF-2294-41E3-AF9A-24E580B82836}
 		{024052DE-83FB-4653-AEA4-90790D29D5BD} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
-		{067F0A06-FCB7-472C-96E9-B03B54E8E18D} = {59840756-302F-44DF-AA47-441A9D673202}
+		{067F0A06-FCB7-472C-96E9-B03B54E8E18D} = {61901E80-E97D-4D61-A9BB-E8F2FDA8B40C}
 		{6BAE5851-50D5-4934-8D5E-30361A8A40F3} = {81C352DB-1818-45B7-A284-18E259F1CC87}
 		{1588FD7C-241E-4E7D-9113-43735F3E6BAD} = {4DAF0299-495E-4CD1-A982-9BAC16A45932}
-		{506FD703-BAA7-4F6E-9361-64F550EC8FCA} = {59840756-302F-44DF-AA47-441A9D673202}
+		{506FD703-BAA7-4F6E-9361-64F550EC8FCA} = {61901E80-E97D-4D61-A9BB-E8F2FDA8B40C}
+		{416FD703-BAA7-4F6E-9361-64F550EC8FCA} = {61901E80-E97D-4D61-A9BB-E8F2FDA8B40C}
 		{CA5CAD1A-0B5E-45C3-96A8-BB496BFE4E32} = {77875138-BB08-49F9-8BB1-409C2150E0E1}
 		{CA5CAD1A-D7EC-4107-B7C6-79CB77AE2907} = {77875138-BB08-49F9-8BB1-409C2150E0E1}
 		{CA5CAD1A-082C-4476-9F33-94B339494076} = {77875138-BB08-49F9-8BB1-409C2150E0E1}
@@ -3433,6 +3475,7 @@ Global
 		{C323DAEE-B307-4C7B-ACE5-7293CBEFCB5B} = {BDB237B6-1D1D-400F-84CC-40A58FA59C8E}
 		{F19DACD5-0C6E-40DC-B6E4-767A3200542C} = {BDB237B6-1D1D-400F-84CC-40A58FA59C8E}
 		{9CF74355-F018-4C19-81AD-9DC6B7F2C6F5} = {89CDCC5C-9F53-4054-97A4-639D99F169CD}
+		{61901E80-E97D-4D61-A9BB-E8F2FDA8B40C} = {59840756-302F-44DF-AA47-441A9D673202}
 		{8222900C-8B6C-452A-91AC-BE95DB04B95F} = {05500DEF-2294-41E3-AF9A-24E580B82836}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json
index 8cbaa808ddc..a5922e3bc89 100644
--- a/doc/cascadia/profiles.schema.json
+++ b/doc/cascadia/profiles.schema.json
@@ -468,7 +468,12 @@
         "colorScheme": {
           "description": "The name of a color scheme to use, instead of the one specified by the profile",
           "type": "string"
-        }
+        },
+        "elevate": {
+          "type": "boolean",
+          "default": false,
+          "description": "This will override the profile's `elevate` setting."
+        },
       },
       "type": "object"
     },
@@ -1950,6 +1955,11 @@
           ],
           "type": "string"
         },
+        "elevate": {
+          "type": "boolean",
+          "default": false,
+          "description": "When true, this profile should always open in an elevated context. If the window isn't running as an Administrator, then a new elevated window will be created."
+        },
         "experimental.retroTerminalEffect": {
           "description": "When set to true, enable retro terminal effects. This is an experimental feature, and its continued existence is not guaranteed.",
           "type": "boolean"
diff --git a/src/cascadia/CascadiaPackage/CascadiaPackage.wapproj b/src/cascadia/CascadiaPackage/CascadiaPackage.wapproj
index 6e207c7bf10..48d8caffdf9 100644
--- a/src/cascadia/CascadiaPackage/CascadiaPackage.wapproj
+++ b/src/cascadia/CascadiaPackage/CascadiaPackage.wapproj
@@ -78,6 +78,9 @@
     <ProjectReference Include="$(OpenConsoleDir)src\host\exe\Host.EXE.vcxproj">
       <Project>{9CBD7DFA-1754-4A9D-93D7-857A9D17CB1B}</Project>
     </ProjectReference>
+    <ProjectReference Include="$(OpenConsoleDir)src\cascadia\ElevateShim\elevate-shim.vcxproj" >
+      <Project>{416fd703-baa7-4f6e-9361-64f550ec8fca}</Project>
+    </ProjectReference>
     <ProjectReference Include="$(OpenConsoleDir)src\host\proxy\Host.Proxy.vcxproj">
       <Project>{71CC9D78-BA29-4D93-946F-BEF5D9A3A6EF}</Project>
     </ProjectReference>
diff --git a/src/cascadia/ElevateShim/elevate-shim.cpp b/src/cascadia/ElevateShim/elevate-shim.cpp
new file mode 100644
index 00000000000..e9b4d859cfb
--- /dev/null
+++ b/src/cascadia/ElevateShim/elevate-shim.cpp
@@ -0,0 +1,53 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+#include <string>
+#include <filesystem>
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <wil/stl.h>
+#include <wil/resource.h>
+#include <wil/win32_helpers.h>
+#include <shellapi.h>
+
+// BODGY
+//
+// If we try to do this in the Terminal itself, then there's a bunch of weird
+// things that can go wrong and prevent the elevated Terminal window from
+// getting created. Specifically, if the origin Terminal exits right away after
+// spawning the elevated WT, then ShellExecute might not successfully complete
+// the elevation. What's even more, the Terminal will mysteriously crash
+// somewhere in XAML land.
+//
+// To mitigate this, the Terminal will call into us with the commandline it
+// wants elevated. We'll hang around until ShellExecute is finished, so that the
+// process can successfully elevate.
+
+#pragma warning(suppress : 26461) // we can't change the signature of wWinMain
+int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPWSTR pCmdLine, int)
+{
+    // All of the args passed to us (something like `new-tab -p {guid}`) are in
+    // pCmdLine
+
+    // Get the path to WindowsTerminal.exe, which should live next to us.
+    std::filesystem::path module{ wil::GetModuleFileNameW<std::wstring>(nullptr) };
+    // Swap elevate-shim.exe for WindowsTerminal.exe
+    module.replace_filename(L"WindowsTerminal.exe");
+
+    // Go!
+
+    // disable warnings from SHELLEXECUTEINFOW struct. We can't fix that.
+#pragma warning(push)
+#pragma warning(disable : 26476) // Macro uses naked union over variant.
+    SHELLEXECUTEINFOW seInfo{ 0 };
+#pragma warning(pop)
+
+    seInfo.cbSize = sizeof(seInfo);
+    seInfo.fMask = SEE_MASK_DEFAULT;
+    seInfo.lpVerb = L"runas"; // This asks the shell to elevate the process
+    seInfo.lpFile = module.c_str(); // This is `...\WindowsTerminal.exe`
+    seInfo.lpParameters = pCmdLine; // This is `new-tab -p {guid}`
+    seInfo.nShow = SW_SHOWNORMAL;
+    LOG_IF_WIN32_BOOL_FALSE(ShellExecuteExW(&seInfo));
+}
diff --git a/src/cascadia/ElevateShim/elevate-shim.rc b/src/cascadia/ElevateShim/elevate-shim.rc
new file mode 100644
index 00000000000..20d7e068e25
--- /dev/null
+++ b/src/cascadia/ElevateShim/elevate-shim.rc
@@ -0,0 +1,69 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.h"
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (United States) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#include ""winres.h""\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_APPICON             ICON                    "..\\..\\..\\res\\terminal.ico"
+
+#endif    // English (United States) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
diff --git a/src/cascadia/ElevateShim/elevate-shim.vcxproj b/src/cascadia/ElevateShim/elevate-shim.vcxproj
new file mode 100644
index 00000000000..f81353ad368
--- /dev/null
+++ b/src/cascadia/ElevateShim/elevate-shim.vcxproj
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{416fd703-baa7-4f6e-9361-64f550ec8fca}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>elevate-shim</RootNamespace>
+    <ProjectName>elevate-shim</ProjectName>
+    <TargetName>elevate-shim</TargetName>
+    <ConfigurationType>Application</ConfigurationType>
+  </PropertyGroup>
+
+  <Import Project="..\..\..\common.openconsole.props" Condition="'$(OpenConsoleDir)'==''" />
+  <Import Project="$(OpenConsoleDir)src\common.build.pre.props" />
+
+  <!-- Source Files -->
+  <ItemGroup>
+    <ClCompile Include="elevate-shim.cpp">
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <ResourceCompile Include="elevate-shim.rc" />
+  </ItemGroup>
+
+  <Import Project="$(OpenConsoleDir)src\common.build.post.props" />
+
+  <ItemDefinitionGroup>
+    <Link>
+      <!-- Remove all non-onecore dependencies -->
+      <AdditionalDependencies>onecore.lib</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+</Project>
diff --git a/src/cascadia/ElevateShim/resource.h b/src/cascadia/ElevateShim/resource.h
new file mode 100644
index 00000000000..62d8839e293
--- /dev/null
+++ b/src/cascadia/ElevateShim/resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by wt.rc
+//
+#define IDI_APPICON 101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp
index f2c6fac9d81..a3dcbb45f4e 100644
--- a/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp
+++ b/src/cascadia/LocalTests_TerminalApp/SettingsTests.cpp
@@ -69,6 +69,8 @@ namespace TerminalAppLocalTests
 
         TEST_METHOD(TestIterableColorSchemeCommands);
 
+        TEST_METHOD(TestElevateArg);
+
         TEST_CLASS_SETUP(ClassSetup)
         {
             return true;
@@ -1267,4 +1269,264 @@ namespace TerminalAppLocalTests
         }
     }
 
+    void SettingsTests::TestElevateArg()
+    {
+        static constexpr std::wstring_view settingsJson{ LR"(
+        {
+            "defaultProfile": "{6239a42c-0000-49a3-80bd-e8fdd045185c}",
+            "profiles": [
+                {
+                    "name": "profile0",
+                    "guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}",
+                    "commandline": "cmd.exe"
+                },
+                {
+                    "name": "profile1",
+                    "guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}",
+                    "elevate": true,
+                    "commandline": "pwsh.exe"
+                },
+                {
+                    "name": "profile2",
+                    "guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}",
+                    "elevate": false,
+                    "commandline": "wsl.exe"
+                }
+            ],
+            "keybindings": [
+                { "keys": ["ctrl+a"], "command": { "action": "newTab", "profile": "profile0" } },
+                { "keys": ["ctrl+b"], "command": { "action": "newTab", "profile": "profile1" } },
+                { "keys": ["ctrl+c"], "command": { "action": "newTab", "profile": "profile2" } },
+
+                { "keys": ["ctrl+d"], "command": { "action": "newTab", "profile": "profile0", "elevate": false } },
+                { "keys": ["ctrl+e"], "command": { "action": "newTab", "profile": "profile1", "elevate": false } },
+                { "keys": ["ctrl+f"], "command": { "action": "newTab", "profile": "profile2", "elevate": false } },
+
+                { "keys": ["ctrl+g"], "command": { "action": "newTab", "profile": "profile0", "elevate": true } },
+                { "keys": ["ctrl+h"], "command": { "action": "newTab", "profile": "profile1", "elevate": true } },
+                { "keys": ["ctrl+i"], "command": { "action": "newTab", "profile": "profile2", "elevate": true } },
+            ]
+        })" };
+
+        const winrt::guid guid0{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-0000-49a3-80bd-e8fdd045185c}") };
+        const winrt::guid guid1{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}") };
+        const winrt::guid guid2{ ::Microsoft::Console::Utils::GuidFromString(L"{6239a42c-2222-49a3-80bd-e8fdd045185c}") };
+
+        CascadiaSettings settings{ settingsJson, {} };
+
+        auto keymap = settings.GlobalSettings().ActionMap();
+        VERIFY_ARE_EQUAL(3u, settings.ActiveProfiles().Size());
+
+        const auto profile2Guid = settings.ActiveProfiles().GetAt(2).Guid();
+        VERIFY_ARE_NOT_EQUAL(winrt::guid{}, profile2Guid);
+
+        VERIFY_ARE_EQUAL(9u, keymap.KeyBindings().Size());
+
+        {
+            Log::Comment(L"profile.elevate=omitted, action.elevate=nullopt: don't auto elevate");
+
+            KeyChord kc{ true, false, false, false, static_cast<int32_t>('A'), 0 };
+            auto actionAndArgs = TestUtils::GetActionAndArgs(keymap, kc);
+            VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action());
+            const auto& realArgs = actionAndArgs.Args().try_as<NewTabArgs>();
+            VERIFY_IS_NOT_NULL(realArgs);
+            // Verify the args have the expected value
+            VERIFY_IS_NOT_NULL(realArgs.TerminalArgs());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty());
+            VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty());
+            VERIFY_ARE_EQUAL(L"profile0", realArgs.TerminalArgs().Profile());
+            VERIFY_IS_NULL(realArgs.TerminalArgs().Elevate());
+
+            const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, realArgs.TerminalArgs(), nullptr);
+            const auto termSettings = termSettingsResult.DefaultSettings();
+            VERIFY_ARE_EQUAL(L"cmd.exe", termSettings.Commandline());
+            VERIFY_ARE_EQUAL(false, termSettings.Elevate());
+        }
+        {
+            Log::Comment(L"profile.elevate=true, action.elevate=nullopt: DO auto elevate");
+
+            KeyChord kc{ true, false, false, false, static_cast<int32_t>('B'), 0 };
+            auto actionAndArgs = TestUtils::GetActionAndArgs(keymap, kc);
+            VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action());
+            const auto& realArgs = actionAndArgs.Args().try_as<NewTabArgs>();
+            VERIFY_IS_NOT_NULL(realArgs);
+            // Verify the args have the expected value
+            VERIFY_IS_NOT_NULL(realArgs.TerminalArgs());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty());
+            VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty());
+            VERIFY_ARE_EQUAL(L"profile1", realArgs.TerminalArgs().Profile());
+            VERIFY_IS_NULL(realArgs.TerminalArgs().Elevate());
+
+            const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, realArgs.TerminalArgs(), nullptr);
+            const auto termSettings = termSettingsResult.DefaultSettings();
+            VERIFY_ARE_EQUAL(L"pwsh.exe", termSettings.Commandline());
+            VERIFY_ARE_EQUAL(true, termSettings.Elevate());
+        }
+        {
+            Log::Comment(L"profile.elevate=false, action.elevate=nullopt: don't auto elevate");
+
+            KeyChord kc{ true, false, false, false, static_cast<int32_t>('C'), 0 };
+            auto actionAndArgs = TestUtils::GetActionAndArgs(keymap, kc);
+            VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action());
+            const auto& realArgs = actionAndArgs.Args().try_as<NewTabArgs>();
+            VERIFY_IS_NOT_NULL(realArgs);
+            // Verify the args have the expected value
+            VERIFY_IS_NOT_NULL(realArgs.TerminalArgs());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty());
+            VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty());
+            VERIFY_ARE_EQUAL(L"profile2", realArgs.TerminalArgs().Profile());
+            VERIFY_IS_NULL(realArgs.TerminalArgs().Elevate());
+
+            const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, realArgs.TerminalArgs(), nullptr);
+            const auto termSettings = termSettingsResult.DefaultSettings();
+            VERIFY_ARE_EQUAL(L"wsl.exe", termSettings.Commandline());
+            VERIFY_ARE_EQUAL(false, termSettings.Elevate());
+        }
+
+        {
+            Log::Comment(L"profile.elevate=omitted, action.elevate=false: don't auto elevate");
+
+            KeyChord kc{ true, false, false, false, static_cast<int32_t>('D'), 0 };
+            auto actionAndArgs = TestUtils::GetActionAndArgs(keymap, kc);
+            VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action());
+            const auto& realArgs = actionAndArgs.Args().try_as<NewTabArgs>();
+            VERIFY_IS_NOT_NULL(realArgs);
+            // Verify the args have the expected value
+            VERIFY_IS_NOT_NULL(realArgs.TerminalArgs());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty());
+            VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty());
+            VERIFY_ARE_EQUAL(L"profile0", realArgs.TerminalArgs().Profile());
+            VERIFY_IS_NOT_NULL(realArgs.TerminalArgs().Elevate());
+            VERIFY_IS_FALSE(realArgs.TerminalArgs().Elevate().Value());
+
+            const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, realArgs.TerminalArgs(), nullptr);
+            const auto termSettings = termSettingsResult.DefaultSettings();
+            VERIFY_ARE_EQUAL(L"cmd.exe", termSettings.Commandline());
+            VERIFY_ARE_EQUAL(false, termSettings.Elevate());
+        }
+        {
+            Log::Comment(L"profile.elevate=true, action.elevate=false: don't auto elevate");
+
+            KeyChord kc{ true, false, false, false, static_cast<int32_t>('E'), 0 };
+            auto actionAndArgs = TestUtils::GetActionAndArgs(keymap, kc);
+            VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action());
+            const auto& realArgs = actionAndArgs.Args().try_as<NewTabArgs>();
+            VERIFY_IS_NOT_NULL(realArgs);
+            // Verify the args have the expected value
+            VERIFY_IS_NOT_NULL(realArgs.TerminalArgs());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty());
+            VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty());
+            VERIFY_ARE_EQUAL(L"profile1", realArgs.TerminalArgs().Profile());
+            VERIFY_IS_NOT_NULL(realArgs.TerminalArgs().Elevate());
+            VERIFY_IS_FALSE(realArgs.TerminalArgs().Elevate().Value());
+
+            const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, realArgs.TerminalArgs(), nullptr);
+            const auto termSettings = termSettingsResult.DefaultSettings();
+            VERIFY_ARE_EQUAL(L"pwsh.exe", termSettings.Commandline());
+            VERIFY_ARE_EQUAL(false, termSettings.Elevate());
+        }
+        {
+            Log::Comment(L"profile.elevate=false, action.elevate=false: don't auto elevate");
+
+            KeyChord kc{ true, false, false, false, static_cast<int32_t>('F'), 0 };
+            auto actionAndArgs = TestUtils::GetActionAndArgs(keymap, kc);
+            VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action());
+            const auto& realArgs = actionAndArgs.Args().try_as<NewTabArgs>();
+            VERIFY_IS_NOT_NULL(realArgs);
+            // Verify the args have the expected value
+            VERIFY_IS_NOT_NULL(realArgs.TerminalArgs());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty());
+            VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty());
+            VERIFY_ARE_EQUAL(L"profile2", realArgs.TerminalArgs().Profile());
+            VERIFY_IS_NOT_NULL(realArgs.TerminalArgs().Elevate());
+            VERIFY_IS_FALSE(realArgs.TerminalArgs().Elevate().Value());
+
+            const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, realArgs.TerminalArgs(), nullptr);
+            const auto termSettings = termSettingsResult.DefaultSettings();
+            VERIFY_ARE_EQUAL(L"wsl.exe", termSettings.Commandline());
+            VERIFY_ARE_EQUAL(false, termSettings.Elevate());
+        }
+
+        {
+            Log::Comment(L"profile.elevate=omitted, action.elevate=true: DO auto elevate");
+
+            KeyChord kc{ true, false, false, false, static_cast<int32_t>('G'), 0 };
+            auto actionAndArgs = TestUtils::GetActionAndArgs(keymap, kc);
+            VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action());
+            const auto& realArgs = actionAndArgs.Args().try_as<NewTabArgs>();
+            VERIFY_IS_NOT_NULL(realArgs);
+            // Verify the args have the expected value
+            VERIFY_IS_NOT_NULL(realArgs.TerminalArgs());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty());
+            VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty());
+            VERIFY_ARE_EQUAL(L"profile0", realArgs.TerminalArgs().Profile());
+            VERIFY_IS_NOT_NULL(realArgs.TerminalArgs().Elevate());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().Elevate().Value());
+
+            const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, realArgs.TerminalArgs(), nullptr);
+            const auto termSettings = termSettingsResult.DefaultSettings();
+            VERIFY_ARE_EQUAL(L"cmd.exe", termSettings.Commandline());
+            VERIFY_ARE_EQUAL(true, termSettings.Elevate());
+        }
+        {
+            Log::Comment(L"profile.elevate=true, action.elevate=true: DO auto elevate");
+            KeyChord kc{ true, false, false, false, static_cast<int32_t>('H'), 0 };
+            auto actionAndArgs = TestUtils::GetActionAndArgs(keymap, kc);
+            VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action());
+            const auto& realArgs = actionAndArgs.Args().try_as<NewTabArgs>();
+            VERIFY_IS_NOT_NULL(realArgs);
+            // Verify the args have the expected value
+            VERIFY_IS_NOT_NULL(realArgs.TerminalArgs());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty());
+            VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty());
+            VERIFY_ARE_EQUAL(L"profile1", realArgs.TerminalArgs().Profile());
+            VERIFY_IS_NOT_NULL(realArgs.TerminalArgs().Elevate());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().Elevate().Value());
+
+            const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, realArgs.TerminalArgs(), nullptr);
+            const auto termSettings = termSettingsResult.DefaultSettings();
+            VERIFY_ARE_EQUAL(L"pwsh.exe", termSettings.Commandline());
+            VERIFY_ARE_EQUAL(true, termSettings.Elevate());
+        }
+        {
+            Log::Comment(L"profile.elevate=false, action.elevate=true: DO auto elevate");
+
+            KeyChord kc{ true, false, false, false, static_cast<int32_t>('I'), 0 };
+            auto actionAndArgs = TestUtils::GetActionAndArgs(keymap, kc);
+            VERIFY_ARE_EQUAL(ShortcutAction::NewTab, actionAndArgs.Action());
+            const auto& realArgs = actionAndArgs.Args().try_as<NewTabArgs>();
+            VERIFY_IS_NOT_NULL(realArgs);
+            // Verify the args have the expected value
+            VERIFY_IS_NOT_NULL(realArgs.TerminalArgs());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().Commandline().empty());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().StartingDirectory().empty());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().TabTitle().empty());
+            VERIFY_IS_FALSE(realArgs.TerminalArgs().Profile().empty());
+            VERIFY_ARE_EQUAL(L"profile2", realArgs.TerminalArgs().Profile());
+            VERIFY_IS_NOT_NULL(realArgs.TerminalArgs().Elevate());
+            VERIFY_IS_TRUE(realArgs.TerminalArgs().Elevate().Value());
+
+            const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, realArgs.TerminalArgs(), nullptr);
+            const auto termSettings = termSettingsResult.DefaultSettings();
+            VERIFY_ARE_EQUAL(L"wsl.exe", termSettings.Commandline());
+            VERIFY_ARE_EQUAL(true, termSettings.Elevate());
+        }
+    }
+
 }
diff --git a/src/cascadia/TerminalApp/TabManagement.cpp b/src/cascadia/TerminalApp/TabManagement.cpp
index 5048f8fd8bf..815916978f0 100644
--- a/src/cascadia/TerminalApp/TabManagement.cpp
+++ b/src/cascadia/TerminalApp/TabManagement.cpp
@@ -68,6 +68,17 @@ namespace winrt::TerminalApp::implementation
         const auto profile{ _settings.GetProfileForArgs(newTerminalArgs) };
         const auto settings{ TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, *_bindings) };
 
+        // Try to handle auto-elevation
+        if (_maybeElevate(newTerminalArgs, settings, profile))
+        {
+            return S_OK;
+        }
+        // We can't go in the other direction (elevated->unelevated)
+        // unfortunately. This seems to be due to Centennial quirks. It works
+        // unpackaged, but not packaged.
+        //
+        // This call to _MakePane won't return nullptr, we already checked that
+        // case above with the _maybeElevate call.
         _CreateNewTabFromPane(_MakePane(newTerminalArgs, false, existingConnection));
 
         const uint32_t tabCount = _tabs.Size();
@@ -240,8 +251,11 @@ namespace winrt::TerminalApp::implementation
     // - pane: The pane to use as the root.
     void TerminalPage::_CreateNewTabFromPane(std::shared_ptr<Pane> pane)
     {
-        auto newTabImpl = winrt::make_self<TerminalTab>(pane);
-        _InitializeTab(newTabImpl);
+        if (pane)
+        {
+            auto newTabImpl = winrt::make_self<TerminalTab>(pane);
+            _InitializeTab(newTabImpl);
+        }
     }
 
     // Method Description:
diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp
index c1d6487bf93..54dce0f0608 100644
--- a/src/cascadia/TerminalApp/TerminalPage.cpp
+++ b/src/cascadia/TerminalApp/TerminalPage.cpp
@@ -546,7 +546,24 @@ namespace winrt::TerminalApp::implementation
     void TerminalPage::_CompleteInitialization()
     {
         _startupState = StartupState::Initialized;
-        _InitializedHandlers(*this, nullptr);
+
+        // GH#632 - It's possible that the user tried to create the terminal
+        // with only one tab, with only an elevated profile. If that happens,
+        // we'll create _another_ process to host the elevated version of that
+        // profile. This can happen from the jumplist, or if the default profile
+        // is `elevate:true`, or from the commandline.
+        //
+        // However, we need to make sure to close this window in that scenario.
+        // Since there aren't any _tabs_ in this window, we won't ever get a
+        // closed event. So do it manually.
+        if (_tabs.Size() == 0)
+        {
+            _LastTabClosedHandlers(*this, nullptr);
+        }
+        else
+        {
+            _InitializedHandlers(*this, nullptr);
+        }
     }
 
     // Method Description:
@@ -862,6 +879,13 @@ namespace winrt::TerminalApp::implementation
         else
         {
             const auto newPane = _MakePane(newTerminalArgs);
+            // If the newTerminalArgs caused us to open an elevated window
+            // instead of creating a pane, it may have returned nullptr. Just do
+            // nothing then.
+            if (!newPane)
+            {
+                return;
+            }
             if (altPressed && !debugTap)
             {
                 this->_SplitPane(SplitDirection::Automatic,
@@ -1625,13 +1649,6 @@ namespace winrt::TerminalApp::implementation
                                   std::shared_ptr<Pane> newPane)
     {
         const auto focusedTab{ _GetFocusedTabImpl() };
-
-        // Do nothing if no TerminalTab is focused
-        if (!focusedTab)
-        {
-            return;
-        }
-
         _SplitPane(*focusedTab, splitDirection, splitSize, newPane);
     }
 
@@ -1649,6 +1666,14 @@ namespace winrt::TerminalApp::implementation
                                   const float splitSize,
                                   std::shared_ptr<Pane> newPane)
     {
+        // If the caller is calling us with the return value of _MakePane
+        // directly, it's possible that nullptr was returned, if the connections
+        // was supposed to be launched in an elevated window. In that case, do
+        // nothing here. We don't have a pane with which to create the split.
+        if (!newPane)
+        {
+            return;
+        }
         const float contentWidth = ::base::saturated_cast<float>(_tabContent.ActualWidth());
         const float contentHeight = ::base::saturated_cast<float>(_tabContent.ActualHeight());
         const winrt::Windows::Foundation::Size availableSpace{ contentWidth, contentHeight };
@@ -2251,7 +2276,13 @@ namespace winrt::TerminalApp::implementation
     //   a duplicate of the currently focused pane
     // - existingConnection: optionally receives a connection from the outside
     //   world instead of attempting to create one
-    std::shared_ptr<Pane> TerminalPage::_MakePane(const NewTerminalArgs& newTerminalArgs, const bool duplicate, TerminalConnection::ITerminalConnection existingConnection)
+    // Return Value:
+    // - If the newTerminalArgs required us to open the pane as a new elevated
+    //   connection, then we'll return nullptr. Otherwise, we'll return a new
+    //   Pane for this connection.
+    std::shared_ptr<Pane> TerminalPage::_MakePane(const NewTerminalArgs& newTerminalArgs,
+                                                  const bool duplicate,
+                                                  TerminalConnection::ITerminalConnection existingConnection)
     {
         TerminalSettingsCreateResult controlSettings{ nullptr };
         Profile profile{ nullptr };
@@ -2282,6 +2313,12 @@ namespace winrt::TerminalApp::implementation
             controlSettings = TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, *_bindings);
         }
 
+        // Try to handle auto-elevation
+        if (_maybeElevate(newTerminalArgs, controlSettings, profile))
+        {
+            return nullptr;
+        }
+
         auto connection = existingConnection ? existingConnection : _CreateConnectionFromSettings(profile, controlSettings.DefaultSettings());
         if (existingConnection)
         {
@@ -3458,6 +3495,98 @@ namespace winrt::TerminalApp::implementation
         return profile;
     }
 
+    // Function Description:
+    // - Helper to launch a new WT instance elevated. It'll do this by spawning
+    //   a helper process, who will asking the shell to elevate the process for
+    //   us. This might cause a UAC prompt. The elevation is performed on a
+    //   background thread, as to not block the UI thread.
+    // Arguments:
+    // - newTerminalArgs: A NewTerminalArgs describing the terminal instance
+    //   that should be spawned. The Profile should be filled in with the GUID
+    //   of the profile we want to launch.
+    // Return Value:
+    // - <none>
+    // Important: Don't take the param by reference, since we'll be doing work
+    // on another thread.
+    void TerminalPage::_OpenElevatedWT(NewTerminalArgs newTerminalArgs)
+    {
+        // BODGY
+        //
+        // We're going to construct the commandline we want, then toss it to a
+        // helper process called `elevate-shim.exe` that happens to live next to
+        // us. elevate-shim.exe will be the one to call ShellExecute with the
+        // args that we want (to elevate the given profile).
+        //
+        // We can't be the one to call ShellExecute ourselves. ShellExecute
+        // requires that the calling process stays alive until the child is
+        // spawned. However, in the case of something like `wt -p
+        // AlwaysElevateMe`, then the original WT will try to ShellExecute a new
+        // wt.exe (elevated) and immediately exit, preventing ShellExecute from
+        // successfully spawning the elevated WT.
+
+        std::filesystem::path exePath = wil::GetModuleFileNameW<std::wstring>(nullptr);
+        exePath.replace_filename(L"elevate-shim.exe");
+
+        // Build the commandline to pass to wt for this set of NewTerminalArgs
+        std::wstring cmdline{
+            fmt::format(L"new-tab {}", newTerminalArgs.ToCommandline().c_str())
+        };
+
+        wil::unique_process_information pi;
+        STARTUPINFOW si{};
+        si.cb = sizeof(si);
+
+        LOG_IF_WIN32_BOOL_FALSE(CreateProcessW(exePath.c_str(),
+                                               cmdline.data(),
+                                               nullptr,
+                                               nullptr,
+                                               FALSE,
+                                               0,
+                                               nullptr,
+                                               nullptr,
+                                               &si,
+                                               &pi));
+
+        // TODO: GH#8592 - It may be useful to pop a Toast here in the original
+        // Terminal window informing the user that the tab was opened in a new
+        // window.
+    }
+
+    // Method Description:
+    // - If the requested settings want us to elevate this new terminal
+    //   instance, and we're not currently elevated, then open the new terminal
+    //   as an elevated instance (using _OpenElevatedWT). Does nothing if we're
+    //   already elevated, or if the control settings don't want to be elevated.
+    // Arguments:
+    // - newTerminalArgs: The NewTerminalArgs for this terminal instance
+    // - controlSettings: The constructed TerminalSettingsCreateResult for this Terminal instance
+    // - profile: The Profile we're using to launch this Terminal instance
+    // Return Value:
+    // - true iff we tossed this request to an elevated window. Callers can use
+    //   this result to early-return if needed.
+    bool TerminalPage::_maybeElevate(const NewTerminalArgs& newTerminalArgs,
+                                     const TerminalSettingsCreateResult& controlSettings,
+                                     const Profile& profile)
+    {
+        // Try to handle auto-elevation
+        const bool requestedElevation = controlSettings.DefaultSettings().Elevate();
+        const bool currentlyElevated = IsElevated();
+
+        // We aren't elevated, but we want to be.
+        if (requestedElevation && !currentlyElevated)
+        {
+            // Manually set the Profile of the NewTerminalArgs to the guid we've
+            // resolved to. If there was a profile in the NewTerminalArgs, this
+            // will be that profile's GUID. If there wasn't, then we'll use
+            // whatever the default profile's GUID is.
+
+            newTerminalArgs.Profile(::Microsoft::Console::Utils::GuidToString(profile.Guid()));
+            _OpenElevatedWT(newTerminalArgs);
+            return true;
+        }
+        return false;
+    }
+
     // Method Description:
     // - Handles the change of connection state.
     // If the connection state is failure show information bar suggesting to configure termination behavior
@@ -3593,4 +3722,5 @@ namespace winrt::TerminalApp::implementation
 
         applicationState.DismissedMessages(std::move(messages));
     }
+
 }
diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h
index bf570d7e0eb..3995bd69424 100644
--- a/src/cascadia/TerminalApp/TerminalPage.h
+++ b/src/cascadia/TerminalApp/TerminalPage.h
@@ -411,6 +411,11 @@ namespace winrt::TerminalApp::implementation
 
         winrt::Microsoft::Terminal::Settings::Model::Profile GetClosestProfileForDuplicationOfProfile(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile) const noexcept;
 
+        bool _maybeElevate(const winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs,
+                           const winrt::Microsoft::Terminal::Settings::Model::TerminalSettingsCreateResult& controlSettings,
+                           const winrt::Microsoft::Terminal::Settings::Model::Profile& profile);
+        void _OpenElevatedWT(winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs newTerminalArgs);
+
         winrt::fire_and_forget _ConnectionStateChangedHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args) const;
         void _CloseOnExitInfoDismissHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args) const;
         void _KeyboardServiceWarningInfoDismissHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::Foundation::IInspectable& args) const;
diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.h b/src/cascadia/TerminalSettingsModel/ActionArgs.h
index 1da433ca092..072c54f2cfa 100644
--- a/src/cascadia/TerminalSettingsModel/ActionArgs.h
+++ b/src/cascadia/TerminalSettingsModel/ActionArgs.h
@@ -247,6 +247,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
         ACTION_ARG(winrt::hstring, Profile, L"");
         ACTION_ARG(Windows::Foundation::IReference<bool>, SuppressApplicationTitle, nullptr);
         ACTION_ARG(winrt::hstring, ColorScheme);
+        ACTION_ARG(Windows::Foundation::IReference<bool>, Elevate, nullptr);
 
         static constexpr std::string_view CommandlineKey{ "commandline" };
         static constexpr std::string_view StartingDirectoryKey{ "startingDirectory" };
@@ -256,6 +257,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
         static constexpr std::string_view ProfileKey{ "profile" };
         static constexpr std::string_view SuppressApplicationTitleKey{ "suppressApplicationTitle" };
         static constexpr std::string_view ColorSchemeKey{ "colorScheme" };
+        static constexpr std::string_view ElevateKey{ "elevate" };
 
     public:
         hstring GenerateName() const;
@@ -273,7 +275,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
                        otherAsUs->_ProfileIndex == _ProfileIndex &&
                        otherAsUs->_Profile == _Profile &&
                        otherAsUs->_SuppressApplicationTitle == _SuppressApplicationTitle &&
-                       otherAsUs->_ColorScheme == _ColorScheme;
+                       otherAsUs->_ColorScheme == _ColorScheme &&
+                       otherAsUs->_Elevate == _Elevate;
             }
             return false;
         };
@@ -289,6 +292,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
             JsonUtils::GetValueForKey(json, TabColorKey, args->_TabColor);
             JsonUtils::GetValueForKey(json, SuppressApplicationTitleKey, args->_SuppressApplicationTitle);
             JsonUtils::GetValueForKey(json, ColorSchemeKey, args->_ColorScheme);
+            JsonUtils::GetValueForKey(json, ElevateKey, args->_Elevate);
             return *args;
         }
         static Json::Value ToJson(const Model::NewTerminalArgs& val)
@@ -307,6 +311,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
             JsonUtils::SetValueForKey(json, TabColorKey, args->_TabColor);
             JsonUtils::SetValueForKey(json, SuppressApplicationTitleKey, args->_SuppressApplicationTitle);
             JsonUtils::SetValueForKey(json, ColorSchemeKey, args->_ColorScheme);
+            JsonUtils::SetValueForKey(json, ElevateKey, args->_Elevate);
             return json;
         }
         Model::NewTerminalArgs Copy() const
@@ -320,6 +325,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
             copy->_Profile = _Profile;
             copy->_SuppressApplicationTitle = _SuppressApplicationTitle;
             copy->_ColorScheme = _ColorScheme;
+            copy->_Elevate = _Elevate;
             return *copy;
         }
         size_t Hash() const
@@ -338,6 +344,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
             h.write(Profile());
             h.write(SuppressApplicationTitle());
             h.write(ColorScheme());
+            h.write(Elevate());
         }
     };
 }
diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.idl b/src/cascadia/TerminalSettingsModel/ActionArgs.idl
index 576e3704f96..61cc5d2f85d 100644
--- a/src/cascadia/TerminalSettingsModel/ActionArgs.idl
+++ b/src/cascadia/TerminalSettingsModel/ActionArgs.idl
@@ -117,13 +117,20 @@ namespace Microsoft.Terminal.Settings.Model
         String TabTitle;
         Windows.Foundation.IReference<Windows.UI.Color> TabColor;
         String Profile; // Either a GUID or a profile's name if the GUID isn't a match
+
+        // We use IReference<> to treat some args as nullable where null means
+        // "use the inherited value". See ProfileIndex,
+        // SuppressApplicationTitle, Elevate. Strings that behave this way just
+        // use `null` as "use the inherited value".
+
         // ProfileIndex can be null (for "use the default"), so this needs to be
         // a IReference, so it's nullable
         Windows.Foundation.IReference<Int32> ProfileIndex { get; };
-
         Windows.Foundation.IReference<Boolean> SuppressApplicationTitle;
-
         String ColorScheme;
+        // This needs to be an optional so that the default value (null) does
+        // not modify whatever the profile's value is (either true or false)
+        Windows.Foundation.IReference<Boolean> Elevate { get; };
 
         Boolean Equals(NewTerminalArgs other);
         String GenerateName();
diff --git a/src/cascadia/TerminalSettingsModel/MTSMSettings.h b/src/cascadia/TerminalSettingsModel/MTSMSettings.h
index 0d5faab1769..663fff126c4 100644
--- a/src/cascadia/TerminalSettingsModel/MTSMSettings.h
+++ b/src/cascadia/TerminalSettingsModel/MTSMSettings.h
@@ -75,7 +75,8 @@ Author(s):
     X(hstring, TabTitle, "tabTitle")                                                                                                                           \
     X(Model::BellStyle, BellStyle, "bellStyle", BellStyle::Audible)                                                                                            \
     X(bool, UseAtlasEngine, "experimental.useAtlasEngine", false)                                                                                              \
-    X(Windows::Foundation::Collections::IVector<winrt::hstring>, BellSound, "bellSound", nullptr)
+    X(Windows::Foundation::Collections::IVector<winrt::hstring>, BellSound, "bellSound", nullptr)                                                              \
+    X(bool, Elevate, "elevate", false)
 
 #define MTSM_FONT_SETTINGS(X)                                                          \
     X(hstring, FontFace, "face", DEFAULT_FONT_FACE)                                    \
diff --git a/src/cascadia/TerminalSettingsModel/Profile.idl b/src/cascadia/TerminalSettingsModel/Profile.idl
index 41b9c9e018f..d54c6431a53 100644
--- a/src/cascadia/TerminalSettingsModel/Profile.idl
+++ b/src/cascadia/TerminalSettingsModel/Profile.idl
@@ -81,5 +81,7 @@ namespace Microsoft.Terminal.Settings.Model
         INHERITABLE_PROFILE_SETTING(BellStyle, BellStyle);
         INHERITABLE_PROFILE_SETTING(Boolean, UseAtlasEngine);
         INHERITABLE_PROFILE_SETTING(Windows.Foundation.Collections.IVector<String>, BellSound);
+
+        INHERITABLE_PROFILE_SETTING(Boolean, Elevate);
     }
 }
diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp b/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp
index bf854ab2e56..491affc5e7f 100644
--- a/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp
+++ b/src/cascadia/TerminalSettingsModel/TerminalSettings.cpp
@@ -155,6 +155,14 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
                     defaultSettings.ApplyColorScheme(scheme);
                 }
             }
+            // Elevate on NewTerminalArgs is an optional value, so the default
+            // value (null) doesn't override a profile's value. Note that
+            // elevate:false in an already elevated terminal does nothing - the
+            // profile will still be launched elevated.
+            if (newTerminalArgs.Elevate())
+            {
+                defaultSettings.Elevate(newTerminalArgs.Elevate().Value());
+            }
         }
 
         return settingsPair;
@@ -255,6 +263,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
             const til::color colorRef{ profile.TabColor().Value() };
             _TabColor = static_cast<winrt::Microsoft::Terminal::Core::Color>(colorRef);
         }
+
+        _Elevate = profile.Elevate();
     }
 
     // Method Description:
diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettings.h b/src/cascadia/TerminalSettingsModel/TerminalSettings.h
index 2c97dd8be9f..23ebb390b93 100644
--- a/src/cascadia/TerminalSettingsModel/TerminalSettings.h
+++ b/src/cascadia/TerminalSettingsModel/TerminalSettings.h
@@ -152,6 +152,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
         INHERITABLE_SETTING(Model::TerminalSettings, hstring, PixelShaderPath);
         INHERITABLE_SETTING(Model::TerminalSettings, bool, IntenseIsBold);
 
+        INHERITABLE_SETTING(Model::TerminalSettings, bool, Elevate, false);
+
     private:
         std::optional<std::array<Microsoft::Terminal::Core::Color, COLOR_TABLE_SIZE>> _ColorTable;
         gsl::span<Microsoft::Terminal::Core::Color> _getColorTableImpl();
diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettings.idl b/src/cascadia/TerminalSettingsModel/TerminalSettings.idl
index d6b6e395d6d..e2345e0748e 100644
--- a/src/cascadia/TerminalSettingsModel/TerminalSettings.idl
+++ b/src/cascadia/TerminalSettingsModel/TerminalSettings.idl
@@ -39,5 +39,7 @@ namespace Microsoft.Terminal.Settings.Model
         String Commandline { set; };
         String StartingDirectory { set; };
         String EnvironmentVariables { set; };
+
+        Boolean Elevate;
     };
 }


Test patch: