For whatever reason Microsoft Office asks you to individually click all of the downloadable fonts on Word, Excel, and PowerPoint after you have purchased and downloaded them – and just want to use them natively on your device. You should be able to run this in Powershell, or troubleshoot easily from something close to it. I hope this is helpful:
<# .SYNOPSIS Bulk-downloads every Microsoft 365 cloud font into the local FontCache so you don’t have to click each one in the font picker to trigger the on-demand download. .DESCRIPTION Office shows 1,000+ fonts in the font picker, but most are “cloud fonts” – listed with a small cloud icon and only downloaded the first time you apply them. This script drives Microsoft Word via COM automation, iterates Application.FontNames, and applies each font to a throwaway document. That triggers Office to fetch each cloud font into: %LOCALAPPDATA%\Microsoft\FontCache\4\CloudFonts\ Once cached, the fonts are instantly available in Word, Excel, PowerPoint, Outlook, and any other Office app on this machine. .PARAMETER WaitSeconds Seconds to wait after applying all fonts for background downloads to finish. Default: 60. Increase if you have a slow connection or many uncached fonts. .PARAMETER ListNewFiles Switch – if set, prints every newly downloaded font file at the end. Default off (just shows totals; the list can be hundreds of lines). .NOTES - Requires Microsoft Word (Office 2016+ or Microsoft 365 recommended). - Word will open visibly during the run; please don’t interact with it. - Safe to run with Word already open – uses a separate COM instance and only closes the throwaway document it creates (your existing docs are untouched), but for cleanest results close other Word windows first. - Cloud font URLs/cache schema can change between Office versions; if you’re on something pre-2016, the cache path may differ. - Use freely. No warranty. .EXAMPLE powershell -NoProfile -ExecutionPolicy RemoteSigned -File .\Download-AllOfficeFonts.ps1 .EXAMPLE powershell -NoProfile -ExecutionPolicy RemoteSigned -File .\Download-AllOfficeFonts.ps1 -WaitSeconds 120 -ListNewFiles #> [CmdletBinding()] param( [int]$WaitSeconds = 60, [switch]$ListNewFiles ) $ErrorActionPreference = ‘Stop’ $cloudFontsPath = Join-Path $env:LOCALAPPDATA ‘Microsoft\FontCache\4\CloudFonts’ function Get-CacheSnapshot if (-not (Test-Path $cloudFontsPath)) { return @() } Get-ChildItem $cloudFontsPath -File -Recurse -ErrorAction SilentlyContinue # — Pre-flight: confirm Word is installed — if (-not [Type]::GetTypeFromProgID(‘Word.Application’)) Write-Host “ERROR: Microsoft Word does not appear to be installed on this machine.” -ForegroundColor Red Write-Host “This script drives Word via COM automation and requires Office 2016+ or Microsoft 365.” exit 1 } $before = Get-CacheSnapshot $beforeSize = if ($before) { ($before else 0 } Write-Host (“Before: {0} files, {1:N1} MB in cache” -f $before.Count, ($beforeSize / 1MB)) Write-Host “Starting Word (will open visibly - please don’t interact with it)…” $word = $null try { $word = New-Object -ComObject Word.Application } catch { Write-Host “ERROR: Failed to start Word via COM: $_” -ForegroundColor Red exit 1 } $word.Visible = $true # must be visible so the layout engine renders & triggers downloads $word.DisplayAlerts = 0 # wdAlertsNone $doc = $null try { $doc = $word.Documents.Add() $selection = $word.Selection $fontNames = $word.FontNames $total = $fontNames.Count Write-Host “Office reports $total fonts. Cycling through each…” $errors = 0 $applied = 0 for ($i = 1; $i -le $total; $i++) { $name = $fontNames.Item($i) try { $selection.Font.Name = $name $selection.TypeText(“$name`r”) $applied++ if ($i % 50 -eq 0) { Write-Host (" [{0}/{1}] {2}" -f $i, $total, $name) $doc.Repaginate() } catch $errors++ } } Write-Host (“Applied {0} fonts ({1} errors).” -f $applied, $errors) try { $doc.Repaginate() catch } Write-Host “Waiting $WaitSeconds s for background downloads to settle…” for ($t = 0; $t -lt $WaitSeconds; $t += 10) { Start-Sleep -Seconds 10 $now = Get-CacheSnapshot Write-Host (" +{0}s: {1} files in cache" -f ($t + 10), $now.Count) } } finally { if ($doc) { try { $doc.Close(0) catch } } # 0 = wdDoNotSaveChanges if ($word) { try { $word.Quit() catch } [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($word) } [System.GC]::Collect() [System.GC]::WaitForPendingFinalizers() } # — Summary — $after = Get-CacheSnapshot $afterSize = if ($after) { ($after else 0 } $beforePaths = $before $new = $after | Where-Object $_.FullName -notin $beforePaths } Write-Host “” Write-Host (“After: {0} files, {1:N1} MB in cache” -f $after.Count, ($afterSize / 1MB)) Write-Host (“Delta: +{0} files, +{1:N1} MB downloaded” -f $new.Count, (($afterSize - $beforeSize) / 1MB)) if ($ListNewFiles -and $new.Count -gt 0) { Write-Host “” Write-Host “Newly downloaded files:” $new ({1:N0} KB)" -f (Split-Path $.FullName -Leaf), ($.Length / 1KB)) } } submitted by /u/staying-human
Originally posted by u/staying-human on r/ClaudeCode
