1

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

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

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

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

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

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

"server1","server2" | % {Get-Service -Name myservicename -ComputerName $_ | Set-Service -Status Stopped }

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

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

[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 ответ1

1

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

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
  }
}

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .