Is there any way to remove all comments including the comments block in a Word-Document (.docx) using PowerShell?
Illustration:
Super User is a question and answer site for computer enthusiasts and power users. It only takes a minute to sign up.
Sign up to join this communityIs there any way to remove all comments including the comments block in a Word-Document (.docx) using PowerShell?
Illustration:
You need to call into the MSOffice DOM, using COM with PowerShell. PowerShell cannot do this by itself.
You use PowerShell to start word - you have to understand PowerShell to do this.
Use the Word DOM language to make whatever changes you are after. - you have to understand Word programming and the Office DOM to do this.
There are lots of examples of how to leverage PowerShell to affect word and other docs.
Manipulating word with PowerShell all over the web.
Beginning with PowerShell and Word
Generate Word documents with PowerShell
Weekend Scripter: Add Comment to Word Doc
Use PowerShell to Count Comments in Word Docs
$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()
Though the above is about counting, the same type of approach can be used to remove.
Never run any code you do not fully understand / can trust, no matter where you get it from.
Plan this out. Write your code Test your code Come back if you have issues.
Update for OP
As for your query ..
trying things like $doc.Comments.remove or $doc.DeleteAllComments.
… don't guess at this. You can literally open word, start the macro recorder, try what you are doing my clicking through the doc, the recorder would write the code for you, that you can that save and put into your script. Yes, you have to save a doc when you make changes to it, just as you would if you were doing it live in Word.
The default to delete comments in a word doc as shown via Word Macros is...
ActiveDocument.DeleteAllComments
If you wanted to walk the doc... then something like this psudo-code...
ActiveDocument.Comments | ForEach {$_.Delete}
Again, this part is not really a PowerShell thing, but understanding what MSWord expects and how to navigate that model.
Which is always why I tell folks, don't over complicate these sorts of things. Do this stuff in Word Macro/VBA and then export for use in automation tools like PowerShell. If you can't do it natively in Word, PowerPoint, etc., it is highly unlikely you'll be able to do it using an external tool.
You can even create a Macro using VBA and save it for use in other doc targets and call that macro via PowerShell.
Example:
Call Word vba Macro from PowerShell
https://blogs.technet.microsoft.com/stefan_stranger/2016/03/15/call-word-vba-macro-from-powershell
You have to use the methods the Word, PowerPoint, etc., gives you, so you have to know what they are and thus how to look them up. This is what the Get-Member cmdlet is for. You don't need this, Get-Member line in your code, I just put it there a point of instruction.
$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()
$doc.Comments.remove
or $doc.DeleteAllComments
. But I didn't succeed yet. Also I can't find (using popular search engines) any method for deleting comments. Can you help me out here, please? I guess after deleting the comments it requires also a function like this: $doc.save()
Dec 10, 2018 at 13:15