1

I am writing a script that scans files for SSNs. I've got most of it working, but this section is giving me grief and I can't find any useful documentation on it.

I'm running into an issue with skipping password protected PowerPoint files.

#Scan for SSN in pptx

$findtext = "\b(?!0{3}|6{3})([0-6]\d{2}|7([0-6]\d|7[012]))([ -]?)(?!00)\d\d\3(?!0000)\d{4}\b"
$pptfiles = Get-Childitem -Path $searchpath -Include *.ppt, *.pptx -Recurse
# Create instance of the PowerPoint.Application COM object
$ppt = New-Object -ComObject PowerPoint.Application
# walk through the collection of slides
foreach ($pptfile in $pptfiles) {

          $presentation = $ppt.Presentations.open($pptfile, [Microsoft.Office.Core.MsoTriState]::msoTrue,
                [Microsoft.Office.Core.MsoTriState]::msoFalse, [Microsoft.Office.Core.MsoTriState]::msoFalse)

  $slidecount = $presentation.Slides.Count
      $slideCounter = 1
      WHILE ($slideCounter -le $slideCount) {      
            $slide = $presentation.slides.item($slidecounter)
            $title = $slide.Shapes[1].TextFrame.TextRange.Text
            $body = $slide.Shapes[2].TextFrame.TextRange.Text
            $arrcontents = @($title, $body)
            ForEach ($line in $arrcontents) {
                  $pptline = $line.trim()
                  If ($pptline -match $findtext) {
                        $Violation = [PSCustomObject]@{
                              Path       = $pptfile | Select-Object | Select-object -ExpandProperty fullname
                              Line       = $pptline
                              LineNumber = "Slide $slideCounter"
                        }
                        $Violation | Select-Object Path, Line, LineNumber | export-csv $outputpath\$PIIFile -append -NoTypeInformation
                  }
            }
            $slideCounter++
      }
      # prevent the Save Presentation prompt from displaying
      $presentation.saved = $true
      # close presentation
      $presentation.close()
} #end for
# release memory
$ppt.quit()
# release the memory immediately
$ppt = $null
$file = $null
Stop-Process -name POWERPNT

I can't check if there is a password automatically without opening the file, which is paradoxical, so my plan was to use a try-catch statement (removed from current code) while opening the file, and pass the password in. The problem is that the parameters for PowerPoint are different than the ones for Word or Excel, so entering a false password in the 5th parameter does not work. This method (below), also does not seem to work.

Presentation presentation = ppApp.Presentations.Open($"{presentationFile}::{password1}::", MsoTriState.msoFalse, MsoTriState.msoFalse, WithWindow: MsoTriState.msoFalse);

Any help would be appreciated. Thanks in advance.

1 Answers1

2

Since Presentations.Open() does not have a password option, you could do this with what you have as a workaround.

Presentations.Open("c:\temp\open.pptx::password::")

Passing a bad password results in a trappable error, thus... I created two new blank pptx files and password protected one and not the other and then did this:

Passing in a bad password

Clear-Host
($filenames = (Get-ChildItem -Path 'D:\Temp' -FIlter '*protected*.ppt*').FullName)

$application = New-Object -ComObject powerpoint.application
$application.visible = "msoTrue"

$filenames | 
ForEach-Object {
    Try
    {
        ($presentation = $application.Presentations.open("$PSitem::{password1}::"))
        Write-Verbose -Message "$PSitem access successful" -Verbose
        $presentation.Close()
    }
    Catch {Write-Warning -Message 'Open failed. Either the file is password protected, corrupt or some other issue'}
    Finally 
    {
        Write-Host "Closing $PSItem" -ForegroundColor Yellow
    }
}

$application.Quit()
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()

# Results
<#
D:\Temp\PresentationNotProtected.pptx
D:\Temp\PresentationProtected.pptx


Application                      : Microsoft.Office.Interop.PowerPoint.ApplicationClass
...
FullName                         : D:\Temp\PresentationNotProtected.pptx
Name                             : PresentationNotProtected.pptx
Path                             : D:\Temp
Saved                            : 0
...
PasswordEncryptionProvider       : 
PasswordEncryptionAlgorithm      : 
PasswordEncryptionKeyLength      : 0
PasswordEncryptionFileProperties : True
Password                         : ********
WritePassword                    : ********
Permission                       : 
...

VERBOSE: D:\Temp\PresentationNotProtected.pptx access successful
Closing D:\Temp\PresentationNotProtected.pptx
WARNING: Open failed. Either the file is password protected, corrupt or some other issue
Closing D:\Temp\PresentationProtected.pptx
#>

Passing in the proper password

($presentation = $application.Presentations.open("$PSitem::password::"))
<#
D:\Temp\PresentationNotProtected.pptx
D:\Temp\PresentationProtected.pptx


Application                      : Microsoft.Office.Interop.PowerPoint.ApplicationClass
...
FullName                         : D:\Temp\PresentationNotProtected.pptx
Name                             : PresentationNotProtected.pptx
Path                             : D:\Temp
...
PasswordEncryptionProvider       : 
PasswordEncryptionAlgorithm      : 
PasswordEncryptionKeyLength      : 0
PasswordEncryptionFileProperties : True
Password                         : ********
WritePassword                    : ********
...

VERBOSE: D:\Temp\PresentationNotProtected.pptx access successful
Closing D:\Temp\PresentationNotProtected.pptx

Application                      : Microsoft.Office.Interop.PowerPoint.ApplicationClass
...
FullName                         : D:\Temp\PresentationProtected.pptx
Name                             : PresentationProtected.pptx
Path                             : D:\Temp
...
PasswordEncryptionProvider       : 
PasswordEncryptionAlgorithm      : 
PasswordEncryptionKeyLength      : 0
PasswordEncryptionFileProperties : True
Password                         : ********
WritePassword                    : ********
Permission                       : 
...

VERBOSE: D:\Temp\PresentationProtected.pptx access successful
Closing D:\Temp\PresentationProtected.pptx
#>
postanote
  • 15,138
  • 2
  • 14
  • 25
  • Nice (you don't need the trailing `::`) - I had no idea this was possible - is it documented somewhere? – mklement0 Dec 12 '20 at 13:35
  • 2
    Thanks for the edits, it was late when I posted this. This approach is just something I stumbled across in the past messing with PowerPoint (and other MSO docs) on another customer MSOffice/Outlook/Exchange development/data classification/discovery project with a WIndows FSRM implementation. Since the approach solved my past issue allowing me to complete the project, I never went back to research it further. Yet, in the normal docs, I've not seen it documented by MS anywhere as I am currently working similar (Azure RMS/AIP/MIP) project. – postanote Dec 12 '20 at 22:55
  • Yes! Thank you. That method works. I was using "$pptfile::password" and "{$pptfile::password}", but they weren't working. "$pptFile::{password}::" Did the trick. – Zachary Johnson Dec 14 '20 at 15:07
  • No problem. Thanks again. – Zachary Johnson Dec 16 '20 at 16:53