0

Is there any way to remove all comments including the comments block in a Word-Document (.docx) using PowerShell?

Illustration:

**enter image description here**

1 Answer 1

1

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()
3
  • Thank you very much by now. I will give it a try next week and then respond you if it worked :)
    – SteffPoint
    Dec 7, 2018 at 7:34
  • No worries, just be sure to really spend time learning how to do this is word VBA directly, as it is what you'll end up doing when you use PS to do this.
    – postanote
    Dec 7, 2018 at 21:04
  • I checked out the script and it is counting the comments correctly. However, I wanted to integrate the remove function for comments, trying things like $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()
    – SteffPoint
    Dec 10, 2018 at 13:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .