maxwellb
maxwellb

Reputation: 13944

How to run PowerShell pwsh command with sudo

How can I use sudo to run a command (for example get-childitem) in PowerShell Core?

Using get-childitem on a path not visible to the current user:

$ get-childitem -path /sys/kernel/debug     
get-childitem : Access to the path '/sys/kernel/debug' is denied.
At line:1 char:1
+ get-childitem -path /sys/kernel/debug
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : PermissionDenied: (/sys/kernel/debug:String) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand

But trying to use sudo results in "command not found":

$ sudo get-childitem -path /sys/kernel/debug
sudo: get-childitem: command not found

Upvotes: 2

Views: 3624

Answers (1)

maxwellb
maxwellb

Reputation: 13944

To use the same semantics for sudo as you would in a POSIX shell (bash, etc.), create a wrapper function and an alias for it. Place these in your $profile for them to be available every time you are in pwsh.

$ cat $profile

function Invoke-MySudo { & /usr/bin/env sudo pwsh -command "& $args" }
set-alias sudo invoke-mysudo
  • /usr/bin/env sudo - This avoids recursively calling the alias "sudo". Or any other rewriting of the name "sudo" in the current session.
  • The desired command is run inside an elevated pwsh session via sudo. Default aliases such as pwd -> Get-Location will be used if they are called.

Result:

$ sudo get-childitem -path /sys/kernel/debug | head
[sudo] password for user: 


    Directory: /sys/kernel/debug

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----           5/22/19  8:35 AM                acpi
d-----           5/22/19  8:35 AM                asoc
d-----           5/22/19  3:32 PM                bdi
d-----           5/22/19  3:32 PM                block

Because the current shell is still pwsh, the pipeline has all the trimmings of a command invoked in PowerShell, such as foreach-object and where-object.

To use pipeline chaining in the context of the elevated user, provide the entire expression as a string. Any piping outside of the sudo command will operate on the results of the standard output of the invoked command.

$ sudo 'get-childitem -path /sys/kernel/debug `
    | where-object { $_.name -like ''b*'' } `
    | foreach-object { write-host $_.fullname } ' `
  | foreach-object {
    "{0} ... {1}" -f $_.GetType(), $_.ToUpper() | write-host
  }
System.String ... /SYS/KERNEL/DEBUG/BDI
System.String ... /SYS/KERNEL/DEBUG/BLOCK
System.String ... /SYS/KERNEL/DEBUG/BLUETOOTH
System.String ... /SYS/KERNEL/DEBUG/BTRFS

Upvotes: 2

Related Questions