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

281 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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](#features)
2. [Requirements](#requirements)
3. [Installation](#installation)
4. [Usage](#usage)
5. [Output Format](#output-format)
6. [How It Works](#how-it-works)
7. [Performance Notes](#performance-notes)
8. [Troubleshooting](#troubleshooting)
9. [Platform-specific pypff Installation](#platform-specific-pypff-installation)
10. [Project Structure](#project-structure)
11. [FAQ](#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](#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
```bash
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
```bash
python -c "import pypff; import tqdm; print('All good!')"
```
---
## Usage
### Basic usage (process PST files in the script's own directory)
```bash
python Extract.py
```
### Specify a directory
```bash
python Extract.py /path/to/pst/folder
```
```powershell
# 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
```csv
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](#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)
```bash
sudo apt-get install python3-libpff
# or
pip install libpff-python
```
### Linux (Fedora / RHEL)
```bash
sudo dnf install libpff-devel python3-libpff
```
### macOS (Homebrew)
```bash
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):
```powershell
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.*