簡體   English   中英

從 HTTP 下載腳本並使用 Powershell 使用參數運行它的最短方法是什么?

[英]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.

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