簡體   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