用于缓冲管道输入到PowerShell cmdlet的设计模式

use*_*092 5 powershell design-patterns

我偶尔会遇到这样的情况,即支持将管道输入到Cmdlet,但是我希望执行的操作(例如,数据库访问)对大量的对象有意义。

实现此目的的典型方法如下所示:

function BufferExample {
<#
.SYNOPSIS
Example of filling and using an intermediate buffer.
#>
[CmdletBinding()]
param(
    [Parameter(ValueFromPipeline)]
    $InputObject
)

BEGIN {
    $Buffer = New-Object System.Collections.ArrayList(10)
    function _PROCESS {
        # Do something with a batch of items here.
        Write-Output "Element 1 of the batch is $($Buffer[1])"
        # This could be a high latency operation such as a DB call where we 
        # retrieve a set of rows by primary key rather than each one individually.

        # Then empty the buffer.
        $Buffer.Clear()
    }
}

PROCESS {
    # Accumulate the buffer or process it if the buffer is full.
    if ($Buffer.Count -ne $Buffer.Capacity) {    
        [void]$Buffer.Add($InputObject)        
    } else {
        _PROCESS 
    }
}

END {
     # The buffer may be partially filled, so let's do something with the remainder.
    _PROCESS
}
}
Run Code Online (Sandbox Code Playgroud)

有没有一种“样板”的方式来做到这一点?

一种方法可能是编写一个我称之为“ _PROCESS”的函数来接受数组参数,但不接受管道输入,然后让暴露给用户的cmdlet成为代理函数,用于缓冲输入并传递缓冲区如 Proxy命令中所述

或者,我可以在希望编写的cmdlet主体中点缀源动态代码以支持此功能,但是,这似乎容易出错,并且可能难以调试/理解。

Ran*_*tta 0

我认为这是您正在使用的最佳方法之一。

但当您仍在寻找更好的调试时,我相信您可以在函数内引入一些日志以及所需的日志文件位置。

此外,对于点源,您仍然可以编写点源引用并调用另一个脚本内的函数,并且您可以将所有内容包装在一个函数中。

多个功能的最佳方法是创建为模块。

希望对您有帮助。