Краткая формулировка команды , которая загружает скрипт через HTTP и выполняет его локально, необязательно с аргументами , возможно, так:
- alias
irm
для Invoke-RestMethod
вместо (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 следует избегать .
Команда использует расширяемую строку ("..."
, интерполяция строки), чтобы создать строку с удаленным сценарием content , заключенным в блок сценария { ... }
, которыйзатем вызывается в дочерней области (&
).Обратите внимание, что аргументы для передачи в сценарий должны быть внутри "..."
.
Однако существует общее предостережение (которое не кажетсядля вас проблема): если сценарий завершается с exit
, вызывающий экземпляр PowerShell тоже закрывается .
Существует два обходных путей:
Запустить сценарий в дочернем процессе :
powershell { iex "& { $(irm http://company-server/bootstrap.ps1) } RunJob" }
Предупреждения:
Вышеописанное работает только из PowerShell;из-за пределов PowerShell вы должны использовать powershell -c "..."
вместо powershell { ... }
, но учтите, что при необходимости необходимо правильно экранировать внедренные двойные кавычки (для URL с метасимволами PS и / или настраиваемыми аргументами с, скажем,пробелы), может стать хитрым.
Если сценарий предназначен для изменения среды вызывающего, изменения будут потеряны из-за запуска в дочернем процессе.
Сохраните сценарий во временный файл first:
Примечание. Команда разбита на несколько строк для удобства чтения, но также работаеткак однострочный:
& {
$f = Join-Path ([IO.Path]::GetTempPath()) ([IO.Path]::GetRandomFileName() + '.ps1');
irm http://company-server/bootstrap.ps1 > $f;
& $f RunJob;
ri $f
}
Очевидным недостатком является то, что команда намного длиннее.
Обратите внимание, что команда написана с учетом надежности и межплатформенной совместимости,так что он также работает в PowerShell Core на всех поддерживаемых платформах.В зависимости от того, какие платформы вам нужно поддерживать / какие предположения вы хотите сделать (например, что текущий каталог доступен для записи), команда может быть сокращена.
Потенциальные будущие улучшения
В этом выпуске GitHub , написанном для PowerShell Core 6.2.0-preview.4, предлагается усовершенствовать командлет
Invoke-Command
(icm
), чтобы значительно упростить загрузку сценариев ивыполнить сценарии, чтобы вы могли вызвать соответствующий сценарий следующим образом:
# 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