Files
PST_Contents_to_TXT/README.md
T
2026-09-13 19:53:09 +01:00

9.8 KiB
Raw Blame History

PST Email Extractor

A command-line tool that scans a directory for Outlook PST files and extracts the metadata of every email — subject, sender, recipients, date, size, attachments count, and message class — into individual CSV files.


Table of Contents

  1. Features
  2. Requirements
  3. Installation
  4. Usage
  5. Output Format
  6. How It Works
  7. Performance Notes
  8. Troubleshooting
  9. Platform-specific pypff Installation
  10. Project Structure
  11. FAQ

Features

  • Batch processing drop any number of .pst files in a folder and run once
  • Resilient extraction corrupt messages are skipped gracefully; processing continues
  • Rich metadata exports 8 fields per message including attachment count and message class
  • Progress bars real-time per-file progress via tqdm
  • UTF-8 output fully compatible with Excel, Google Sheets, and any modern CSV tool
  • Iterative folder traversal avoids Python recursion limits on deeply nested PST archives
  • Human-friendly summaries per-run statistics on success / failure counts

Requirements

Dependency Version Purpose
Python ≥ 3.8 Runtime
tqdm ≥ 4.66 Progress bars
pypff / libpff-python any PST file reading

Note: pypff wraps the native C library libpff. Installation varies by platform — see Platform-specific pypff Installation.


Installation

Step 1 Clone or download the project

Place Extract.py and install_dependencies.py in the same directory.

Step 2 Run the dependency installer

python install_dependencies.py

This script will:

  1. Upgrade pip, setuptools, and wheel.
  2. Install tqdm via pip.
  3. Attempt to install libpff-python / pypff via pip.
  4. Print platform-specific instructions if the automatic install fails.

Step 3 Verify

python -c "import pypff; import tqdm; print('All good!')"

Usage

Basic usage (process PST files in the script's own directory)

python Extract.py

Specify a directory

python Extract.py /path/to/pst/folder
# Windows PowerShell
python Extract.py "C:\Users\You\Desktop\PST_Files"

Example output

📂  Working directory: /data/pst_files

================================================================================
🔍  SEARCHING FOR PST FILES
================================================================================
✓   Found 3 PST file(s)

📁  PST Files:
    1. archive_2021.pst  (1,204.3 MB)
    2. archive_2022.pst  (876.1 MB)
    3. personal.pst      (312.7 MB)

================================================================================
🚀  PROCESSING
================================================================================

────────────────────────────────────────────────────────────────────────────────
📊  1/3  |  ✓ Done: 0  |  ❌ Failed: 0  |  ⏳ Remaining: 2
🔄  archive_2021.pst
  📊 Counting messages in archive_2021.pst …
  ✓  42,817 messages found
  Processing archive_2021.pst: 100%|████████| 42817/42817 [02:14<00:00]
  ✓  Written 42,817 rows  |  Errors skipped: 3
  ✅  Saved → archive_2021_email_list.csv  (42,817 rows)

Output Format

For each input file <name>.pst, a corresponding <name>_email_list.csv is created in the same directory.

CSV columns

Column Description Max Length
Folder Full folder path inside the PST (e.g. Inbox\Projects\2022) 200 chars
Subject Email subject line 500 chars
From Sender name and/or email address 200 chars
To Semicolon-separated recipient list 1000 chars
Date Delivery or submit time in YYYY-MM-DD HH:MM:SS UTC
Size Estimated message size in bytes (sum of body and headers)
Attachments Number of attachments
MessageClass MAPI message class (e.g. IPM.Note, IPM.Appointment) 100 chars

Example rows

Folder,Subject,From,To,Date,Size,Attachments,MessageClass
Inbox,Q3 Budget Review,Alice Smith <alice@example.com>,bob@example.com,2023-09-01 14:22:10 UTC,18432,2,IPM.Note
Sent Items,Re: Proposal,Bob Jones <bob@example.com>,alice@example.com,2023-09-02 09:05:44 UTC,4210,0,IPM.Note
Calendar,,Alice Smith <alice@example.com>,,2023-10-10 09:00:00 UTC,1024,0,IPM.Appointment

How It Works

  1. Discovery find_pst_files() uses glob to locate all .pst files in the given directory.
  2. Counting Before extraction, count_total_messages() recursively counts all messages so tqdm can show an accurate progress bar.
  3. Traversal process_folder() uses an iterative stack (not Python recursion) to walk the full folder tree, guarding against deep nesting and corrupt nodes.
  4. Extraction extract_email_info() wraps every individual attribute access in a try/except so one corrupt property never aborts the whole message.
  5. Writing Results are streamed directly to a UTF-8 CSV file via csv.writer, keeping memory usage flat regardless of PST size.
  6. Error recovery Failed messages are counted and reported in the summary but do not interrupt processing.

Performance Notes

  • Memory The extractor streams rows directly to disk, so even a 50 GB PST file won't exhaust RAM.
  • Speed Processing speed depends on your disk I/O. SSDs can process ~5,00015,000 messages/min; spinning disks are 35× slower.
  • Large recipient lists Recipient lists are capped at 100 entries and 1,000 characters to avoid giant rows.
  • Iterative traversal The folder walker uses an explicit stack instead of recursion, making it safe for PST archives with hundreds of nested folders.

Troubleshooting

ModuleNotFoundError: No module named 'pypff'

Run python install_dependencies.py. If the automatic install fails, see Platform-specific pypff Installation.

Failed to open PST file

  • The file may be in use by Outlook. Close Outlook completely and try again.
  • The file may be corrupted. Try running the Outlook Inbox Repair Tool (scanpst.exe on Windows).

Progress bar reaches 100% but fewer rows are written than expected

This is normal. Some items in a PST folder hierarchy are not email messages (calendar events, contacts, tasks). They are counted in the total but may fail extraction silently. The Errors skipped count in the summary reflects this.

CSV opens with garbled characters in Excel

The CSV is UTF-8. In Excel, use Data → From Text/CSV and choose UTF-8 encoding, or open via File → Open and select the encoding in the import wizard.

Very slow processing on large PST files

Ensure the PST file is on a local drive, not a network share or cloud-synced folder. Network latency multiplies enormously across hundreds of thousands of small reads.


Platform-specific pypff Installation

Linux (Debian / Ubuntu)

sudo apt-get install python3-libpff
# or
pip install libpff-python

Linux (Fedora / RHEL)

sudo dnf install libpff-devel python3-libpff

macOS (Homebrew)

brew install libpff
pip install libpff-python

Windows

Automatic pip installation may fail because libpff requires compilation.

Option 1 Pre-built wheel (if available for your Python version):

pip install libpff-python

Option 2 Build from source follow the official guide: https://github.com/libyal/libpff/blob/main/documentation/Building.md

Option 3 WSL (recommended) Install Windows Subsystem for Linux, then follow the Ubuntu steps above. This is the easiest path for most Windows users.


Project Structure

.
├── Extract.py               # Main extractor  run this
├── install_dependencies.py  # One-time dependency installer
└── README.md                # This file

Outputs are placed alongside the input PST files:

/your/pst/folder/
├── archive_2021.pst
├── archive_2021_email_list.csv   ← generated
├── archive_2022.pst
└── archive_2022_email_list.csv   ← generated

FAQ

Does the tool modify the PST files? No. PST files are opened read-only. The tool never writes to them.

Can I run it on a single PST file instead of a whole directory? Put the PST file in its own folder and pass that folder path. Alternatively, the function export_pst_to_csv(pst_path, output_csv_path) can be imported and called directly from your own script.

What happens if I run it twice on the same directory? Existing CSV files are overwritten without warning. If you want to preserve previous results, move or rename them first.

Does it export email bodies or attachments? No — only metadata is exported. This keeps the output small and avoids legal / privacy issues associated with exporting full message content.

What message types are included? All MAPI message objects found in the PST: emails (IPM.Note), meeting requests (IPM.Schedule.*), appointments (IPM.Appointment), contacts (IPM.Contact), tasks (IPM.Task), etc. The MessageClass column lets you filter by type in your spreadsheet.

Will it work with OST files? libpff has partial OST support. Rename the file to .pst and try — results may vary depending on the OST version and whether the file is currently synced.


For bug reports and feature requests, open an issue in your project repository.