microsoft / sudo

It's sudo, for Windows
MIT License
5.01k stars 130 forks source link

megathread: sudo should better support PowerShell #5

Open zadjii-msft opened 8 months ago

zadjii-msft commented 8 months ago

Currently, sudo only works for elevating an actual executable[^1]. For something like Get-ChildItem (gci) in PowerShell, that's not an executable, it's a cmdlet. We'll need a proper PowerShell module to be able to properly support various PowerShell scenarios.

In the time being, we're working on the sudo.ps1 script to provide a better experience for using sudo from PowerShell.

### Tasks
- [ ] Support for PowerShell cmdlets
- [ ] Support for PowerShell script blocks
- [ ] Support for PowerShell aliases
- [ ] Should `sudo.ps1` pass `-noprofile` to the elevated PowerShell?
- [ ] #6 

[^1]: It also supports CMD intrinsics, when run from CMD.exe.

gerardog commented 7 months ago

My two cents are... The less, the better.

PowerShell already has some degree of support for Unix/Linux sudo both on Linux and WSL, thanks to the so-called "MiniShell mode" image

When PS invokes an external command and finds a scriptblock, it serializes it and adds special arguments to allow Standard I/O CLIXML serialization. It also auto-fallbacks to output-format text if you don't capture the result (which really improves performance). Here is a dump of how it works:

image

This makes sudo pwsh {scriptblock} -args $arg1, $arg2... syntax work out-of-the-box on Linux's sudo, gsudo, and ms-sudo.

gsudo has syntax sugar for shell detection, which makes the pwsh word not required. You can do that by prepending pwsh.exe to the command to elevate when it starts with -encodedCommand. Beware than doing that may confuse users, making them believe the elevation is running in-process.

Regarding other syntaxes besides ScriptBlocks, such as sudo Do-Something:

Another debatable reason for sudo.ps1 may be to implement sudo !!, but in my opinion, that feature, a relic of the 1980s, is frustrating in modern PowerShell. Try it on gsudo. I hate it, even though I coded it

Lastly, when you run sudo Do-Something your out of process sudo.exe will never know if Do-Something is an .exe or a PS alias. A sudo.ps1 could detect that, but helplessly won't be able to ensure that Do-Something function has the exact source on the elevated pwsh.

For all these reasons, plus the difficulty of per-user installation, I think shipping a sudo.ps1 should be avoided.

What I suggest, is to add an auto-completion script to ms-sudo, to be added to each $PROFILE, like sudo completition powershell | Invoke-Expression, analog to kubectl completion powershell | Out-String | Invoke-Expression See docs. Once that is implemented, sudo+[tab-key] can be a modern sudo !! and auto-complete with your last ran command, (but rewritten with the {scriptblock} syntax. Extra points if it detects the $variables and replace them with args[0], args[1], and so... for example:

PS C:\> $process = 'notepad.exe'

PS C:\> Get-Process $process | Stop-Process
Stop-Process: Access Denied.

PS C:\> sudo [press-tab-key]
[Then the line auto completes as:]

PS C:\> sudo pwsh {Get-Process $args[0] | Stop-Process } -args $process

This autocompletion script micro-spec, would work for Linux sudo too... So maybe is in the interest of the PowerShell team to implement ?

I hope you find this insights useful.

mominshaikhdevs commented 7 months ago

PowerShell should not be the shell of priority here. Rather, all "Shell Specific Commamnds" can be supported through sudo as said in https://github.com/microsoft/sudo/issues/62#issuecomment-1983550167

tusharsnx commented 6 months ago

I wonder if sudo is expected to work with shell builtins like PowerShell Cmdlets.

https://superuser.com/questions/241129/why-wont-sudo-cd-work

if the user just adds some parenthesis then part of the command now runs before the sudo invocation, which makes things confusing

Isn't that how sudo works on linux too? You should escape parts of the command if you want it to be executed in the sudo context, otherwise it is always computed before sudo is run 🤔

masterflitzer commented 3 months ago

I wonder if sudo is expected to work with shell builtins like PowerShell Cmdlets Isn't that how sudo works on linux too?

interesting perspective, bash on linux doesn't have cmdlets like pwsh on windows has, so you're right cmdlets are not commands so the correct way would be sudo COMMAND and sudo pwsh -c CMDLET, even though sudo CMDLET would be more convenient