powershellautomationpasswords

Removing passwords from .Docx files using Powershell


I'm very new to Powershell and been banging my head against this for a while, hopefully someone can point me towards where I am going wrong. I am trying to use Powershell to remove the opening passwords from multiple .docx files in a folder. I can get it to change the password to something else but cannot get it to remove entirely, the part in Bold below is where I am getting tripped up and the error code details are at the bottom, appreciate any help with this!

$path = ("FilePath")
$passwd = ("CurrentPassword")
$counter=1
$WordObj = New-Object -ComObject Word.Application
foreach ($file in $count=Get-ChildItem $path -Filter \*.docx) { 
  $WordObj.Visible = $true
  $WordDoc = $[WordObj.Documents.Open](https://WordObj.Documents.Open) 
  ($file.FullName, $null, $false, $null, $passwd)
  $WordDoc.Activate()
  $WordDoc.Password=$null
  $WordDoc.Close()
  Write-Host("Finished: "+$counter+" of "+$count.Length)
  $counter++
}

$WordObj.Application.Quit()
**Error details -** Object reference not set to an instance of an object. At line: 14 char: 5
\+$WordDoc.Password=$Null
\+Category info: Operations Stopped: (:) \[\], NullReferenceException
\+FullyQualifiedErrorId: System.NullReferenceException

I got an answer elsewhere to try using .unprotect instead but not sure how to insert this into my code!


Solution

  • $path    = 'X:\TheFolderWhereTheProtectedDocumentsAre'
    $passwd  = 'CurrentPassword'
    $counter = 0
    $WordObj = New-Object -ComObject Word.Application
    $WordObj.Visible = $false
    
    # get the .docx files. Make sure this is an array using @()
    $documentFiles = @(Get-ChildItem -Path $path -Filter '*.docx' -File)
    foreach ($file in $documentFiles) {
        try {
            # add password twice, first for the document, next for the documents template
            $WordDoc = $WordObj.Documents.Open($file.FullName, $null, $false, $null, $passwd, $passwd)
            $WordDoc.Activate()
            $WordDoc.Password = $null
            $WordDoc.Close(-1)  # wdSaveChanges, see https://learn.microsoft.com/en-us/office/vba/api/word.wdsaveoptions
            $counter++
        }
        catch {
            Write-Warning "Could not open file $($file.FullName):`r`n$($_.Exception.Message)"
        }
    
    }
    
    Write-Host "Finished: $counter documents of $($documentFiles.Count)"
    
    # quit Word and dispose of the used COM objects in memory
    $WordObj.Quit()
    $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($WordDoc)
    $null = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($WordObj)
    [System.GC]::Collect()
    [System.GC]::WaitForPendingFinalizers()