[英]What is shortest possible way to download script from HTTP and run it with parameters using Powershell?
我有一個存儲在內部工件服務器中的 PowerShell 腳本文件。 腳本 URL 是http://company-server/bootstrap.ps1
。
下載該腳本並使用自定義參數執行的簡潔方法是什么?
我想將這樣的命令發送給用戶,他們會一遍又一遍地復制粘貼它,所以它必須是單行並且應該很短。
我目前擁有的作品,但它又長又笨重:
$c=((New-Object System.Net.WebClient).DownloadString('http://company-server/bootstrap.ps1'));Invoke-Command -ScriptBlock ([Scriptblock]::Create($c)) -ArgumentList 'RunJob'
我想知道是否有更短的方法可以做到這一點。
通過 HTTP 下載腳本並在本地執行它的命令的簡短表述可能是這樣的,它利用了以下優勢:
Invoke-RestMethod
的別名irm
,代替(New-Object System.Net.WebClient).DownloadString()
& ([scriptblock]::Create((irm http://company-server/bootstrap.ps1))) RunJob
RunJob
是傳遞給腳本的 OP 的自定義參數。
一個更短但可能更晦澀的方法是使用iex
,它是Invoke-Expression
的內置別名,由GitHub 評論提供。
iex "& { $(irm http://company-server/bootstrap.ps1) } RunJob"
順便說一句:在一般使用中, 應避免使用 Invoke-Expression 。
該命令使用可擴展字符串( "..."
,字符串插值)創建一個字符串,其中遠程腳本的內容包含在腳本塊{ ... }
中,然后在子范圍 ( &
) 中調用。 請注意要傳遞給腳本的參數如何必須在"..."
內。
但是,有一個一般性警告(這對您來說似乎不是問題):如果腳本以exit
終止,則調用的 PowerShell 實例也會退出。
有兩種解決方法:
在子進程中運行腳本:
powershell { iex "& { $(irm http://company-server/bootstrap.ps1) } RunJob" }
注意事項:
以上僅適用於 PowerShell; 從 PowerShell 外部,您必須使用powershell -c "..."
而不是powershell { ... }
,但請注意,如果需要,正確轉義嵌入式雙引號(對於帶有 PS 元字符和/或自定義參數的 URL,比如說,空格),可能會變得棘手。
如果腳本是為了修改調用者的環境而設計的,那么修改會因為運行在子進程中而丟失。
首先將腳本保存到臨時文件:
注意:該命令分布在多行以提高可讀性,但它也可以作為單行:
& {
$f = Join-Path ([IO.Path]::GetTempPath()) ([IO.Path]::GetRandomFileName() + '.ps1');
irm http://company-server/bootstrap.ps1 > $f;
& $f RunJob;
ri $f
}
明顯的缺點是命令要長得多。
請注意,該命令的編寫考慮了穩健性和跨平台兼容性,因此它也適用於所有支持的平台上的 PowerShell Core 。 根據您需要支持的平台/您願意做出的假設(例如,當前目錄是可寫的),可以縮短命令。
GitHub 問題 #5909 ,從 PowerShell Core 6.2.0-preview.4 開始編寫,並從 PowerShell Core 7.0 開始修訂,建議增強
Invoke-Command
( icm
) cmdlet 可大大簡化下載腳本和執行方案,以便您可以按如下方式調用相關腳本:
# WISHFUL THINKING as of PowerShell Core 7.0
# iwr is the built-in alias for Invoke-WebRequest
# icm is the built-in alias for Invoke-Command.
iwr http://company-server/bootstrap.ps1 | icm -Args RunJob
GitHub 問題 #8835更進一步,建議創建一個 RFC 以引入一個新的 PowerShell提供程序,該提供程序允許在以前只接受文件的地方使用 URL,從而實現以下調用:
# WISHFUL THINKING as of PowerShell Core 7.0
& http://company-server/bootstrap.ps1 RunJob
然而,雖然這些選項非常方便,但需要考慮安全隱患。
這是一個較短的解決方案(158 個字符。)
$C=(New-Object System.Net.WebClient).DownloadString("http://company-server/bootstrap.ps1");icm -ScriptBlock ([Scriptblock]::Create($c)) -ArgumentList "RunJob"
這里是 121
$C=(curl http://company-server/bootstrap.ps1).content;icm -ScriptBlock ([Scriptblock]::Create($c)) -ArgumentList "RunJob"
這里是 108
$C=(curl http://company-server/bootstrap.ps1).content;icm ([Scriptblock]::Create($c)) -ArgumentList "RunJob"
這里是 98
$C=(iwr http://company-server/bootstrap.ps1).content;icm -sc([Scriptblock]::Create($c)) -ar RunJob
感謝 Ansgar Wiechers
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.