我在这里找到了非常有用的信息来开始使用脚本:
但我不能对几个Word文档做同样的事情 - 例如同一个文件夹中的3或4个单词文档。
我尝试了命令ForEach
,但我总是收到一条错误消息。
有人可以帮我修改以下脚本,以便考虑路径文件夹中的所有word文档吗?
$path = "C:\fso\Test.docx"
$application = New-Object -ComObject word.application
$application.Visible = $false
$document = $application.documents.open($path)
$binding = "System.Reflection.BindingFlags" -as [type]
$customProperties = $document.CustomDocumentProperties
$typeCustomProperties = $customProperties.GetType()
$CustomProperty = "Client"
$Value = "My_WayCool_Client"
[array]$arrayArgs = $CustomProperty,$false, 4, $Value
Try {
$typeCustomProperties.InvokeMember(`
"add", $binding::InvokeMethod,$null,$customProperties,$arrayArgs) |
out-null
} Catch [system.exception] {
$propertyObject = $typeCustomProperties.InvokeMember(`
"Item", $binding::GetProperty, $null, $customProperties, $CustomProperty)
$typeCustomProperties.InvokeMember(`
"Delete", $binding::InvokeMethod, $null, $propertyObject, $null)
$typeCustomProperties.InvokeMember(`
"add", $binding::InvokeMethod, $null, $customProperties, $arrayArgs) |
Out-Null
}
$document.Saved = $false
$document.save()
$application.quit()
$application = $null
[gc]::collect()
[gc]::WaitForPendingFinalizers()
我也试过这个
Get-ChildItem -path $path | Where-Object { $_.Name -like '*.docx' }
和ForEach
cmdlet。
答案 0 :(得分:1)
正如Matt建议的那样,我会在应用程序打开后放入ForEach循环。我还想在ForEach循环中添加关闭当前文档。类似的东西:
$path = "C:\fso\*.docx"
$application = New-Object -ComObject word.application
$application.Visible = $false
ForEach($File in (GCI $path|Select -Expand FullName)){
$document = $application.documents.open($file)
$binding = "System.Reflection.BindingFlags" -as [type]
<Other Commands>
$document.Saved = $false
$document.save()
$document.Close()
}
$application.quit()
$application = $null
[gc]::collect()
[gc]::WaitForPendingFinalizers()
答案 1 :(得分:1)
以下是我能够做到的事情:
#Set the PATH variable to the location where you saved the script and CSV file
$path = "c:\temp\PowerShell Scripts\"
#Set the DOC variable to the location of the document you want to update
$doc = "c:\temp\test.docx"
$application = New-Object -ComObject word.application
$application.Visible = $false
$document = $application.documents.open($doc)
$binding = "System.Reflection.BindingFlags" -as [type]
$customProperties = $document.CustomDocumentProperties
$typeCustomProperties = $customProperties.GetType()
$CustomPropertiesWorklist = Import-Csv $path\args.csv
if($CustomPropertiesWorklist.Count){
for($i = 0; $i -lt $CustomPropertiesWorklist.Count; $i++)
{
$CustomProperty = $CustomPropertiesWorklist[$i].CP
$msoPropertyType = $CustomPropertiesWorklist[$i].Type
$Value = $CustomPropertiesWorklist[$i].Value
[array]$arrayArgs = $CustomProperty,$false,$msoPropertyType,$Value
Try
{
$typeCustomProperties.InvokeMember(`
"add", $binding::InvokeMethod,$null,$customProperties,$arrayArgs) |
out-null
}
Catch [system.exception]
{
$propertyObject = $typeCustomProperties.InvokeMember(`
"Item", $binding::GetProperty,$null,$customProperties,$CustomProperty)
$typeCustomProperties.InvokeMember(`
"Delete", $binding::InvokeMethod,$null,$propertyObject,$null)
$typeCustomProperties.InvokeMember(`
"add", $binding::InvokeMethod,$null,$customProperties,$arrayArgs) |
Out-Null
}
}
}
else
{
$CustomProperty = $CustomPropertiesWorklist.CP
$msoPropertyType = $CustomPropertiesWorklist.Type
$Value = $CustomPropertiesWorklist.Value
[array]$arrayArgs = $CustomProperty,$false,$msoPropertyType,$Value
Try
{
$typeCustomProperties.InvokeMember(`
"add", $binding::InvokeMethod,$null,$customProperties,$arrayArgs) |
out-null
}
Catch [system.exception]
{
$propertyObject = $typeCustomProperties.InvokeMember(`
"Item", $binding::GetProperty,$null,$customProperties,$CustomProperty)
$typeCustomProperties.InvokeMember(`
"Delete", $binding::InvokeMethod,$null,$propertyObject,$null)
$typeCustomProperties.InvokeMember(`
"add", $binding::InvokeMethod,$null,$customProperties,$arrayArgs) |
Out-Null
}
}
$document.Saved = $false
$document.save()
$application.quit()
$application = $null
[gc]::collect()
[gc]::WaitForPendingFinalizers()
答案 2 :(得分:1)
我调整并组合了我在这个线程中找到的一些解决方案,并创建了我认为这样的脚本应该如何表现的方式,即更改多个word文档中的多个自定义属性并自动更新文档中的实际字段。希望这对其他人也有帮助!
您只需要更改将要添加/更新的属性列表,并设置.docx文件所在文件夹的路径,并且应该处理其余文件。
#Comment out (or remove, you barbarian) the properties that do not need updating
$propertiesToUpdate = @{
"Product Name" = "Amazing Product"
"Project Name" = "Best Project"
"Revision (Record)" = "01.00"
"Approved By (Record)" = "Me"
"Date Approved (Record)" = "10.03.2016"
}
#Update the path to the documents to update:
$path = "C:\path\*.docx"
Write-Host -ForegroundColor Cyan "Loading Application..."
$application = New-Object -ComObject word.application
$application.Visible = $false
function AddOrUpdateCustomProperty ($CustomPropertyName, $CustomPropertyValue, $DocumentToChange)
{
$customProperties = $DocumentToChange.CustomDocumentProperties
$typeCustomProperties = $customProperties.GetType()
$binding = "System.Reflection.BindingFlags" -as [type]
[array]$arrayArgs = $CustomPropertyName,$false, 4, $CustomPropertyValue
Try
{
$typeCustomProperties.InvokeMember("add", $binding::InvokeMethod,$null,$customProperties,$arrayArgs) | out-null
}
Catch [system.exception]
{
$propertyObject = $typeCustomProperties.InvokeMember("Item", $binding::GetProperty, $null, $customProperties, $CustomPropertyName)
$typeCustomProperties.InvokeMember("Delete", $binding::InvokeMethod, $null, $propertyObject, $null)
$typeCustomProperties.InvokeMember("add", $binding::InvokeMethod, $null, $customProperties, $arrayArgs) | Out-Null
}
Write-Host -ForegroundColor Green "Success! Custom Property:" $CustomPropertyName "set to value:" $CustomPropertyValue
}
ForEach($File in (GCI $path|Select -Expand FullName))
{
Write-Host -ForegroundColor Cyan "Opening Document..." $File
$document = $application.documents.open($File)
ForEach($property in $propertiesToUpdate.GetEnumerator())
{
AddOrUpdateCustomProperty $($property.Name) $($property.Value) $document
}
Write-Host -ForegroundColor Cyan "Updating document fields."
$document.Fields.Update() | Out-Null
Write-Host -ForegroundColor Cyan "Saving document."
$document.Saved = $false
$document.save()
$document.close()
}
$application.quit()
$application = $null
[gc]::collect()
[gc]::WaitForPendingFinalizers()
Write-Host -ForegroundColor Green "Done!"
答案 3 :(得分:1)
我无法完成上述工作。始终object.GetType()无法检索任何内容,从而导致错误。这就是我为BuiltIn属性工作的原因;同样适用于自定义属性:
#Properties to update (BuiltIn)
$propertyUpdates = @{
"Company" = "Company"
"Manager" = "Manager"
}
#Path to the documents to update:
$path = "C:\FilesToUpdate\*.docx"
Write-Host -ForegroundColor Cyan "Loading Application..."
$app = New-Object -ComObject Word.Application
$app.Visible = $false
ForEach($file in (GCI $path|Select -Expand FullName))
{
Write-Host -ForegroundColor Cyan "Opening document: " $file
$doc = $app.Documents.Open($file)
$binding = "System.Reflection.BindingFlags" -as [type]
Write-Host -ForegroundColor Cyan "Updating document properties..."
ForEach($p in $propertyUpdates.GetEnumerator())
{
Try {
$props = $doc.BuiltInDocumentProperties
$prop = [System.__ComObject].InvokeMember("Item", $binding::GetProperty, $null, $props, $p.Name)
[System.__ComObject].InvokeMember("Value", $binding::SetProperty, $null, $prop, $p.Value)
}
Catch [system.exception] {
write-host -ForegroundColor red "Value not found for $p.Name"
}
}
$doc.Fields.Update() | Out-Null
Write-Host -ForegroundColor Cyan "Saving document."
$doc.Saved = $false
$doc.save()
$doc.close()
}
$app.quit()
$app = $null
[gc]::collect()
[gc]::WaitForPendingFinalizers()
Write-Host -ForegroundColor Green "Done!"