2017-07-31 34 views
2

出于某种原因,我的计划是拒绝在这种情况下工作:管道向用户函数参数的问题

  • 我有一个用来取代cmdlet的,由于缺乏灵活性
  • 我的自定义函数我通过这个功能的文件或文件夹对象,通过管道

这是函数:

function Get-ChildItemCustom { 
    Param(
     [Parameter(ValueFromPipeline=$true)] 
     [System.IO.FileSystemInfo] $item, 
     [Parameter(ValueFromPipeline=$false)] 
     [string] $archive_path 
    ) 
    Process { 
     Get-ChildItem $item 
    } 
} 

我想能够使用这个功能就像Get-ChildItem:输入一个[System.IO.FileSystemInfo]对象,并获取所有的孩子(排序有一些额外的标准,我没有包括在这里)作为输出。

这是我如何调用该函数:

Get-ChildItem $parentfolder_path | 
    Get-ChildItemCustom | 
    Do-SomethingElse 

错误再次解释说,Get-ChildItem的结果(这是可验证[System.IO.FileSystemInfo]类型)被视为字符串。

不能转换 “E:\ DATA \ VHG-ITC-TEST \新建文件夹\档案” 类型 “System.String” 的值输入 “System.IO.FileSystemInfo”。

参数之前的类型并不总是存在的。当$item没有明确有型,功能会误读输入(据说仅服用Name属性作为输入):

GET-ChildItem:找不到路径“C:\ WINDOWS \ SYSTEM32 \新建文件夹”因为它不存在。

所以该函数似乎无法正确接受对象输入。我要不惜一切代价避免使用字符串,只是走动的对象。我是否设置了错误的参数?我能做什么?

回答

1

问题不在于你的功能,而在于Get-ChildItem处理参数的方式(因为Moerwald在他的回答中已被怀疑)。

当调用Get-ChildItemFileInfo对象作为参数被传递给所述第一位置参数(-Path),它需要一个字符串数组作为输入未命名的参数,因此该对象被转换为一个字符串。然而,在某些情况下,铸造FileInfo对象为字符串扩展FullName财产,而在其他扩展只是Name属性(我无法解释PowerShell如何决定什么时候能够捡到它,虽然)。后者是你的情况发生了什么。而且,由于Get-ChildItem认为只是一个名字,而不是一个完整的路径,它看起来在当前工作目录,它失败的项目。

有许多的方法来避免这个问题,其中之一Moerwald已经表明。其他是:使用管道传递$itemGet-ChildItem

  • function Get-ChildItemCustom { 
        Param(
         [Parameter(ValueFromPipeline=$true)] 
         [IO.FileSystemInfo]$item, 
    
         [Parameter(ValueFromPipeline=$false)] 
         [string]$archive_path 
        ) 
    
        Process { 
         $item | Get-ChildItem 
        } 
    } 
    
  • 按名称映射转移的财产的完整路径:

    function Get-ChildItemCustom { 
        Param(
         [Parameter(
          ValueFromPipeline=$true, 
          ValueFromPipelineByPropertyName=$true 
         )] 
         [string[]]$FullName, 
    
         [Parameter(ValueFromPipeline=$false)] 
         [string]$archive_path 
        ) 
    
        Process { 
         Get-ChildItem $FullName 
        } 
    } 
    

就个人而言,我更喜欢最后的变体(通过属性名称传递)。