我有一个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'
我想知道是否有更短的方法。
答案 0 :(得分:1)
一个简短的命令,它可以通过HTTP下载脚本并在本地执行该脚本(可选地带有参数),这可以利用以下优点:
irm
的别名Invoke-RestMethod
代替(New-Object System.Net.WebClient).DownloadString()
& ([scriptblock]::Create((irm http://company-server/bootstrap.ps1))) RunJob
RunJob
是OP传递给脚本的自定义参数。
一种甚至更简短但也许更晦涩的方法是使用iex
,这是Invoke-Expression
的内置别名,由this GitHub comment提供。
iex "& { $(irm http://company-server/bootstrap.ps1) } RunJob"
顺便说一句:一般使用Invoke-Expression should be avoided。
该命令使用可扩展字符串("..."
,字符串插值)来创建一个字符串,该字符串的远程脚本的 content 包含在脚本块{ ... }
中,然后调用该脚本块在子范围(&
)中。请注意,传递给脚本的参数必须位于 "..."
内部。
但是,有一个一般警告(对您来说似乎不成问题):如果脚本以exit
结尾,则调用PowerShell实例也已退出 。
有两种解决方法:
在子进程中运行脚本:
powershell { iex "& { $(irm http://company-server/bootstrap.ps1) } RunJob" }
注意事项:
以上内容仅可在PowerShell中使用;从PowerShell外部,必须使用powershell -c "..."
而不是powershell { ... }
,但是请注意,如果需要,请正确转义 embedded 双引号(对于带有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 中使用。 根据您需要支持的平台/愿意做出的假设(例如,当前目录是可写的),可以缩短该命令。
This GitHub issue(自PowerShell Core 6.2.0-preview.4起编写)建议增强
Invoke-Command
(icm
)cmdlet,以大大简化下载脚本和-执行方案,以便您可以按以下方式调用有问题的脚本:
# WISHFUL THINKING as of PowerShell Core 6.2.0-preview.4
icm -FileUri http://company-server/bootstrap.ps1 RunJob
或者,如果需要对下载方面进行更多控制(例如,传递凭据):
# WISHFUL THINKING as of PowerShell Core 6.2.0-preview.4
irm http://company-server/bootstrap.ps1 | icm -FromPipeline RunJob
答案 1 :(得分:0)
这是一个较短的解决方案(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