Выполнение сценариев или функций powershell с использованием Unix-подобного синтаксиса конвейера

727
Cyberwiz

Я хочу запустить несколько пользовательских шагов обработки, используя конвейер в powershell.

В Linux я мог бы сделать что-то вроде этого:

listServers.sh | <some commands to filter servers> | commandToApplyToEachServer.sh 

И поместите код, относящийся к каждому шагу, в разные сценарии (каждая команда может принимать несколько параметров, и, по крайней мере, последний может быть полностью заменен другим сценарием)

Я хотел бы сделать что-то подобное в powershell, без добавления каких-либо «накладных расходов» (необходимость создания сценариев перед использованием их функций, необходимость повторного создания сценариев в случае изменений и т. Д.)

Выполнить команды непосредственно в командной строке легко:

"server1","server2" | % 

... но я хочу предоставить пользователям (и мне) более простой и надежный способ выполнения этой и аналогичных команд (в основном, завершение каждого шага в скрипте или функции, независимо от того, какой способ выполнения действий наиболее эффективен).

Самое близкое, что я получил, это:

[CmdletBinding()] param( [Parameter(Mandatory=$true)] $env )  Function global:srv { Begin { }  Process { Get-Service -Name someServiceName -ComputerName $_ }  End { } }  Get-Content "$env.csv" 

Что позволяет мне запускать такие вещи, как:

.\listServers.ps1 appServers | srv 

Но, к сожалению, функция srv обновляется только ПОСЛЕ того, как вся команда закончила работать (поэтому любые изменения в функции echo-pipe не вступят в силу до тех пор, пока я не буду ее запускать второй раз, и, конечно, мне нужно получить исходный код listServers.ps1, прежде чем я смогу делать что-либо вообще, потому что srv не существует до тех пор)

ОБНОВЛЕНИЕ: я продвинулся, используя подход единственного сценария (используя некоторые параметры, чтобы обработать фильтрацию и контролировать, какую команду я хочу выполнить в конце, не используя конвейер). Но все равно было бы интересно узнать, возможно ли использовать конвейер.

1
Есть ли причина, по которой вы не можете передавать имена серверов в качестве параметров в обычном режиме? soandos 9 лет назад 0
Да, может быть более 10 серверов, и я хочу прочитать их из файла. Cyberwiz 9 лет назад 0
Почему бы не написать функцию, которая читает файл, а затем передает его как массив имен серверов? soandos 9 лет назад 0
Я не уверен, как вы имеете в виду, не могли бы вы уточнить? Cyberwiz 9 лет назад 0

1 ответ на вопрос

1
Austin T French

Кажется, что самый буквальный перевод

listServers.sh | <some commands to filter servers> | commandToApplyToEachServer.sh 

было бы как:

Get-content listServers.txt | Where-Object {*attributes and whatever} | CommandToRun 

С PowerShell и трубопроводами все зависит только от того, как вы получите что-то и что сможете. Например, я хочу перезагрузить все мои серверы с именем MAILSERVERxxxx:

Get-QADComputer -name * | where-object {$_.Name -Match "$MAILSERVER"} | Restart-Computer -ComputerName $_.Name 

можно было бы сделать, но в большей степени в соответствии с практикой PowerShell, вы часто можете справиться с этим совершенно по-другому:

Get-QADComputer -Name "MAILSERVER*" | Restart-Computer $_.Name 

Несколько заметок:

  • PowerShell очень гибкий
  • PowerShell предназначался для доведения командной строки Windows до уровней полезности BASH.
  • Синтаксис также гибкий
  • Get-QADComputers - это командлет от Quest и теперь Dell

Вы также можете использовать C-подобный синтаксис для выполнения многих одних и тех же задач, что еще больше расширяет возможности PowerShell.

Если вы хотите, например, прочитать файл, построить и массив на основе критериев соответствия, а затем сделать что-то, прежде чем двигаться дальше:

$someArray = @() Get-Content "H:\SomeFile.txt" | ` Foreach-object { if ($_ -MAtch "$MAILSERVER") { $someArray += $_} }  $someArray | foreach-Object { if (Test-Connection "$_") { $Version = (Get-WmiObject -ComputerName "$_" -Class "Win32_OperatingSystem").Version } } 

Надеюсь, это поможет.

Привет! Спасибо, ваш ответ был очень информативным (особенно Get-QADComputer, я определенно буду его использовать). Однако это не решает мою основную проблему: как использовать файлы сценариев в конвейере? (или любая аналогичная функция, которая позволяет мне запускать команду удобно и без необходимости повторно создавать исходные файлы, если произошли изменения перед выполнением моей настоящей команды) Cyberwiz 9 лет назад 0