Какой самый короткий способ загрузить скрипт из HTTP и запустить его с параметрами, используя Powershell? - PullRequest
0 голосов
/ 28 января 2019

У меня есть файл сценария 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'

Интересно, есть ли более короткий способ сделать это?.

Ответы [ 2 ]

0 голосов
/ 28 января 2019

Краткая формулировка команды , которая загружает скрипт через 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
0 голосов
/ 28 января 2019

Вот более короткое решение (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

Спасибо Ансгару Вичерсу

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...