繁体   English   中英

PowerShell中的代理功能不接受管道输入

[英]Proxy function in PowerShell not accepting pipeline input

我为Remove-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'] }
}

因此,仅当Path是唯一参数时,才会调用我的自定义Recycle-Item函数。 所以,像Get-ChildItem .\\temp\\ | rm -DeletePermanently Get-ChildItem .\\temp\\ | rm -DeletePermanently正常工作,但Get-ChildItem .\\temp\\ | rm Get-ChildItem .\\temp\\ | rm有一个错误,因为传递给Recycle-ItemPath$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")
}

如注释中所述,当您在它们之间管道对象时,提供程序cmdlet通常绑定在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] }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM