"test" | % -begin { iex (irm $DropBoxUrl) } -process { $_ | test_echo }
The above uses a ForEach-Object
call's -Begin
block to download and evaluate the script (the usual caveats re iex
(Invoke-Expression
) apply - you should trust the source), which defines the test_echo
function contained in the downloaded script.
The -Begin
script block executes before pipeline input is processed, which means that by the time the -Process
script block processes (each) pipeline input object, the test_echo
function is already defined.
Also note that irm
(Invoke-RestMethod
) rather than iwr
(Invoke-WebRequest
) is used, given that you're only interested in the content of the script.
Of course, this doesn't gain you much, as you could simply use two statements, which has the added advantage that all pipeline input (should there be multiple input objects) are handled by a single test_echo
invocation:
iex (irm $DropBoxUrl) # Download and effectively dot-source the script.
"test" | test_echo # Pipe to the script's `test_echo` function.
A general caveat is that if the downloaded script contains an exit
statement that is hit during evaluation, the calling shell exits as a whole.
Since in effect you need to dot-source the downloaded script in order to make its functions available, the only way to solve the exit
problem is to download to a (temporary) file first, and dout-source that.
If dot-sourcing isn't needed, calling via the PowerShell CLI (child process) may be an option - see below.
GitHub issue #5909 proposes a future enhancement that would allow piping Invoke-WebRequest
(iwr
) calls to Invoke-Command
(icm
) for direct-from-the-web downloading and execution, without the exit
problem (iwr $DropboxLink | icm
).
Note that if your downloaded script were to accept pipeline input directly, you could use [scriptblock]::Create()
as follows (Invoke-Expression
is not an option, because it doesn't accept pipeline input):
# Assumes that the script located at $DropBoxUrl
# *itself* accepts pipeline input.
# Use . (...) if you want to *dot-source* the script, as
# Invoke-Expression would implicitly do.
"test" | & ([scriptblock]::Create((irm $DropBoxUrl))
To work around the exit
problem, you can call via the CLI and a script block, using pwsh
, the PowerShell (Core) 7+ CLI, in this example; use powershell.exe
for Windows PowerShell:
# Assumes that the script located at $DropBoxUrl
# *itself* accepts pipeline input.
'test' |
pwsh -NoProfile {
$input | & ([scriptblock]::Create($args[0]))
} -args (irm $DropBoxUrl)