Proxy function in PowerShell not accepting pipeline input

I created a for Remove-Item

that is removed to the trash instead of a permanent one (using a proxy so that I can easily replace the alias rm

without breaking third party scripts).

However, it doesn't work when the file is passed to a function. The heart of the proxy function is the following:

if ($PSBoundParameters['DeletePermanently'] -or $PSBoundParameters['LiteralPath'] -or $PSBoundParameters['Filter'] -or $PSBoundParameters['Include'] -or $PSBoundParameters['Exclude'] -or $PSBoundParameters['Recurse'] -or $PSBoundParameters['Force'] -or $PSBoundParameters['Credential']) {
    if ($PSBoundParameters['DeletePermanently']) { $PSBoundParameters.Remove('DeletePermanently') | Out-Null }
    $scriptCmd = {& $wrappedCmd @PSBoundParameters }
} else {
    $scriptCmd = {& Recycle-Item -Path $PSBoundParameters['Path'] }
}

      

So my custom function Recycle-Item

is only called if Path

is the only parameter. So, something like Get-ChildItem .\temp\ | rm -DeletePermanently

works just fine, but it Get-ChildItem .\temp\ | rm

is a mistake, as Path

passed in Recycle-Item

, $null

.

I've tried skipping $Path

instead, $PSBoundParameters['Path']

and tried splatting @PSBoundParameters

like the challenge $wrappedCmd

above, but none of it does much good. I copied params

from this function in Recycle-Item

to make sure it expects input from the pipeline, but that doesn't help either. Some of these changes seem to go by the filename, but not the full path, so I don't know if there is some magic inside Remove-Item

that I need to replicate to process the file object from the pipeline.

Recycle-Item

is just a basic function:

function Recycle-Item($Path) {
    $item = Get-Item $Path
    $directoryPath = Split-Path $item -Parent

    $shell = new-object -comobject "Shell.Application"
    $shellFolder = $shell.Namespace($directoryPath)
    $shellItem = $shellFolder.ParseName($item.Name)
    $shellItem.InvokeVerb("delete")
}

      

+3


source to share


1 answer


As mentioned in the comments, provider cmdlets usually bind to LiteralPath

when you link objects between them. This method allows you to Path

support wildcard substitutions without the ability to pass ambiguous item paths between cmdlets.

Remove-Item

has only two sets of parameters, and they are named after their required parameters, Path

andLiteralPath



To solve your problem, just check for all specific parameters that are not one of these two, then pass the appropriate value Remove-Item

based on the value $PSCmdlet.ParameterSetName

:

if(@($PSBoundParameters.Keys |Where-Object {@('DeletePermanently','Filter','Include','Exclude','Recurse','Force','Credential') -contains $_}).Count -ge 1){
    # a parameter other than the Path/LiteralPath or the common parameters was specified, default to Remove-Item
    if ($PSBoundParameters['DeletePermanently']) { 
        $PSBoundParameters.Remove('DeletePermanently') | Out-Null 
    }
    $scriptCmd = {& $wrappedCmd @PSBoundParameters }
} else {
    # apart from common parameters, only Path/LiteralPath was specified, go for Recycle-Item
    $scriptCmd = {& Recycle-Item -Path $PSBoundParameters[$PSCmdlet.ParameterSetName] }
}

      

+2


source







All Articles