簡體   English   中英

如何在保持環境的情況下在單獨的window中啟動另一個PowerShell session?

[英]How to start another PowerShell session in a separate window while keeping the environment?

在 PowerShell 工作時,我傾向於通過鍵入快速切換到管理模式

Start-Process wt -Verb runas

當我這樣做時,會出現一個新的 window(遺憾的是,Windows 中沒有sudo )。 然而,在那個新的 session 中,環境是全新的。 在跳轉到新的 window 時是否可以保留變量、別名、工作目錄和所有其他類似內容? 如果不是,那么好吧,這是一個有效的答案。


舉個例子,我正在尋找這種行為:

第一 window

C:\test> $x = 123
C:\test> Start-Process wt

新window

C:\test> $x
123

通過(安全意識)設計,提升的會話( -Verb RunAs繼承調用者的環境變量

此外,無論您是否使用-Verb RunAs ,當您啟動另一個 PowerShell 進程時, state PowerShell session(別名,函數,當前位置......)永遠不會被繼承,例如Start-Process


您可以通過在提升的 session 中執行的命令根據調用方的 state 中的值顯式和選擇性地重新定義感興趣的 state 來解決此問題,但這非常麻煩並且有局限性,如以下示例所示:

# 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)\`"; " })
"@

重要

  • 我省略了對 Windows 終端 ( wt.exe ) 的調用,因為這會創建另一個PowerShell session,這意味着將為該session 僅保留以下定義:

    • 環境變量。
    • 當前位置(工作目錄),如果其默認 shell 配置為使用父進程的工作目錄。 或者,更可預測的是,傳遞工作目錄。 明確地使用-d選項:
      wt.exe -d \"$((Get-Location -PSProvider FileSystem).ProviderPath)\"
    • 如果這足夠了,您可以刪除保留別名、函數和常規變量的命令,將-WindowStyle Hidden添加到Start-Process ,在參數列表中刪除-NoExit之前的-Command ,並在底部添加一個wt.exe調用.
  • 保留其他類型的定義需要直接在提升的powershell session 中工作,但是它將始終使用常規( conhost.exe ) 控制台 window。

一般而言,最好將應在常規會話和高級會話中可用的定義放在$PROFILE文件中。

作為補充,為了方便起見,請參閱此答案function Enter-AdminPSSession ,它允許您傳遞腳本塊以在提升的 session 中執行,您可以將調用者的 state 中的值作為 arguments 傳遞給該腳本塊。

筆記:

  • 以上使用Windows PowerShell CLI, powershell.exe 要改用PowerShell (Core) 7+ ,請替換pwsh.exe

  • 上面涵蓋了以通用方式保存當前文件系統位置、環境變量、別名和函數。

  • 警告:相比之下,保留常規變量僅限於字符串和數字- 本質上,這些數據類型的實例,其字符串化表示在解釋為源代碼文字時被識別為此類。

    • 通過使用 Base64 編碼和 CLI 的-EncodedCommand-EncodedArguments參數進行不平凡的額外努力,支持更多的數據類型是可能的,如本答案所示,但可以用類型保真度表示的類型范圍從根本上受限於 PowerShell 的 XML-基於序列化基礎結構 - 請參閱此答案

您不能保留變量,在創建新的 window 后您將立即丟失它們,最好的辦法是創建一個包含所有活動的腳本,然后將其保存在同一工作目錄中。

當您打開一個新的 window 時,只需調用您的腳本,它就能為您提供與其他 window 中相同的信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM