Powershell script to compare Word templates

I have a PowerShell script that was created by a former colleague. The idea of the script is to open a word file and compare it to the company official templates. Then, it creates an output data file where we have the compliance information for each file. We have over 3000 Word files, the reason why it is done by a script. However, when we try to run the script now,  it doesn't finish running (it stops in the 300). What I noticed is that the word processes it opens, it doesn't close after, so the CPU gets really busy and I believe that's the reason it stops.

Here's the script as of now:

#to enable powershell scripts on your machine:
# * Run a powershell command prompt as Administrator
# * type this :                Set-ExecutionPolicy Unrestricted

function Select-Folder($message='Select a folder', $path = 0) {  
    $object = New-Object -comObject Shell.Application  
     
    $folder = $object.BrowseForFolder(0, $message, 0, $path)  
    if ($folder -ne $null) {  
        $folder.self.Path  
    }  
}  
$folder = Select-Folder -mess 'Select the folder where the Resumes/CVs are'


cd $folder

$word = New-Object -Com Word.Application
$word.Visible = $false #to prevent the document you open to show
$binding = "System.Reflection.BindingFlags" -as [type]
#$files = Get-ChildItem -filter *.doc
#Just attempt to read all files in the directory
$files = Get-ChildItem
$output = Join-Path $pwd.path OUTPUT.dat

function GetTemplateName {
$word = New-Object —ComObject Word.Application
if ($word -eq $null) { Throw ( "Calling Word but not there..")
 }
$doc = $word.Documents.Open($docname, $false, $true) # open in read only mode
if ($doc -eq $null) { Throw ( "DOC = $doc ")
 }

      Foreach($property in $doc.BuiltInDocumentProperties) {
         try {
              $pn = [System.__ComObject].invokemember("name",$binding::GetProperty,$null,$property,$null)
              if ($pn -eq "Template") {
                   $template = [System.__ComObject].invokemember("value",$binding::GetProperty,$null,$property,$null)
                   $result = "$file`t$template"
                   echo $result
                   Add-Content $output $result
                }
            }
         catch {
                $e = $_.Exception
                $msg = $e.Message
                while ($e.InnerException) {
                  $e = $e.InnerException
                  $msg += "`n" + $e.Message
                }
                echo $msg
             }
      }
$doc.Close([ref] $false)
}

Foreach ($file in $files) {
      if ($file.name.toLower().endsWith(".pdf")) {
        $result = "$file`tPDF"
            echo $result
            Add-Content $output $result
      } Elseif ($file.name.endsWith(".doc")) {
            $docname =  Join-Path $pwd.path $file.name
            GetTemplateName
      } Elseif ($file.name.endsWith(".docx")) {
            $docname =  Join-Path $pwd.path $file.name
            GetTemplateName
      } else {
        $result = "$file`tWrong File Format"
            echo $result
            Add-Content $output $result
      }
}

$word.Quit()
Juliana SantosAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

oBdACommented:
Well, in GetTemplateName, you're opening new Word instances without ever closing them, so every call to that function leaves one instance.
This should work:
#to enable powershell scripts on your machine:
# * Run a powershell command prompt as Administrator
# * type this :                Set-ExecutionPolicy Unrestricted

Function Select-Folder($Message='Select a folder', $Path = 0) {
	$shell = New-Object -ComObject Shell.Application
	$folder = $shell.BrowseForFolder(0, $Message, 0, $Path)
	if ($folder) {
		$folder.Self.Path
    }
	[void][Runtime.InteropServices.Marshal]::FinalReleaseComObject($shell)
}

Function Get-WordTemplateName([System.__ComObject]$Word, [string]$Path) {
	Try {
		$result = $null
		$wordDocument = $word.Documents.Open($Path, $false, $true) # open in read only mode
		$propTemplate = $wordDocument.BuiltInDocumentProperties | Where-Object {[System.__ComObject].InvokeMember('Name', 'GetProperty', $null, $_, $null) -eq 'Template'}
		If ($propTemplate) {
			$value = [System.__ComObject].InvokeMember('Value', 'GetProperty', $null, $propTemplate, $null)
			"$($Path)`t$($value)"
		} Else {
			"$($Path)`tNo template found!"
		}
	} Catch {
		$e = $_.Exception
		$msg = $e.Message
		While ($e.InnerException) {
			$e = $e.InnerException
			$msg += "`n" + $e.Message
		}
		Write-Warning $msg
		"$($Path)`tUnable to open: $($_.Exception)"
	}
	If ($wordDocument) {$wordDocument.Close([ref]$false)}
}

$folder = Select-Folder -Message 'Select the folder where the Resumes/CVs are'
If (-not $folder) {Exit}
Set-Location $folder

$word = New-Object -ComObject Word.Application
if (-not $word) {
	Throw "Calling Word but not there.."
}
$word.Visible = $false #to prevent the document you open to show

#$files = Get-ChildItem -filter *.doc
#Just attempt to read all files in the directory
$files = Get-ChildItem 
$output = Join-Path $pwd.path OUTPUT.dat

ForEach ($file in $files) {
	if ($file.Extension -eq ".pdf") {
		$result = "$file`tPDF"
	} ElseIf (".doc", ".docx" -contains $file.Extension) {
		$result = Get-WordTemplateName -Word $word -Path $file.FullName
	} Else {
		$result = "$file`tWrong File Format"
	}
	Write-Output $result
	Add-Content -Path $output -Value $result
}

$word.Quit()
[void][Runtime.InteropServices.Marshal]::FinalReleaseComObject($word)

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Juliana SantosAuthor Commented:
Amazing! I'll give it a try and let you know! Thank you very much for the help! :)
Juliana SantosAuthor Commented:
Thank you very much! It worked like a charm :)
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.