Как «псевдоним» со связанным параметром, не прерывая конвейерную обработку в Powershell? - PullRequest
0 голосов
/ 19 января 2019

Я часто добавляю |select -first 10 в конец команд, и я хотел бы сократить это до |s10, |s50 и еще пару вариантов.Так что я бы хотел сделать эквивалент set-alias s10 select-object -first 10.

Стандартный способ, которым вы "псевдоним" связываете параметры, это написать функцию и пересылать @args вместе с дополнительными параметрами.Но если я напишу функцию, которая передает от $input до select-object, я потеряю потоковую передачу.

Я мог бы написать функцию начала / процесса / окончания, но я не знаю, могу ли я / как перенаправить каждуюиз них к эквивалентам в select-объекте.Я мог бы написать свою собственную реализацию начала / процесса / конца select-object, которая просто реализует поведение -first, но это просто неправильно ...

(Мой запасной вариант - добавить завершение табуляции для расширения s10,но я бы действительно хотел узнать, как реализовать правильную функцию.)

Как реализовать функцию, которая перенаправляет на select-object параметр, который я хочу добавить, но не нарушает конвейерную обработку?

Ответы [ 2 ]

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

Я нашел этот источник https://blogs.technet.microsoft.com/heyscriptingguy/2011/03/01/proxy-functions-spice-up-your-powershell-core-cmdlets/

В этом случае ярлык / псевдоним для Select-String -First 10 сводится к:

$metadata = New-Object System.Management.Automation.CommandMetaData (Get-Command Select-Object)
[System.Management.Automation.ProxyCommand]::Create($MetaData) | Out-File -FilePath prxyfunctions.psm1

Откройте файл модуля prxyfunctions.psm1 и оберните весь контент в новую функцию под названием S10

function S10 {
    [CmdletBinding(DefaultParameterSetName = 'DefaultParameter', HelpUri = 'https://go.microsoft.com/fwlink/?LinkID=113387', RemotingCapability = 'None')]
    param(

    <abbreviated...>

.ForwardHelpTargetName Microsoft.PowerShell.Utility\Select-Object
.ForwardHelpCategory Cmdlet

#>
}

Затем в разделе Begin {} добавьте один оператор $PSBoundParameters.Add('First','10'), как показано ниже.

begin {
        try {
            $outBuffer = $null
            if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) {
                $PSBoundParameters['OutBuffer'] = 1
            }
            $PSBoundParameters.Add('First','10')
            $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Utility\Select-Object', [System.Management.Automation.CommandTypes]::Cmdlet)
            $scriptCmd = {& $wrappedCmd @PSBoundParameters }
            $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
            $steppablePipeline.Begin($PSCmdlet)
        }
        catch {
            throw
        }
    }

Вот и все. Сохраните файл, импортируйте модуль, наберите короткую команду типа gci c:\|s10 и получите всего 10 результатов. Если вы действительно хотите, чтобы все было надежно, нужно больше кодирования. Если используется S10 -First 2, вы получите хорошую ошибку.


РЕДАКТИРОВАТЬ в ответ на полезные комментарии @PetSerAl

Некоторые командлеты, находящиеся далее в конвейере, могут не поддерживать прокси-функцию, например, Sort-Object. Сравните вывод этих двух строк

-join (20..1 | Select -First 10 | Sort)
11121314151617181920

-join (20..1 | S10 | Sort)
<nothing>

-join (20..1 | S10 -Wait | Sort)
11121314151617181920

Это можно обойти, используя параметр -Wait в командной строке. Или закодируйте параметр Wait в прокси-функции $PSBoundParameters.Add('Wait',$true)

При работе с большими коллекциями это прискорбно, поскольку отключает функцию Select-Object, которая останавливает конвейер после элементов x, что приводит к большей обработке и более длительному ожиданию.

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

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

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