OneNoteにはエクスポート機能が備わっている。ノート、セクション、ページ、それぞれの単位で1ファイルにエクスポートできるのだが、次のような場合のエクスポートには対応していない。
- 異なる複数のページを、それぞれ個別のファイルにエクスポートする
- ノート、セクション配下の全ページを、それぞれ個別のファイルにエクスポートする
またサポートしている出力フォーマットも限られており、例えばMarkdownのような未対応のフォーマットの場合、エクスポートしたファイルを変換する必要がある。
いずれの場合においても、自動的かつ効率的に処理を行うためには、プログラムの力を借りたくなる場面だ。
この投稿では、PowerShellとOneNoteとの連携方法、エクスポートしてファイルをMarkdownへ変換するまでの手順を紹介する。
事前注意
PowerShellのバージョン
Windows Terminalから動作させるものも含め、PowerShellはWindowsに標準搭載される一機能となった。だからこそ気づきにくいのだが、PowerShellには異なる2つの系統が存在している。*1
Desktop | Ver 5.1まで | .NET Framework上で実行実行される |
Core | Ver 6.0以降 | .NET Core上で実行される |
この投稿で紹介するスクリプトはDesktopで動作するが、Coreでは動作しない。もしWindows TerminalでPower Shellを実行している場合、次の機能のいずれかで新しいタブを開くとよい。
- Windows PowerShell
- Developer PowerShell for VS 2022
階層構造の取得
OneNoteのデータはフォルダとファイルの組み合わせで構成されており、各ページはファイル中のデータとして処理されている*4。COMオブジェクトを介して、この構成情報をXMLとして取得することができる。PowerShellに限らず、プログラムを介してOneNoteの情報を操作する場合、基本的に、このXMLオブジェクトを参照、操作することになる。
GetHierarchyメソッド*5を実行すると、その引数である$HierarchyにXMLのポインタが格納される。
$OneNote = New-Object -ComObject OneNote.Application Add-Type -assembly Microsoft.Office.Interop.OneNote $OneNoteID = "" [xml]$Hierarchy = "" $OneNote.GetHierarchy( $OneNoteID, [Microsoft.Office.InterOp.OneNote.HierarchyScope]::hsPages, [ref]$Hierarchy, [Microsoft.Office.InterOp.OneNote.XMLSchema]::xsCurrent)
OneNote内のデータには、ノートからセクション、ページに至るまで内部IDが割り当てられている。引数$OneNoteIDに該当するIDを指定することで、そのノード配下の階層構造を取得することができる。このIDについては後述する。
IDを指定すれば、XML中の特定ノードを参照できる。つまり、OneNote内のノートやセクション、ページを参照することができる。OneNote内のノートやセクション、ページを編集するのは、XMLを編集することと同じだ。これをプログラムを介して行う。
IDに何も指定しなければ、OneNoteのルート・ノードが指定されたことになり、全てのノートブックの全階層を取得できる。次のコード(onenote-printall.ps1)を実行すると、それらの情報を出力することができる。
IDの取得、CSVファイルでの出力
特定のノートブックやセクション以下の全ページ、あるいは階層に関わらない特定のページ群などに対してバルク処理を行うとしよう。XMLの階層構造を辿りながら逐次処理するプログラムよりも、対象IDに対するループ処理としてプログラムする方が分かりやすいし、作業効率も良い。
そのためには、全IDを取得し、操作対象となるIDを事前に特定しておく必要がある。
次のコード(onenote-makecsv.ps1)を実行すると、全ノードのIDをCSVファイルとして出力することができる。
なおプログラム、並びにCSV中の”depth”は階層構造を表している。ルート・ノードから階層構造を捉えた場合、それぞれの番号が次のように対応している。
1 | notebook |
2 | section group section |
3~ | page |
OneNoteページのエクスポート、Markdownへの変換
注意:Markdownへの変換
OneNoteはエクスポート機能を有しているが、対応フォーマットは限られている。Markdownのようにサポートされていないフォーマットでエクスポートしたい場合、まずOneNoteがサポートしているフォーマットで文書をエクスポートし、そのファイルを目的のフォーマットへ変換する必要がある。
例えば、Wordフォーマット(docxファイル)でエクスポートし、それをPandoc*6を用いてMarkdownへ変換する、といった具合だ。
注意:実行ユーザーの統一→管理者として実行
ここで紹介する注意事項は、おそらくOneNote操作で最大のハマりどころだ。当たり前の事として暗黙に把握されているのか、Microsoftサイトを含め、これを紹介しているサイトを見たことがない。
- スクリプト実行中(特にPublishメソッド*7実行時)、OneNoteを起動しておくこと
- Windows Terminal、PowerShell、スクリプト、OneNoteの実行ユーザーが同一であること
OneNoteオブジェクトのメソッドPublishは、OneNote本体のエクスポート機能に依存しているようだ。これを実行するとき、OneNoteが動作している必要がある。つまり、スクリプト実行前にOneNoteを起動しておく必要がある。
同一のユーザーで操作していても、セキュリティの都合上、システム上のユーザーが細分化され、異なるユーザーで実行されていることがある。共通ユーザーによる構成要素の実行を担保するには、全ての構成要素を管理者として実行するのがよい。
事前にOneNoteを起動していない場合、あるいは実行ユーザーに不整合がある場合、次のエラーが出力される。これで、以上2つのいずれかの原因にたどり着くのは、まず無理だろう。
The remote procedure call failed. (Exception from HRESULT: 0x800706BE)
OneNoteのエクスポート
次の情報を指定してPublishメソッドを実行することで、指定したIDの情報をエクスポートすることができる。
もし単一のノートやセクションをエクスポートするかどうかに関わらず、単一のページを1ファイルとしてエクスポートするならば、対象となるページのIDを指定し、それを必要回数だけ実行することになる。
単一のノートやセクションなど、まとまったページを1ファイルとしてエクスポートするならば、そのノートやセクションのIDを指定すればよい。
このようなIDの確認、特定に、先に出力しておいたCSVファイルが役に立つ。
次のサンプル・コード(onenote-exportmakecsv.ps1)は、ある単一ページを一つのファイルとして出力し、それをMarkdownファイルに変換している。
添付画像は、OneNote内の1ページが、Wordファイルとしてエクスポートされ、Markdownに変換された変遷を表している。