# Note: Execution via & { ... } prevents iex (Invoke-Expression) from
# effectively dot-sourcing the code, i.e. from running it
# directly in the calling scope, which can have unwanted side effects.
iex "& { $(irm https://sample.com/cli.ps1) }"
# More robust:
& ([scriptblock]::Create((irm https://sample.com/cli.ps1)))
2条答案
按热度按时间roqulrg31#
为your own effective solution提供更简洁的替代方案-还假设从PowerShell* 执行 *;关于直接执行从Web下载的代码的常见警告:[1]
存在上述故障的边缘情况(见下文);然后使用下面的健壮形式,这也使得将 arguments传递给脚本变得容易:
假设你知道脚本不包含
exit
语句(这将退出 * 你的整个会话 ),你甚至可以使用进程内 * 执行(就像你通过辅助文件的解决方案一样),如下所示:进程内执行不仅速度更快,而且还使脚本能够直接修改当前会话的环境变量,并保持脚本输出对象的完整类型保真度(如果有的话)。
如果脚本 * 确实 * 有
exit
语句,则必须首先下载到(临时)* 文件 *(如您的解决方案中所示),尽管下面讨论的建议的未来增强功能将使其变得不必要。注意事项:
irm
是Invoke-RestMethod
cmdlet的内置别名-有关详细信息,请参阅下一节。iex
是Invoke-Expression
cmdlet的内置别名。Invoke-Expression
是generally to be avoided,但在这里,它可以在不需要辅助脚本 * 文件 *(.ps1
)的情况下执行源代码。[scriptblock]::Create($sourceCodeString)
是一种将源代码解析为script block(其文字形式为{ ... }
)的方法,即可以在以后使用&
(调用操作符)或.
(点源操作符)按需调用的可重用代码单元。它的使用绕过了以下
Invoke-Expression
错误,至少在PowerShell 7.3.3中存在:顺便说一句:如果是:
-ExecutionPolicy Bypass
覆盖它Set-ExecutionPolicy
将其设置为 * 永久 *,如您自己的答案所示-请参阅this answer了解背景信息。Invoke-Command
cmdlet,以基于Invoke-WebRequest
调用作为管道输入,直接从Web强大地支持脚本的执行。Invoke-WebRequest
和Invoke-Command
的内置别名iwr
和icm
):curl
vs.curl.exe
vs.Invoke-WebRequest
vs.Invoke-RestMethod
:curl.exe
确实随Windows的最新版本而来。curl.exe
*,即 * 带有 *.exe
扩展名。curl
(* 不含 *.exe
部分)是Invoke-WebRequest
cmdlet的 * 别名 *,Invoke-WebRequest
cmdlet是PowerShell对curl.exe
的 * 模拟 *,尽管语法非常不同。幸运的是,这个别名已从PowerShell (Core) 7+中删除。
但是,可以在两个PowerShell版本中使用的内置PowerShell惯用别名是
iwr
,用于引用Invoke-WebRequest
。Invoke-RestMethod
cmdlet(其内置别名为irm
)可用于代替Invoke-WebRequest
,以满足以下情况:您只关心响应的 * 数据 *,而不关心 Package * 数据的丰富响应信息对象。Invoke-RestMethod
可以方便地将数据分别解析为[xml]
(System.Xml.XmlDocument
)示例和自定义对象图([pscustomobject]
)形式的XML DOM。[1]只有当您完全控制或隐式信任脚本的内容时才执行此操作,以防止执行潜在的恶意代码。
lymnna712#
这个方法的作用是: