如何为PowerShell的gci命令输出添加文件属性、排序及获取修改人
解决PowerShell获取带修改时间的Excel文件及最后修改人问题
一、生成带最后修改时间并按时间倒序的Excel文件列表
修改你的脚本,结合排序和属性选择,可以直接输出包含最后修改时间的文件列表,最新文件排在最前面:
# 基础版:输出默认格式的时间和路径 Get-ChildItem -Filter *.xl* -Recurse | Sort-Object -Property LastWriteTime -Descending | Select-Object LastWriteTime, FullName | Out-File AllExcelWithTime.txt
如果需要统一时间格式(比如yyyy-MM-dd HH:mm:ss),让输出更易读,可以用计算属性自定义格式:
# 自定义时间格式版 Get-ChildItem -Filter *.xl* -Recurse | Sort-Object LastWriteTime -Descending | Select-Object @{Name='LastWriteTime'; Expression={$_.LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss')}}, FullName | Out-File AllExcelWithTime.txt -Encoding utf8
各部分说明:
Sort-Object -Property LastWriteTime -Descending:按文件最后修改时间倒序排列,确保最新文件在前Select-Object:指定要输出的属性(最后修改时间、完整路径),自定义时间格式时用@{Name=...; Expression=...}生成格式化后的时间字段-Encoding utf8:可选参数,解决默认UTF-16编码在普通文本编辑器中乱码的问题
二、获取文件的最后修改人信息
获取最后修改人需要依赖NTFS文件系统的属性,且你需要有读取文件权限的权限,有两种常用方法:
方法1:通过文件所有者属性获取(简单但可能不准确)
文件的所有者通常是最后修改文件的用户,但如果有权限变更,可能和实际修改人不一致,适合快速获取:
Get-ChildItem -Filter *.xl* -Recurse | Sort-Object LastWriteTime -Descending | Select-Object @{Name='LastWriteTime'; Expression={$_.LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss')}}, FullName, @{Name='LastModifiedBy'; Expression={(Get-Acl $_.FullName).Owner}} | Out-File AllExcelDetails.txt -Encoding utf8
方法2:读取文件扩展属性(更准确,对应Windows“详细信息”中的“修改者”)
通过Windows Shell组件读取文件的扩展属性,这个值和你在文件属性“详细信息”里看到的“修改者”一致:
$shell = New-Object -ComObject Shell.Application Get-ChildItem -Filter *.xl* -Recurse | Sort-Object LastWriteTime -Descending | ForEach-Object { $folder = $shell.Namespace($_.DirectoryName) $file = $folder.ParseName($_.Name) # 10是“修改者”属性的索引,部分系统/语言可能有差异,可自行验证 $modifiedBy = $folder.GetDetailsOf($file, 10) [PSCustomObject]@{ LastWriteTime = $_.LastWriteTime.ToString('yyyy-MM-dd HH:mm:ss') FullName = $_.FullName LastModifiedBy = $modifiedBy } } | Out-File AllExcelFullDetails.txt -Encoding utf8 # 释放COM对象,避免资源占用 [System.Runtime.Interopservices.Marshal]::ReleaseComObject($shell) | Out-Null
索引验证方法:
如果10对应的不是“修改者”,可以运行以下代码找到对应索引:
$shell = New-Object -ComObject Shell.Application $testFolder = $shell.Namespace("C:\你的测试文件夹路径") for ($i = 0; $i -le 200; $i++) { $propName = $testFolder.GetDetailsOf($testFolder.Items(), $i) if ($propName -eq "修改者") { Write-Host "修改者索引:$i" } } [System.Runtime.Interopservices.Marshal]::ReleaseComObject($shell) | Out-Null
内容的提问来源于stack exchange,提问作者ILoveMadoka
相关产品推荐
相关产品推荐

