Search code examples
powershellms-officehierarchyonenote

How do I use PowerShell to pull headers from a OneNote document


Background: In my work environment, we have a transitional location for our knowledgebase notes. These reside in a number of OneNote 2016 workbooks which have been maintained over years. I am currently in the middle of delegating content update efforts to our staff and part of this work involves importing all our OneNote notebook names and section names into an excel spreadsheet for hierarchy management.

Task: I spent ages looking online for an easy and quick way to export hierarchy information from OneNote to csv using PowerShell and could not for the life of me find an easy way that worked. The following code resonated through the interwebs but each time I tried to run the code, I kept getting errors.

$onenote = New-Object -ComObject OneNote.Application
$scope = [Microsoft.Office.Interop.OneNote.HierarchyScope]::hsPages
[ref]$xml = $null

$onenote.GetHierarchy($null, $scope, $xml)

$schema = @{one=”http://schemas.microsoft.com/office/onenote/2013/onenote”}

$xpath = “//one:Notebook/one:Section”
Select-Xml -Xml (

$xml.Value) -Namespace $schema -XPath $xpath |
foreach {
$node = $psitem.Node

$npath = Split-Path -Path $node.Path -Parent

$props = [ordered]@{
Workbook =  Split-Path -Path $npath -Leaf
Section = $node.Name
}
New-Object -TypeName PSObject -Property $props
}

Error: The error I would get from executing this code was as follows:

value of type "System.String" to type "System.Xml.XmlNode". At line:10 char:17 + Select-Xml -Xml (


Solution

  • Solution: In the end I had to break down the established connection to the Onenote Application and found a workable solution for OneNote 2016. I've provided my solution but am keen to hear of any other possible ways to manipulate this data effectively in the future:

    Function Get-OneNoteHeaders{ 
    
    [CmdletBinding()]
    Param()
    
    Begin
    {
        $onenote = New-Object -ComObject OneNote.Application
        $scope = [Microsoft.Office.Interop.OneNote.HierarchyScope]::hsPages
        [ref]$xml = $null
        $csvOutput = "c:\temp\onenote-headers.csv"
    }
    Process
    {     
        $onenote.GetHierarchy($null, $scope, $xml)
        [xml]$result = ($xml.Value)
    
        Foreach($notebook in $($result.DocumentElement.Notebook)){
            Add-content -Path $csvOutput -Value "$($notebook.name)"
            Foreach($section in $($notebook.section)){
                Add-content -Path $csvOutput -Value ",$($section.name)"
                Foreach($page in $section.page){
                    Add-content -Path $csvOutput -Value ",,$($page.name)"
                }
            }
        }
    }
    End{}
    }
    
    #Get-OneNoteHeaders