forked from lukesampson/psutils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sudo.ps1
79 lines (64 loc) · 2.16 KB
/
sudo.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
Set-StrictMode -Off;
if(!$args) { "usage: sudo <cmd...>"; exit 1 }
$powershellExe = 'powershell.exe'
if ($host.Version.Major -gt 5) {
$powershellExe = 'pwsh.exe'
}
function is_admin {
return ([System.Security.Principal.WindowsIdentity]::GetCurrent().UserClaims | ? { $_.Value -eq 'S-1-5-32-544'})
}
function sudo_do($parent_pid, $dir, $cmd) {
$src = 'using System.Runtime.InteropServices;
public class Kernel {
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool AttachConsole(uint dwProcessId);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
public static extern bool FreeConsole();
}'
$kernel = add-type $src -passthru
$kernel::freeconsole()
$kernel::attachconsole($parent_pid)
$p = new-object diagnostics.process; $start = $p.startinfo
$start.filename = "$powershellExe"
$start.arguments = "-noprofile -Command $cmd`nexit `$lastexitcode"
$start.useshellexecute = $false
$start.workingdirectory = $dir
$p.start()
$p.waitforexit()
return $p.exitcode
}
function serialize($a, $escape) {
if($a -is [string] -and $a -match '\s') { return "'$a'" }
if($a -is [array]) {
return $a | % { (serialize $_ $escape) -join ', ' }
}
if($escape) { return $a -replace '[>&]', '`$0' }
return $a
}
if($args[0] -eq '-do') {
$null, $dir, $parent_pid, $cmd = $args
$exit_code = sudo_do $parent_pid $dir (serialize $cmd)
exit $exit_code
}
if(!(is_admin)) {
[console]::error.writeline("sudo: you must be an administrator to run sudo")
exit 1
}
$a = if ($args[0] -eq '-please' -or $args[0] -eq '-plz') {
Get-History -Count 1 | select -ExpandProperty CommandLine
} else {
serialize $args $true
}
$wd = serialize (convert-path $pwd) # convert-path in case pwd is a PSDrive
$savetitle = $host.ui.rawui.windowtitle
$p = new-object diagnostics.process; $start = $p.startinfo
$start.filename = "$powershellExe"
$start.arguments = "-noprofile -Command & '$pscommandpath' -do $wd $pid $a`nexit `$lastexitcode"
$start.verb = 'runas'
$start.UseShellExecute = $true
$start.windowstyle = 'hidden'
try { $null = $p.start() }
catch { exit 1 } # user didn't provide consent
$p.waitforexit()
$host.ui.rawui.windowtitle = $savetitle
exit $p.exitcode