如何从PowerShell的Get-ChildItem结果中提取单个文件属性并存入独立数组
问题核心根源
你最初的实现存在两个连锁的逻辑错误,直接导致无法提取独立属性:
- 管道输出被完全打散
在Get-ChildItem后的ForEach-Object块中,你没有把多个属性组装成自定义对象输出,而是把每个文件的5个属性逐个直接输出到管道。PowerShell的管道会将块内所有未赋值的输出全部摊平成一维值流——比如如果匹配到2个PDF文件,最终$fileNames集合会依次装入10个独立值:文件1的FullName、文件1的LastWriteTime、文件1的Exists、文件1的BaseName、文件1的Extension、文件2的FullName...,完全丢失了「值与文件的对应关系」 - 集合元素不再是带属性的对象
打散后的集合元素都是裸的字符串、时间值、布尔值,根本不携带BaseName这类文件对象的属性定义,所以执行$file."BaseName"自然无法返回有效结果。
正确实现方案
方案1:手动遍历填充数组(逻辑直观易理解)
核心思路是先拿到完整的带属性的FileInfo对象集合,再逐对象读取属性填充到对应数组,完全避免管道打散问题:
$folderPath = "C:\Users\me\someThing1\someThing2" # 直接获取完整的文件对象集合,不提前拆解属性 $fileObjects = Get-ChildItem -Path $folderPath -Filter *.pdf -Recurse # 初始化目标存储数组 $FullNames = @() $LastWriteTimes = @() $Exists = @() $BaseNames = @() $Extensions = @() # 逐对象匹配属性填充 foreach ($file in $fileObjects) { $FullNames += $file.FullName $LastWriteTimes += $file.LastWriteTime $Exists += $file.Exists $BaseNames += $file.BaseName $Extensions += $file.Extension }
方案2:原生批量属性提取(性能更优,适合大目录遍历)
PowerShell支持直接从对象集合层面批量提取指定属性生成独立数组,不需要手动循环追加,在遍历包含成百上千文件的大目录时,这种写法的运行速度远高于手动循环拼接数组:
$folderPath = "C:\Users\me\someThing1\someThing2" $fileObjects = Get-ChildItem -Path $folderPath -Filter *.pdf -Recurse # 直接批量提取属性生成对应数组 $FullNames = $fileObjects.FullName $LastWriteTimes = $fileObjects.LastWriteTime $Exists = $fileObjects.Exists $BaseNames = $fileObjects.BaseName $Extensions = $fileObjects.Extension
注意:
Get-ChildItem返回的FileInfo对象本身是从磁盘扫描得到的有效条目,正常情况下其Exists属性永远返回$true。如果你的场景需要后续校验文件路径是否真实存在,不要直接依赖这个属性值,需要单独对路径做存在性校验。
内容的提问来源于stack exchange,提问作者rhythmo
相关产品推荐
相关产品推荐

