2017-04-17 48 views
3

我创建了一个proxy functionRemove-Item,它删除到回收站,而不是永久(使用代理,这样我可以无缝地更换rm别名,不破坏第三方脚本)。代理功能不接受管道输入

但是,当文件传送到函数中时它不起作用。代理功能的心脏是这样的:

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'] } 
} 

所以,我的自定义功能Recycle-Item只有当Path是唯一的参数调用。所以,类似Get-ChildItem .\temp\ | rm -DeletePermanently的工作正常,但Get-ChildItem .\temp\ | rm有错误,因为Path传递给Recycle-Item的是$null

我试过路过$Path代替$PSBoundParameters['Path']并试图泼洒@PSBoundParameters像上面的呼叫$wrappedCmd,但没有它似乎有很大的裨益。我已将params从此函数复制到Recycle-Item,以确保它期望从管道输入,但这似乎也没有帮助。其中一些更改似乎通过文件名传递,但不是完整路径,所以我不知道Remove-Item内是否有一些魔术需要复制以处理管道中的文件对象。

Recycle-Item仅仅是一个基本的功能:

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") 
} 
+2

管涌'GET-ChildItem'到'删除,Item'将绑定在'LiteralPath',前前后后管道不'Path' –

回答

2

正如在评论中提到的,提供者小命令通常在LiteralPath他们之间,当你管对象绑定。这种方式允许Path支持通配符匹配,而不会在cmdlet之间传递模糊的项目路径。

Remove-Item只有两个参数集,并且它们在其强制参数,PathLiteralPath

得名解决您的问题,简单地检查所有定义的参数这两个中的一个,然后通过相应的值Remove-Item基础上$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] } 
} 
+0

即使m'Get-ChildItem','PsCmdlet.ParametersSetName'是'Path'(并且'$ PSBoundParameters ['LiteralPath']'的检查是'$ false'),所以我不认为这是这种情况(或者存在一个更大的问题......) – bdukes