2012-03-06 2 views
6

Я смущен тем, что я увидел в книге Learn PowerShell за месяц обедов. В главе 21, когда автор обсуждает функции, которые принимают входные данные через привязку параметров или конвейер, он дает два шаблона.Обработка трубопровода и ввода параметров в функции Powershell

Первого следующего

function someworkerfunction { 
# do some work 
} 
function Get-SomeWork { 
    param ([string[]]$computername) 
    BEGIN { 
     $usedParameter = $False 
     if($PSBoundParameters.ContainsKey('computername')) { 
     $usedParameter = $True 
     } 
    } 
    PROCESS { 
     if($usedParameter) { 
     foreach($computer in $computername) { 
      someworkerfunction -computername $comptuer 
     } 
     } else { 
     someworkerfunction -comptuername $_ 
     } 
    } 

    END {} 
} 

во второй, как этом

function someworkerfunction { 
# do stuff 
} 
function Get-Work { 
    [CmdletBinding()] 
    param(
     [Parameter(Mandatory=$True, 
     ValueFromPipelineByPropertyName=$True)] 
     [Alias('host')] 
     [string[]]$computername 
    ) 
    BEGIN {} 
    PROCESS { 
     foreach($computer in $computername) { 
     someworkerfunction -comptuername $computer 
     } 
    } 
    END {} 
} 

Я знаю, что второй образец является стандартным Powershell 2.0 Advanced функции. Мой вопрос заключается в поддержке Powershell 2.0 для директивы cmdletbinding, если вы захотите использовать первый шаблон. Это просто наследие Powershell 1.0? В принципе, когда-либо было время использования Powershell 2.0, которое я хотел бы пообщаться с первым шаблоном, когда второй шаблон настолько чище.

Любое понимание будет оценено по достоинству.

спасибо.

ответ

3

Если вы хотите обработать вход для конвейера в своей функции, но не хотите добавлять все атрибуты параметров или хотите назад совместимость с cmdletbinding меньше.

Если вы хотите использовать дополнительные функции командлетов сценариев PowerShell, такие как атрибуты параметров, наборы параметров и т. Д., Затем перейдите ко второму.

0

Первая форма ожидает одно или несколько имен компьютеров в виде строковых аргументов либо из списка аргументов, либо из конвейера.

Вторая форма ожидает либо массив строковых аргументов из списка аргументов, либо входные объекты из конвейера с именами компьютеров в качестве свойства.

1

Чтобы ответить на ваш вопрос, я бы сказал, что первый шаблон - это просто наследие PowerShell 1.0, вы также можете использовать $input в классических функциях без блока сценария процесса. Насколько вы можете написать код PowerShell 2.0, вы можете его забыть.

Что касается функций трубопровода, то в powerShell V1.0 их можно обрабатывать с помощью filters.

вы просто должны знать, что это было сделано так, когда вы берете сэмплы из сети или когда вам нужно отлаживать старый код Powerhell.

Лично я все еще использую старые functions и filters внутри своих модулей. Я оставляю cmdletbinding для функций экспорта или функций профиля.

Powershell немного похож на блоки lego, вы можете делать много вещей разными способами.

+0

Здравствуйте. Спасибо Вам за информацию. Это то, что я хотел знать. – lowteq

1

Если кто-то желает очень, очень простое объяснение того, как читать из централизованному ввода см

How do you write a powershell function that reads from piped input?

Если бы это ^ существовали, когда у меня был этот вопрос, я бы сэкономил много времени, потому что этот поток довольно сложный и на самом деле не объясняет, как обращаться с конвейерным вводом в функцию.

2

Нет, первый пример - это не только наследие. Чтобы создать функцию PowerShell, которая использует параметр массива и принимает входной поток, вам нужно выполнить некоторую работу.

Я даже зашел так далеко, чтобы сказать, что второй пример не работает. По крайней мере, я не мог заставить его работать.

Возьмем такой пример ...

function PipelineMadness() 
{ 
    [cmdletbinding()] 
    param (
     [Parameter(Mandatory = $true, ValueFromPipeline=$true)] 
     [int[]] $InputArray 
    ) 

    Write-Host ('$InputArray.Count {0}' -f $InputArray.Count) 
    Write-Host $InputArray 

    Write-Host ('$input.Count {0}' -f $input.Count) 
    Write-Host $input 

    if($input) { Write-Host "input is true" } 
    else { Write-Host "input is false" } 
} 

результаты ...

PS C:\Windows\system32> 1..5 | PipelineMadness 
$InputArray.Count 1 
5 
$input.Count 5 
1 2 3 4 5 
input is true 

PS C:\Windows\system32> PipelineMadness (1..5) 
$InputArray.Count 5 
1 2 3 4 5 
$input.Count 1 

input is false 

Обратите внимание, что при использовании трубопровода переменная $InputArray одно значение 5 ...

Теперь с блоками BEGIN и PROCESS

function PipelineMadnessProcess() 
{ 
    [cmdletbinding()] 
    param (
     [Parameter(Mandatory = $true, ValueFromPipeline=$true)] 
     [int[]] $InputArray 
    ) 

    BEGIN 
    { 
     Write-Host 'BEGIN' 
     Write-Host ('$InputArray.Count {0}' -f $InputArray.Count) 
     Write-Host $InputArray 

     Write-Host ('$input.Count {0}' -f $input.Count) 
     Write-Host $input 

     if($input) { Write-Host "input is true" } 
     else { Write-Host "input is false" } 
    } 

    PROCESS 
    { 
     Write-Host 'PROCESS' 
     Write-Host ('$InputArray.Count {0}' -f $InputArray.Count) 
     Write-Host $InputArray 

     Write-Host ('$input.Count {0}' -f $input.Count) 
     Write-Host $input 

     if($input) { Write-Host "input is true" } 
     else { Write-Host "input is false" } 
    } 
} 

Теперь это, где он получает странно

PS C:\Windows\system32> 1..5 | PipelineMadnessProcess 
BEGIN 
$InputArray.Count 0 

$input.Count 0 

input is false 
PROCESS 
$InputArray.Count 1 
1 
$input.Count 1 
1 
input is true 
PROCESS 
$InputArray.Count 1 
2 
$input.Count 1 
2 
input is true 

... 

PROCESS 
$InputArray.Count 1 
5 
$input.Count 1 
5 
input is true 

Бегин блок не имеет никаких данных там вообще. И блок процессов работает хорошо, однако, если у вас есть foreach, как в примере, который он действительно будет работать, но он будет работать с foreach с 1 входом X раз. Или, если вы пройдете в массиве, он будет запускать foreach один раз с полным набором.

Так что, я думаю, технически пример будет работать, но он может работать не так, как вы ожидаете.

Также обратите внимание, что даже если блок BEGIN не имел данных, функция прошла проверку синтаксиса.

Смежные вопросы