Powershell 添加 su 命令

作者: EricKwoc | 来源:发表于2018-12-31 17:12 被阅读0次

    因为 Linux 用习惯了,没有 su/sudo命令总觉得不太方便,经过一番搜索,决定自己来实现一个 su 命令。
    基本思路是:

    • 通过别名来调用一个自定义函数(函数可以写在类似于 .bashrc 这样的文件里)
    • 函数要能提权(不需要绕过UAC)

    实现

    那么我们先确定 .bashrc 类似的配置文件的位置。

    > Get-Variable PROFILE
    
    Name                           Value
    ----                           -----
    PROFILE                        C:\Users\Yourname\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
    

    然后用编辑器(如 Notepad++ 或 Notepad2)打开这个文件,在里面输入如下内容:

    function su-fun {Start-Process powershell -Verb runAs -argumentlist '-NoExit', "cd '$pwd'"}
    set-alias su su-fun
    set-alias sudo su-fun
    

    保存即可。

    解析:

    首先我们看这一句

    Start-Process powershell -Verb runAs -argumentlist '-NoExit', "cd '$pwd'"
    

    前半段很好理解,Start-Process powershell -Verb runAs就是新建一个 Powershell 窗口,后面的 -verb runAs 就是 “Run as Administrator 的意思,也就是以管理员身份启动一个新的 Powershell 窗口。

    后半段是什么意思呢?细心的人会发现,通过之前那句命令启动的 shell 的工作目录是在默认工作目录,也就是C:\Windows\System32,而不是我们之前的位置。那么我们怎么样吧工作目录传递过去呢?

    首先我想到的是 start-process-WorkingDirectory <String> 参数,但是实际测试发现不管用,应该是安全起见,RunAs 和 WorkingDirectory 不能同时启用,请参见 Stack Overflow

    In practice, as of PSv5 – and the docs do not mention that – the -WorkingDirectory parameter is not respected if you start a process elevated (with administrative privileges, which is what -Verb RunAs – somewhat obscurely – does): the location defaults to $env:SYSTEMROOT\system32 (typically, C:\Windows\System32)

    与此同时,该贴答主还贴出了解决方案

    Start-Process -FilePath powershell.exe -Verb Runas -ArgumentList '-NoExit', '-Command', 'cd C:\ws'
    

    也就是说,把 cd xxx 作为一个命令传入新开的 Powershell 中。
    但我们不能照搬嘛,我们要把 C:\ws 改成我们的当前目录,而在 Powershell 中,存有当前目录的变量就是 $pwd,于是命令便顺理成章地变成了

    Start-Process -FilePath powershell.exe -Verb Runas `
      -ArgumentList '-NoExit', '-Command', "cd '$pwd'"
    

    $pwd 外加上了引号,避免路径中包含空格时出问题

    命令有了,怎么让这个命令拥有别名呢?当然,我们可以把这个命令保存为批处理脚本放到 C:\Windows\System32,但这样毕竟不优雅,有没有不用脚本也能达到相同效果的呢?我首先想到的就是 Set-Alias 这个命令,Alias 就是别名的意思嘛。但是 Set-Alias 不能设置这么长的命令的别名,怎么办呢?

    又是一番搜索,找到了这个How to create a complex powershell alias

    里面提到,可以先用 function 把要执行的代码块包起来,然后给这个 function 一个别名。

    于是整体思路就出来了:在配置文档里面用 function 创建代码块,并且给它一个别名。

    function sudo-fun {Start-Process powershell -Verb runAs -argumentlist '-NoExit', "cd '$pwd'"}
    set-alias sudo sudo-fun
    
    

    DEBUG

    若出现如图所示错误,是因为你的系统为了自保护,默认禁用了ps脚本(也就是我们的配置文件)的执行,我们需要用管理员身份执行这个命令 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser 来允许它

    这样子就可以了

    参考:about_Execution_Policies

    参考文档:Start-Process - Microsoft Docs

    EOF

    相关文章

      网友评论

        本文标题:Powershell 添加 su 命令

        本文链接:https://www.haomeiwen.com/subject/oikwlqtx.html