PowerShell代理命令Write-Table的PassThru功能异常问题求助
PowerShell代理命令Write-Table的PassThru功能异常问题求助
我来帮你捋清楚问题出在哪,以及怎么解决~
问题根源
你当前的代理命令里,$steppablePipeline.Process($_) 会把 Format-Table生成的格式化指令对象(比如那些FormatStartData、FormatEntryData之类的内部对象)直接输出到管道里,而你在process块里又额外输出了原始的$_。这就导致后续管道里同时混着两种对象:你想要传递的原始文件对象,还有Format-Table用来渲染表格的内部指令对象。Get-Item只能处理文件路径/对象,自然会对那些格式化指令报错。
而且Format-Table本身的设计就是把格式化对象输出到管道,由PowerShell主机负责把这些对象转换成可见的表格显示。你现在的写法相当于让这些格式化对象既被用来显示表格,又流到了下一个命令里,这就乱套了。
解决方法
核心思路是:让Format-Table的输出只用来渲染表格到主机,不进入后续管道;只有当PassThru开关开启时,才把原始输入对象传递下去。
修改你的代理命令,把Format-Table的输出通过Out-Host处理,这样格式化对象就被主机消费掉,不会流入管道了。修改后的代码如下:
function Write-Table { [CmdletBinding(HelpUri='https://go.microsoft.com/fwlink/?LinkID=2096703')] param( [switch] ${AutoSize}, [switch] ${RepeatHeader}, [switch] ${HideTableHeaders}, [switch] ${Wrap}, [Parameter(Position=0)] [System.Object[]] ${Property}, [System.Object] ${GroupBy}, [string] ${View}, [switch] ${ShowError}, [switch] ${DisplayError}, [switch] ${Force}, [ValidateSet('CoreOnly','EnumOnly','Both')] [string] ${Expand}, [Parameter(ValueFromPipeline=$true)] [psobject] ${InputObject}, [switch] ${PassThru}) begin { try { $outBuffer = $null if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) { $PSBoundParameters['OutBuffer'] = 1 } # 移除PassThru参数,因为我们自己处理它 if ($PSBoundParameters.ContainsKey('PassThru')) { $Null = $PSBoundParameters.Remove('PassThru') } $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Utility\Format-Table', [System.Management.Automation.CommandTypes]::Cmdlet) # 修改这里:把Format-Table的输出通过Out-Host传递,确保格式化对象不进入管道 $scriptCmd = {& $wrappedCmd @PSBoundParameters | Out-Host } $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin) $steppablePipeline.Begin($PSCmdlet) } catch { throw } } process { try { # 只有PassThru开启时,才把原始对象输出到管道 if ($PassThru) { $_ } $steppablePipeline.Process($_) } catch { throw } } end { try { $steppablePipeline.End() } catch { throw } } clean { if ($null -ne $steppablePipeline) { $steppablePipeline.Clean() } } <# .ForwardHelpTargetName Microsoft.PowerShell.Utility\Format-Table .ForwardHelpCategory Cmdlet #> }
验证效果
现在再运行你的测试命令:
gci *.txt | Write-Table -PassThru | Get-Item
你会看到表格正常显示,同时Get-Item能正确处理每个文件对象,不会再出现找不到路径的错误。如果后续要执行Remove-Item,也能正常工作啦~
备注:内容来源于stack exchange,提问作者iRon
相关产品推荐
相关产品推荐

