如何在保持环境不变的情况下在单独的窗口中启动另一个 PowerShell 会话?
在使用 PowerShell 时,我倾向于通过键入“
Start-Process wt -Verb runas
当我这样做时,会出现一个新窗口”来快速切换到管理模式(遗憾的是,Windows 中没有 sudo
)。然而,在新的会议中,环境是全新的。在跳转到新窗口时是否可以保留变量、别名、工作目录和所有其他类似内容?如果没有,那么,这是一个有效的答案。
举个例子,我正在寻找这种行为:
第一个窗口
C:\test> $x = 123
C:\test> Start-Process wt
新窗口
C:\test> $x
123
While working in PowerShell I tend to quickly switch to admin mode by typing
Start-Process wt -Verb runas
When I do so, a new window appears (sadly, no sudo
in Windows). In that new session however, the environment is totally fresh. Is it possible to keep variables, aliases, working dir and all other stuff of similar matter while jumping to a new window? If not, then well, it's a valid answer.
To give some example, I am looking for this behavior:
First window
C:\test> $x = 123
C:\test> Start-Process wt
New window
C:\test> $x
123
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
根据设计,提升会话 (
-Verb RunAs
)不会继承调用者的环境变量甚至显式尝试通过环境都会被 底层 .NET API。[1]另外,无论您是否使用
-Verb RunAs
,a 的状态 PowerShell 会话(别名、函数、仅 shell 变量等)在启动另一个 PowerShell 进程时永远不会被继承,例如与启动进程
。一种解决方法是根据调用者状态的值,通过在提升的会话中执行的命令显式地、选择性地重新创建感兴趣的状态,但这非常麻烦并且有局限性,如以下示例所示:
重要:
我省略了对 Windows 终端 (
wt.exe
) 的调用,因为这会创建另一个 /em> PowerShell 会话,这意味着只会为该会话保留以下定义:-d
选项:wt.exe -d \"$((Get-Location -PSProvider FileSystem).ProviderPath)\"
-WindowStyle Hidden
添加到Start-Process
,删除-NoExit
在参数列表中的-Command
之前,并在底部添加wt.exe
调用。保留其他类型的定义需要直接在提升的
powershell
会话中工作,该会话将始终使用常规 (conhost.exe
)然而,控制台窗口。一般来说,最好将在常规会话和提升会话中都可用的定义放置在
$PROFILE
文件。作为补充,请参阅此答案以获取方便的函数
Enter-AdminPSSession
,它允许您传递脚本块在提升的会话中执行,您可以将调用者状态中的值作为参数传递给该会话。注意:
以上使用Windows PowerShell CLI,
powershell.exe
。要使用 PowerShell (Core) 7+,请替换pwsh.exe
。以上内容涵盖以通用方式保留当前文件系统位置、环境变量、别名和函数。
警告:相比之下,保留常规变量仅限于字符串和数字 - 本质上是那些数据类型的实例,其字符串化表示当解释为源代码文字时,会被识别为此类。
-EncodedCommand
和-EncodedArguments
参数的 Base64 编码,支持更多数据类型是可能的,如 这个答案,但是可以用类型保真度表示的类型范围从根本上受到 PowerShell 的限制基于 XML 的序列化基础设施 - 请参阅此答案。[1] 此限制也出现在 PowerShell(核心)中7,其中
Start-Process
现在有一个-Environment
参数,用于修改继承的环境,但是不能< /em> 与 结合-动词 RunAs
。不幸的是,从 v7.5.0 开始,这种无效的参数组合会被悄悄地忽略,而不是报告错误(这就是类似的 .NET API 调用中发生的情况):请参阅 GitHub 问题 #20923。By design, elevated sessions (
-Verb RunAs
) do not inherit the caller's environment variables and even explicit attempts to pass an environment are categorically prevented by the underlying .NET API.[1]Also, whether or not you use
-Verb RunAs
, the state of a PowerShell session (aliases, functions, shell-only variables, ...) is never inherited when you launch another PowerShell process, such as withStart-Process
.A workaround is to explicitly and selectively recreate the state of interest via commands executed in the elevated session, based on values from the caller's state, but that is quite cumbersome and has limitations, as the following example shows:
Important:
I've omitted the call to Windows Terminal (
wt.exe
), as that would create another PowerShell session, which means that only the following definitions would be preserved for that session:-d
option:wt.exe -d \"$((Get-Location -PSProvider FileSystem).ProviderPath)\"
-WindowStyle Hidden
toStart-Process
, remove-NoExit
before-Command
in the argument list, and add awt.exe
call at the bottom.Preserving the other types of definitions requires working directly in the elevated
powershell
session, which will invariably use a regular (conhost.exe
) console window, however.In general, it's best to place definitions that should be available in both regular and elevated sessions in your
$PROFILE
file.Complementarily, see this answer for convenience function
Enter-AdminPSSession
, which allows you to pass a script block to execute in the elevated session, to which you can pass values from the caller's state as arguments.Note:
The above uses the Windows PowerShell CLI,
powershell.exe
. To use PowerShell (Core) 7+ instead, substitutepwsh.exe
.The above covers preserving the current file-system location, environment variables, aliases, and functions in a generic fashion.
Caveat: By contrast, preserving regular variables is limited to strings and numbers - in essence, instances of those data types whose stringified representation is recognized as such when interpreted as a source-code literal.
-EncodedCommand
and-EncodedArguments
parameters as shown in this answer, but the range of types that can be represented with type fidelity is fundamentally limited by PowerShell's XML-based serialization infrastructure - see this answer.[1] This limitation also surfaces in PowerShell (Core) 7, where
Start-Process
now has an-Environment
parameter for modifying the inherited environment, which, however, can not be combined with-Verb RunAs
. Unfortunately, as of v7.5.0, such an invalid parameter combination is quietly ignored instead of reporting an error (which is what happens in an analogous .NET API call): see GitHub issue #20923.您不能保留变量,创建新窗口后您将立即丢失它们,您能做的最好的事情是创建一个包含所有活动的脚本,然后将其保存在同一工作目录中。
当您打开一个新窗口时,只需调用您的脚本即可为您提供与其他窗口中相同的信息。
You can not keep variables, you will lose them immediately after the new window is created, the best you can do instead is to create a script containing all your activities then save it in the same working directory.
When you open a new window just call your script that will be able to give you the same information as in the other window.