Count pages in word document via Powershell without com object

Viewed 252

I'm trying to write a PowerShell script to count the number of pages in word documents which will end up in a database to be used as a way to assess average number of pages in documents. We have thousands of these word documents which we get from providers and my challenge is that I already have an automated solution in a system without Office apps, meaning no COM object implementation possible. I've been looking at PSWriteWord as an option but the command for getting page settings seems to only work for margin, size and orientation and does not output a page count. Does anyone have a suggestion on how to tackle this one? I'm adding the code I tried with PSWriteWord and the results in case someone sees a fluke in my method.

Import-Module PSWriteWord
$WordDocument = Get-WordDocument -FilePath 'C:\Users\user\Desktop\testdocument.docx'
Get-WordPageSettings -WordDocument $WordDocument  

enter image description here

2 Answers

What you can do is use the Shell.Application object and the System.Document.PageCount standard Windows property, something like this:

$application = New-Object -com "Shell.Application"
$folder = $application.Namespace("c:\myFolder1\myFolder2")
$docfile = $folder.ParseName("myDoc.docx");
Write-Host $docfile.ExtendedProperty("System.Document.PageCount")

This is the equivalent of what you'll see in the Shell's Properties dialog, Details tab.

If Word is not installed at all, this method will only be able to read old Word files (.doc format).

For .docx file (Open Xml format), if Word is not installed, you can use Microsoft's Open Xml SDK. Just download the package from Nuget, extract it, and copy the DocumentFormat.OpenXml.dll somewhere (from net46 folder for example) on your disk. This is the only extra file you'll need.

Once you've done that, this other script will dump the page count:

[System.Reflection.Assembly]::LoadFrom("DocumentFormat.OpenXml.dll") | out-null
$doc = [DocumentFormat.OpenXml.Packaging.WordprocessingDocument]::Open("c:\myFolder1\myFolder2\myDoc.docx", $false)
Write-Host $doc.ExtendedFilePropertiesPart.Properties.Pages.Text
$doc.Dispose()

I just want to give a little back since I got a lot out of this, in case someone comes to this page wondering how to the get the page count of DOC and DOCX files without Word installed. Thanks to Simon Mourier for pointing me in the right direction, I have taken his answers and turned them into a function. As he said, you'll need to download the file DocumentFormat.OpenXml.dll which is contained in the lib\net46 folder within the documentformat.openxml.2.16.0.nupkg file that's available here: https://www.nuget.org/packages/DocumentFormat.OpenXml/ The function takes a PSObject or a string with the path to the file. I'm only using it to return the page count, but you can return many other properties by editing the return line within the function or maybe adding it as a parameter.

function Get-PageCount {
    param (
        $docuName
    )
    if ($docuName -is [string]) {
        $docuName = Get-Item $docuName
    }
    if ($docuName.Extension -eq '.doc') {
        # Process Doc Extension Files
        $application = New-Object -com "Shell.Application"
        $folder = $application.Namespace((Split-Path $docuName))
        $docfile = $folder.ParseName($docuName.Name)
        return $docfile.ExtendedProperty("System.Document.PageCount")
    }
    else {
        [System.Reflection.Assembly]::LoadFrom((Join-Path $appFolder 'DocumentFormat.OpenXml.dll')) | out-null # Replace $appFolder with the location where DocumentFormat.OpenXml.dll was stored 
        $doc = [DocumentFormat.OpenXml.Packaging.WordprocessingDocument]::Open($docuName.FullName, $false)
        return $doc.ExtendedFilePropertiesPart.Properties.Pages.Text
    }
}`
Related