从大量Office文件提取ContentCreated/DateLastSaved的PowerShell问题求助
问题修复方案:旧Word .doc文件元数据提取失效
问题原因
原脚本依赖Shell.Application的GetDetailsOf方法,该方法的属性索引不固定,会随Windows版本、区域设置和文件类型变化,对Word 97-2003的二进制.doc文件兼容性差,导致部分文件无法正确读取ContentCreated和DateLastSaved属性。
替代解决方案:直接调用Word COM对象读取原生元数据
使用Microsoft Word的COM对象直接访问.doc文件的内部属性,避免Shell索引的兼容性问题,准确性更高。
自定义PowerShell函数
function Get-OfficeDocumentMetadata { [CmdletBinding()] param ( [Parameter(Position = 0, ValueFromPipeline)][System.IO.FileInfo] $File ) Begin { # 初始化Word应用程序,后台运行 $wordApp = New-Object -ComObject Word.Application $wordApp.Visible = $false $wordApp.DisplayAlerts = 0 # 禁用警告提示 } Process { foreach ($f in $File) { # 只处理Word文档 if ($f.Extension -notin '.doc', '.docx') { Write-Verbose "跳过非Word文件: $($f.FullName)" continue } try { $document = $wordApp.Documents.Open($f.FullName, $false, $true) # 只读打开 # 提取核心元数据 $metadata = [ordered]@{ Path = $f.FullName ContentCreated = $document.BuiltInDocumentProperties("Creation Date").Value DateLastSaved = $document.BuiltInDocumentProperties("Last Save Time").Value Author = $document.BuiltInDocumentProperties("Author").Value Title = $document.BuiltInDocumentProperties("Title").Value } # 转换为自定义对象输出 [PSCustomObject]$metadata # 关闭文档,不保存 $document.Close($false) } catch { Write-Warning "处理文件失败 $($f.FullName): $_" if ($document) { $document.Close($false) } } } } End { # 释放Word COM对象,避免内存泄漏 $wordApp.Quit() [System.Runtime.Interopservices.Marshal]::ReleaseComObject($document) | Out-Null [System.Runtime.Interopservices.Marshal]::ReleaseComObject($wordApp) | Out-Null [GC]::Collect() [GC]::WaitForPendingFinalizers() } }
使用方法
执行以下命令批量提取并导出:
Get-ChildItem -Recurse -Filter "*.doc" | Get-OfficeDocumentMetadata | Select-Object Path,ContentCreated,DateLastSaved | Export-Csv "DocumentMetadata.csv" -NoTypeInformation
注意事项
- 需安装Microsoft Word(支持Word 97-2003格式的版本均可)
- 处理大量文件时,建议分批次运行,避免内存占用过高
- 若文件为只读/加密状态,需确保当前用户有读取权限
- 函数会后台运行Word,处理完成后自动退出,不会显示界面
内容的提问来源于stack exchange,提问作者Kendall Aughenbaugh
相关产品推荐
相关产品推荐

