3

PURPOSE

The script should iterate through each file in a folder, convert to .txt and upload text to Azure database

PROBLEM

Everything works fine up until it hits a password protected file, I just want to skip these files. I am running this on hundreds of thousands of documents and the script will pause if it hits a password protected file until you either enter the password or click Cancel.

SCRIPT

Write-Output "Processing: $($file)"
Try {
    $doc = $word.Documents.OpenNoRepairDialog($file)
}
Catch {

}

if ($doc) {
    $fileName = [io.path]::GetFileNameWithoutExtension($file)
    $fileName = $filename + ".txt"
    $doc.SaveAs("$env:TEMP\$fileName", [ref]$saveFormat)
    $doc.Close()


    $4ID = $fileName.split('-')[-1].replace(' ', '').replace(".txt", "")
    $text = Get-Content -raw "$env:TEMP\$fileName"
    $text = $text.replace("'", "")

    $query += "
    ('$text', $4ID),"
    Remove-Item -Force "$env:TEMP\$fileName"
}

SOLUTION

For anyone having the same issue, the solution was to pass a non empty string to the open call like so:

$wd.Documents.Open($file, $false, $falsel, $false, "ttt")

rather than

$wd.Documents.Open($file, $false, $falsel, $false, "")
Owain Esau
  • 1,876
  • 2
  • 21
  • 34

1 Answers1

6

Here is a demo script of indicating if a Word document is password protected in the current directory. If the file opening doesn't get triggered by the catch block, continue your logic in the try block.

$wd = New-Object -ComObject Word.Application

$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
$files = Get-ChildItem $dir -Include *.doc, *.docx -Recurse

foreach ($file in $files) {
    try {
        $doc = $wd.Documents.Open($file, $null, $null, $null, "")
    } catch {
        Write-Host "$file is password-protected!"
    }
}

You will need to integrate the rest of your logic if you choose this approach, but it shows the general idea of checking password protected files.

RoadRunner
  • 25,803
  • 6
  • 42
  • 75
  • 1
    Had to change $file to $file.fullname in the Open call to get this to run. Unfortunately, this still pauses the script execution as the catch block doesn't trigger until you click cancel on the password prompt. – Owain Esau Nov 05 '18 at 03:12
  • @OwainEsau I'm not sure why it would do that for you. Perhaps you can try some of the approaches in [this](https://stackoverflow.com/questions/17389528/how-to-check-if-a-word-file-has-a-password) answer. – RoadRunner Nov 05 '18 at 03:37
  • Hi, I have been through all of those suggestions. If it runs it always tries to open the file and hangs. – Owain Esau Nov 05 '18 at 03:39
  • Do you know what Word versions you are trying to open? – RoadRunner Nov 05 '18 at 03:41
  • Office 365 - Word V 16.0.9126.2295 - 32 bit – Owain Esau Nov 05 '18 at 03:53
  • All the files were updated to the newest format, also tried as a .doc file rather than docx – Owain Esau Nov 05 '18 at 03:56
  • 3
    Figured it out, i had to change $wd.Documents.Open($file, $null, $null, $null, "") to $wd.Documents.Open($file, $false, $falsel, $false, "ttt") not sure why but word was opening when an empty string was used as the password. – Owain Esau Nov 05 '18 at 04:30
  • 1
    @OwainEsau Sorry I'm pretty rusty and powershell and don't use it often. Would explain why I missed that. Glad to hear it solved your problem. – RoadRunner Nov 05 '18 at 04:34
  • Here's the documentation on the Open methid: https://learn.microsoft.com/en-us/office/vba/api/word.documents.open – Jane Panda Oct 04 '19 at 15:26