答案1
您需要使用 PowerShell 中的 COM 调用 MSOffice DOM。PowerShell 本身无法执行此操作。
您使用 PowerShell 来启动 Word - 您必须了解 PowerShell 才能执行此操作。
使用 Word DOM 语言进行您想要的任何更改。 - 您必须了解 Word 编程和 Office DOM 才能执行此操作。
有很多关于如何利用 PowerShell 影响 Word 和其他文档的示例。
在整个网络上使用 PowerShell 操作文字。
$Path = "E:\data\BookDOcs\PS3_StartHere"
$word = New-Object -comobject word.application
$word.visible = $false
Foreach($filepath in (Get-ChildItem $path -Filter *.docx -Recurse))
{
$doc = $word.documents.open($filePath.FullName)
$count = $doc.Comments.count
if( $count -ge 1)
{"$count comments in $filepath"}
$doc.close()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($doc) | Out-Null
Remove-Variable Doc
}
# CleanUp
$word.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($word) | Out-Null
Remove-Variable Word
[gc]::collect()
[gc]::WaitForPendingFinalizers()
虽然以上是关于计数,但可以使用相同类型的方法来删除。
永远不要运行任何你不完全理解/不能信任的代码,无论你从哪里获得它。
制定计划。编写代码,测试代码,如果有问题,请回来。
OP 更新
至于您的疑问..
尝试$doc.Comments.remove 或 $doc.DeleteAllComments 之类的方法。
…不要猜测。您可以直接打开 Word,启动宏录制器,尝试单击文档执行的操作,录制器会为您编写代码,您可以保存并放入脚本中。是的,您必须在对文档进行更改后保存它,就像您在 Word 中实时执行操作一样。
通过 Word 宏显示的默认删除 Word 文档中的注释是...
ActiveDocument.DeleteAllComments
如果你想浏览文档...那么像这个伪代码...
ActiveDocument.Comments | ForEach {$_.Delete}
再次强调,这部分实际上并不是 PowerShell 的事情,而是了解 MSWord 的期望以及如何浏览该模型。
这就是为什么我总是告诉大家,不要把这些事情搞得太复杂。在 Word Macro/VBA 中执行这些操作,然后导出以用于 PowerShell 等自动化工具。如果您无法在 Word、PowerPoint 等中本地执行此操作,则您极不可能使用外部工具执行此操作。
您甚至可以使用 VBA 创建宏并将其保存以供其他文档目标使用,并通过 PowerShell 调用该宏。
例子:
从 PowerShell 调用 Word vba 宏
https://blogs.technet.microsoft.com/stefan_stranger/2016/03/15/call-word-vba-macro-from-powershell
您必须使用 Word、PowerPoint 等提供的方法,因此您必须知道它们是什么以及如何查找它们。这就是 Get-Member cmdlet 的用途。您不需要在代码中添加此 Get-Member 行,我只是将其放在一个指令点。
$Path = "D:\Documents\Test document.docx"
$word = New-Object -comobject word.application
$word.visible = $False
Foreach($filepath in (Get-ChildItem $path -Filter *.docx -Recurse))
{
$doc = $word.documents.open($filePath.FullName)
$count = $doc.Comments.count
if( $count -ge 1)
{"$count comments in $filepath"}
# Get all comment properties and methods so to know what can be used
<#
$doc.Comments | Get-Member
TypeName: System.__ComObject#{0002093d-0000-0000-c000-000000000046}
Name MemberType Definition
---- ---------- ----------
Delete Method void Delete ()
DeleteRecursively Method void DeleteRecursively ()
Edit Method void Edit ()
...
#>
# There are only 3 methods possible. Use the required method to handle the target.
$doc.Comments | ForEach{$_.Delete()}
$doc.save()
$doc.close()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($doc) | Out-Null
Remove-Variable Doc
}
# CleanUp
$word.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($word) | Out-Null
Remove-Variable Word
[gc]::collect()
[gc]::WaitForPendingFinalizers()