在 PowerShell 中工作时,我倾向于通过键入快速切换到管理模式
Start-Process wt -Verb runas
当我这样做时,会出现一个新窗口(遗憾的是,Windows 中没有
sudo
)。然而,在新的会议中,环境是全新的。在跳转到新窗口时是否可以保留变量、别名、工作目录和所有其他类似内容?如果没有,那么,这是一个有效的答案。
举个例子,我正在寻找这种行为:
C:\test> $x = 123
C:\test> Start-Process wt
C:\test> $x
123
根据设计,提升的会话 (
-Verb RunAs
) 不继承调用者的环境变量。
此外,无论您是否使用
-Verb RunAs
,当您启动另一个 PowerShell 进程(例如使用 Start-Process
)时, 会话的状态(别名、函数、当前位置...)都不会被继承。 。
# Define a few things to copy to the elevated session.
$x1 = 123
$x2 = '3" of snow' # !! See the caveat re regular variables below.
$env:foo = 1
$env:foo2 = 2
Set-Alias bar Get-Date
function baz { "hello, world" }
# Note: The following only copies the definitions above.
# You could try to copy ALL such definitions, by omitting a target name / pattern:
# Get-ChildItem env:
# Get-ChildItem function:
# Get-ChildItem alias:
# CAVEAT: This will NOT generally work with *regular variables*.
Start-Process -Verb RunAs powershell @"
-NoExit -Command Set-Location -LiteralPath \"$((Get-Location -PSProvider FileSystem).ProviderPath)\"
$(Get-Variable x? | ForEach-Object { "`${$($_.Name)} = $(if ($_.Value -is [string]) { "'{0}'" -f ($_.Value -replace "'", "''" -replace '"', '\"') } else { $_.Value }); " })
$(Get-ChildItem env:foo* | ForEach-Object { "Set-Item \`"env:$($_.Name)\`" \`"$($_.Value -replace '"', '\"\"')\`"; " })
$(Get-ChildItem function:bar | ForEach-Object { "`$function:$($_.Name) = \`"$($_.Definition -replace '"', '\"\"')\`"; " })
$(Get-ChildItem alias:baz | ForEach-Object { "`$alias:$($_.Name) = \`"$($_.Definition)\`"; " })
"@
重要:
wt.exe
) 的调用,因为这会创建另一个 PowerShell 会话,这意味着只会为 that 会话保留以下定义:
-d
选项:
wt.exe -d \"$((Get-Location -PSProvider FileSystem).ProviderPath)\"
-WindowStyle Hidden
添加到
Start-Process
,在参数列表中删除
-NoExit
之前的
-Command
,并添加
wt.exe
调用在底部。
powershell
会话中工作,但是,该会话总是使用regular (
conhost.exe
) 控制台窗口。
文件中。 作为补充,请参阅
这个答案以获取便利功能Enter-AdminPSSession
,它允许您传递一个脚本块以在提升的会话中执行,您可以将调用者状态中的值作为参数传递给该脚本块。注:
Windows PowerShell CLI,powershell.exe
。要使用PowerShell (Core) 7+,请替换
pwsh.exe
。
通用方式保留当前的文件系统位置、环境变量、别名和函数。
警告:相比之下,保留常规变量仅限于字符串和数字 - 本质上,这些数据类型的实例,其字符串化表示在解释为源代码文字时被识别为此类。
-EncodedCommand
和
-EncodedArguments
参数的 Base64 编码,支持更多数据类型是可能的,如这个答案所示,但是可以用类型保真度表示的类型范围从根本上来说是有限的。受到 PowerShell 基于 XML 的序列化基础设施的限制 - 请参阅此答案。
当您打开新窗口时,只需调用脚本即可为您提供与其他窗口中相同的信息。