powershell 为多个文件和子目录设置类别

powershell set category for multiple files and subdirectories

我一直在将 "tags" 放入文件名中,但这种组织大量文件的方式很糟糕。

例如:"ABC - file name.docx"

所以,我想将类别属性设置为 "ABC",而不是使用 PowerShell 将其包含在名称中。该脚本必须在某个文件夹的子目录中找到名称中带有 "ABC" 的所有文件,并将类别属性设置为 "ABC".

所以我在第一部分找到了文件,但我不知道从这里去哪里。

Get-ChildItem -Filter "ABC*" -Recurse

有什么想法吗?

谢谢。

所以这篇大量借鉴了Scripting Guys。我们需要做的是,对于我们找到的每个文件,都使用 Word COM 对象来访问该文件的那些特殊属性。使用当前文件名,我们通过拆分第一个连字符并保存两个部分来提取 "category" 。第一个成为类别,第二个是我们给文件的新名称,假设类别更新成功。

这个还有误差,但是这个

$path = "C:\temp"

# Create the Word com object and hide it sight
$wordApplication = New-Object -ComObject word.application
$wordApplication.Visible = $false

# Typing options for located Word Documents. Mainly to prevent changes to timestamps
$binding = "System.Reflection.BindingFlags" -as [type]

# Locate Documents.
$docs = Get-childitem -path $Path -Recurse -Filter "*-*.docx"
$docs | ForEach-Object{
    $currentDocumentPath = $_.fullname
    $document = $wordApplication.documents.open($currentDocumentPath)
    $BuiltinProperties = $document.BuiltInDocumentProperties
    $builtinPropertiesType = $builtinProperties.GetType()
    $categoryUpdated = $false  # Assume false as a reset of the state.

    # Get the category from the file name for this particular file.
    $filenamesplit =  $_.Name.split("-",2)
    $category = $filenamesplit[0].Trim()

    # Attempt to change the property.
    Try{ 
        $BuiltInProperty = $builtinPropertiesType.invokemember("item",$binding::GetProperty,$null,$BuiltinProperties,"Category")  
        $BuiltInPropertyType = $BuiltInProperty.GetType()
        $BuiltInPropertyType.invokemember("value",$binding::SetProperty,$null,$BuiltInProperty,[array]$category)
        $categoryUpdated = $true
    }Catch [system.exception]{
        # Error getting property so most likely is not populated. 
        Write-Host -ForegroundColor Red "Unable to set the 'Category' for '$currentDocumentPath'" 
    }

    # Close the document. It should save by default. 
    $document.close()

    # Release COM objects to ensure process is terminated and document closed. 
    [System.Runtime.InteropServices.Marshal]::ReleaseComObject($BuiltinProperties) | Out-Null
    [System.Runtime.InteropServices.Marshal]::ReleaseComObject($document) | Out-Null
    Remove-Variable -Name document, BuiltinProperties

    # Assuming the category was successfully changed lets remove the information from the current filename as it is redundant.
    If($categoryUpdated){Rename-Item $currentDocumentPath -NewName $filenamesplit[1].Trim()}
}

$wordApplication.quit()
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($wordApplication) | Out-Null
Remove-Variable -Name wordApplication
[gc]::collect()
[gc]::WaitForPendingFinalizers()

你应该在评论中看到一些解释,我试图添加以进行澄清。另请阅读上面的 link 以获得有关 COM 对象发生的情况的更多解释。