Have you ever needed to find all of the Microsoft Office password-protected files on a file server that contains very large files using PowerShell? I have. While searching for an answer, I came across two methods. Unfortunately, both methods didn't work for me. Ultimately, I found a third method that works very well.
Below, I will discuss each method with examples and provide my recommendation.
Method 1: Open the Document
The first method I encountered involves attempting to open the document, and if that fails, it is assumed that the document is password-protected.
This method fails for me because it causes Office to open a copy of every file it finds. While this might be acceptable for a folder with only a few files, I am dealing with an entire file server, rendering this approach unsuitable. I do not recommend this method.
Method 2: Use Get-Content
The second method I encountered involves reading the file in plain text using Get-Content. Get-Content processes the file and presents each line as an object. With this approach, the script examines each line to determine the presence of "schemas.microsoft.com/office/2006/keyencryptor/password". When this string is detected, it signifies that the file is password protected.
This method fails due to the way Get-Content operates. Employing Get-Content consumes a significant amount of memory. In cases of particularly large office files, this could potentially lead the server to exhaust its RAM and become unresponsive. This is precisely what occurred in my situation. Also, this method can be very slow. I don't recommend this method.
Method 3: The Recommended Method to Finding Office Password-Protected Files Using PowerShell with System.IO.StreamReader
This is the method I've come up with. In this approach, I use the .NET System.IO.StreamReader class. This class is particularly useful when you want to read text content from a source that's too large to load into memory all at once unlike Get-Content. It also gives you control of how many lines of the file you want to read. This is great because the text string I'm looking for is within at most the first 20 to 50 lines of the file. This method is fast, doesn't open the Office application for each file, and doesn't consume horrible amounts of RAM like Get-Content does.
Comment below if you found this helpful.