我有一个 PowerShell 脚本文件存储在内部工件服务器中。脚本网址为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'
Run Code Online (Sandbox Code Playgroud)
我想知道是否有更短的方法来做到这一点。
注意:从代码高尔夫的角度来看,通过消除无关紧要的空白,可以进一步缩短下面的解决方案;例如, &{$args[0]}hi
而不是 & { $args[0] } hi
. 然而,为了可读性,保留了这样的空白。
通过 HTTP 下载脚本并在本地执行(可选地使用参数)的命令的简短表述可能是这样的,利用:
irm
代替Invoke-RestMethod
(New-Object System.Net.WebClient).DownloadString()
& ([scriptblock]::Create((irm http://company-server/bootstrap.ps1))) RunJob
Run Code Online (Sandbox Code Playgroud)
RunJob
是 OP 传递给脚本的自定义参数。
一种更短但可能更晦涩的方法是使用 的iex
内置别名,由GitHub 评论Invoke-Expression
提供。
iex "& { $(irm http://company-server/bootstrap.ps1) } RunJob"
Run Code Online (Sandbox Code Playgroud)
顺便说一句:在一般使用中,应避免使用 Invoke-Expression。
该命令使用可扩展字符串("..."
字符串插值)创建一个字符串,其中远程脚本的内容包含在脚本块中{ ... }
,然后在子作用域 ( &
) 中调用该字符串。请注意传递给脚本的参数必须位于 "..."
.
但是,有一个一般警告(这对您来说似乎不是问题):如果脚本以 终止exit
,则调用的 PowerShell 实例也会退出。
有两种解决方法:
在子进程中运行脚本:
powershell { iex "& { $(irm http://company-server/bootstrap.ps1) } RunJob" }
Run Code Online (Sandbox Code Playgroud)
注意事项:
以上仅适用于 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
}
Run Code Online (Sandbox Code Playgroud)
明显的缺点是命令更长。
请注意,该命令在编写时考虑到了稳健性和跨平台兼容性,因此它也可以在所有支持的平台上的 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
Run Code Online (Sandbox Code Playgroud)
GitHub 问题 #8835更进一步,建议创建一个 RFC 来引入一个新的 PowerShell提供程序,允许在以前只接受文件的地方使用 URL,从而实现以下调用:
# WISHFUL THINKING as of PowerShell Core 7.0
& http://company-server/bootstrap.ps1 RunJob
Run Code Online (Sandbox Code Playgroud)
然而,虽然这些选项非常方便,但也需要考虑安全隐患。
归档时间: |
|
查看次数: |
1928 次 |
最近记录: |