Automate Font Inventory with ShowInstalledFonts (PowerShell & Scripts)
Overview
ShowInstalledFonts is a utility/approach for enumerating fonts installed on a system. Automating a font inventory with it (or similar commands/scripts) lets you regularly collect font names, file paths, versions, and metadata for audits, design asset management, or deployment checks.
Goals
- Produce a consistent, machine-readable list of installed fonts.
- Include font name, file path, style/weight, and file metadata (version, date).
- Export to CSV/JSON for reporting or integration with asset systems.
- Run on demand or schedule (Task Scheduler / cron) and optionally centralize results.
Windows — PowerShell approach (example)
Use PowerShell to read installed fonts from the Fonts folder and registry, then export CSV/JSON.
Example script (PowerShell):
powershell
\(fontDirs</span><span> = @</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(163, 21, 21);">"</span><span class="token" style="color: rgb(54, 172, 170);">\)env:windir\Fonts”) \(fonts</span><span> = @</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span> </span> <span></span><span class="token" style="color: rgb(0, 128, 0); font-style: italic;"># Gather font files</span><span> </span><span></span><span class="token" style="color: rgb(57, 58, 52);">Get-ChildItem</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span>Path </span><span class="token" style="color: rgb(54, 172, 170);">\)fontDirs -Include .ttf,.otf,.ttc -Recurse | ForEach-Object { \(file</span><span> = </span><span class="token" style="color: rgb(54, 172, 170);">\) try { \(family</span><span> = </span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(57, 58, 52);">Get-Content</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span>Path </span><span class="token" style="color: rgb(54, 172, 170);">\)file.FullName -Encoding Byte -TotalCount 100) # placeholder for parsing } catch {} \(fonts</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">+=</span><span> </span><span class="token">[PSCustomObject]</span><span>@</span><span class="token" style="color: rgb(57, 58, 52);">{</span><span> </span><span> Name = </span><span class="token" style="color: rgb(54, 172, 170);">\)file.BaseName Path = \(file</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span>FullName </span><span> SizeKB = </span><span class="token">[math]</span><span>::Round</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(54, 172, 170);">\)file.Length/1KB,2) LastWrite = \(file</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span>LastWriteTime </span><span> </span><span class="token" style="color: rgb(57, 58, 52);">}</span><span> </span><span></span><span class="token" style="color: rgb(57, 58, 52);">}</span><span> </span> <span></span><span class="token" style="color: rgb(0, 128, 0); font-style: italic;"># Optionally add registry-sourced names</span><span> </span><span></span><span class="token" style="color: rgb(54, 172, 170);">\)regFonts = Get-ItemProperty -Path “HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts” foreach (\(name</span><span> in </span><span class="token" style="color: rgb(54, 172, 170);">\)regFonts.PSObject.Properties.Name) { \(fonts</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">+=</span><span> </span><span class="token">[PSCustomObject]</span><span>@</span><span class="token" style="color: rgb(57, 58, 52);">{</span><span> </span><span> Name = </span><span class="token" style="color: rgb(54, 172, 170);">\)name RegistryEntry = \(regFonts</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span class="token" style="color: rgb(54, 172, 170);">\)name } } # Deduplicate and export \(fonts</span><span> = </span><span class="token" style="color: rgb(54, 172, 170);">\)fonts | Sort-Object Name -Unique \(fonts</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">|</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">Export-Csv</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span>Path </span><span class="token" style="color: rgb(163, 21, 21);">".\InstalledFonts.csv"</span><span> </span><span class="token" style="color: rgb(57, 58, 52);">-</span><span>NoTypeInformation </span><span></span><span class="token" style="color: rgb(54, 172, 170);">\)fonts | ConvertTo-Json | Out-File ”.\InstalledFonts.json”
Notes:
- Use a font-parsing library (e.g., SharpFont, FontTools via Python) to extract internal font family/style/version.
- Run PowerShell as admin if accessing system-wide registry entries.
Cross-platform — Python approach
Use Python with fontTools to read font metadata on Windows, macOS, and Linux.
Example (Python):
python
from fontTools.ttLib import TTFont from pathlib import Path import json, csv font_paths = [] # common dirs dirs = [Path.home()/”.fonts”, Path(”/usr/share/fonts”), Path(”/Library/Fonts”), Path(“C:/Windows/Fonts”)] for d in dirs: if d.exists(): font_paths += list(d.rglob(“.ttf”)) + list(d.rglob(“.otf”)) + list(d.rglob(“.ttc”)) records = [] for p in set(font_paths): try: tt = TTFont(str(p)) name = None for rec in tt[‘name’].names: if rec.nameID == 1 and rec.platformID == 3: name = rec.string.decode(‘utf-16-be’, errors=‘ignore’) break records.append({ “name”: name or p.stem, “path”: str(p), “size_kb”: round(p.stat().st_size/1024,2) }) except Exception: records.append({“name”: p.stem, “path”: str(p)}) # export CSV/JSON keys = records[0].keys() with open(‘fonts.csv’,‘w’,newline=“,encoding=‘utf-8’) as f: writer = csv.DictWriter(f, fieldnames=keys) writer.writeheader() writer.writerows(records) with open(‘fonts.json’,‘w’,encoding=‘utf-8’) as f: json.dump(records,f,ensure_ascii=False,indent=2)
Scheduling & Centralization
- Windows: Task Scheduler to run PowerShell; use scheduled task to push CSV/JSON to network share or via secure SCP/SFTP.
- macOS/Linux: cron or launchd; use rsync/SCP or HTTP API to POST results to central server.
- Use unique filenames with timestamps, and rotate/remove old reports.
Best practices
- Include hostname, OS, username, and timestamp in exports.
- Hash font files (SHA256) to detect duplicates/changes.
- Store a canonical mapping of font family → file(s) for license tracking.
- Respect licensing — do not redistribute font files unless permitted.
- Validate output schema to make downstream parsing reliable.
Quick checklist to implement
- Choose script: PowerShell (Windows) or Python (cross-platform).
- Extract file path, internal name, style, version, size, and timestamp.
- Export CSV and JSON; include host metadata.
- Schedule runs and secure transfer to central storage.
- Add hashing and periodic diff checks.
If you want, I can generate a ready-to-run PowerShell script that extracts internal font names (using a library) or a Python package-ready script with installation instructions.
Leave a Reply