For example I would like the Select-Object
commandlet to interpret Get-ChildItem|Select-Object 1
as Get-ChildItem|Select-Object -First 1
I have been getting by with "Wrappers" like this for my most common commandlets:
function Select-Object{
[CMDletbinding()]
param (
[Parameter(ValueFromPipeline)]
$InputObect,
[Parameter(Position = 1)]
[int]$First,
[Parameter(Position = 2)]
[int]$Last
)
$input | Select-Object -First $First -Last $Last
}
But there are sometimes buggy and I always rewrite it to add more parameters.
I have been reading the docs and have not found anything other than parametersplicing.
It does not have to be an official solution. So if anyone has come up with a solution to this I would like to know.
PS: I know this is can lead to confusing code, but I am intending to only use it for an interactive\terminal sessions. Doing gci | sel 1
is infinitely more preferable to Get-ChildItem | Select-Object -First 1
Any help would be greatly appreciated!
CodePudding user response:
For wrappers like this you should use a ProxyCommand
. Most of the code below can be auto-generated for you via its .Create(..)
Method:
[System.Management.Automation.ProxyCommand]::Create((Get-Command Select-Object))
Using only the 2 parameters you're interested in -First
and -Last
in addition to the pipeline parameter, the function would look like this:
function sel {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline)]
[object] $InputObject,
[Parameter(Position = 1)]
[int] $First,
[Parameter(Position = 2)]
[int] $Last
)
begin {
$wrapper = { Microsoft.PowerShell.Utility\Select-Object @PSBoundParameters }
$pipeline = $wrapper.GetSteppablePipeline($MyInvocation.CommandOrigin)
$pipeline.Begin($PSCmdlet)
}
process {
$pipeline.Process($InputObject)
}
end {
$pipeline.End()
}
}
Now you can use positional binding without problems:
0..10 | sel 1 # for `-First 1`
0..10 | sel 1 1 # for `-First 1` `-Last 1`
As for parameter splicing you might referring to what's known as Splatting in powershell. For that you can look into about Splatting. As an example the code above is using splatting with the automatic variable $PSBoundParameters
.