29 June 2021

PowerShell: Install Fonts

Font installation using PowerShell has changed since Windows 10 1909. The old way of doing it with PowerShell no longer works. This new script was originally written by Ben Reader who is a fellow Microsoft MVP from Australia. I took the script and modified it by improving on user interface and file tweaks. 

This script gets a list of all font files that exist in the same directory. It then parses through each font file getting the font name attribute at which point it copies the file to c:\windows\Fonts. Next, it registers the font by writing the font file name to HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Fonts so that it will show up in a drop-down menu. The script also writes the status of each step to the screen so the person executing it knows if each font install is successful or not. 

You can download the script from my GitHub site


 <#  
      .SYNOPSIS  
           Install Open Text and True Type Fonts  
        
      .DESCRIPTION  
           This script will install OTF and TTF fonts that exist in the same directory as the script.  
        
      .NOTES  
           ===========================================================================  
           Created with:    SAPIEN Technologies, Inc., PowerShell Studio 2021 v5.8.187  
           Created on:      6/24/2021 9:36 AM  
           Created by:      Mick Pletcher  
           Filename:        InstallFonts.ps1  
           ===========================================================================  
 #>  
   
 <#  
      .SYNOPSIS  
           Install the font  
        
      .DESCRIPTION  
           This function will attempt to install the font by copying it to the c:\windows\fonts directory and then registering it in the registry. This also outputs the status of each step for easy tracking.   
        
      .PARAMETER FontFile  
           Name of the Font File to install  
        
      .EXAMPLE  
                     PS C:\> Install-Font -FontFile $value1  
        
      .NOTES  
           Additional information about the function.  
 #>  
 function Install-Font {  
      param  
      (  
           [Parameter(Mandatory = $true)][ValidateNotNullOrEmpty()][System.IO.FileInfo]$FontFile  
      )  
        
      #Get Font Name from the File's Extended Attributes  
      $oShell = new-object -com shell.application  
      $Folder = $oShell.namespace($FontFile.DirectoryName)  
      $Item = $Folder.Items().Item($FontFile.Name)  
      $FontName = $Folder.GetDetailsOf($Item, 21)  
      try {  
           switch ($FontFile.Extension) {  
                ".ttf" {$FontName = $FontName + [char]32 + '(TrueType)'}  
                ".otf" {$FontName = $FontName + [char]32 + '(OpenType)'}  
           }  
           $Copy = $true  
           Write-Host ('Copying' + [char]32 + $FontFile.Name + '.....') -NoNewline  
           Copy-Item -Path $fontFile.FullName -Destination ("C:\Windows\Fonts\" + $FontFile.Name) -Force  
           #Test if font is copied over  
           If ((Test-Path ("C:\Windows\Fonts\" + $FontFile.Name)) -eq $true) {  
                Write-Host ('Success') -Foreground Yellow  
           } else {  
                Write-Host ('Failed') -ForegroundColor Red  
           }  
           $Copy = $false  
           #Test if font registry entry exists  
           If ((Get-ItemProperty -Name $FontName -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Fonts" -ErrorAction SilentlyContinue) -ne $null) {  
                #Test if the entry matches the font file name  
                If ((Get-ItemPropertyValue -Name $FontName -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Fonts") -eq $FontFile.Name) {  
                     Write-Host ('Adding' + [char]32 + $FontName + [char]32 + 'to the registry.....') -NoNewline  
                     Write-Host ('Success') -ForegroundColor Yellow  
                } else {  
                     $AddKey = $true  
                     Remove-ItemProperty -Name $FontName -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Fonts" -Force  
                     Write-Host ('Adding' + [char]32 + $FontName + [char]32 + 'to the registry.....') -NoNewline  
                     New-ItemProperty -Name $FontName -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Fonts" -PropertyType string -Value $FontFile.Name -Force -ErrorAction SilentlyContinue | Out-Null  
                     If ((Get-ItemPropertyValue -Name $FontName -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Fonts") -eq $FontFile.Name) {  
                          Write-Host ('Success') -ForegroundColor Yellow  
                     } else {  
                          Write-Host ('Failed') -ForegroundColor Red  
                     }  
                     $AddKey = $false  
                }  
           } else {  
                $AddKey = $true  
                Write-Host ('Adding' + [char]32 + $FontName + [char]32 + 'to the registry.....') -NoNewline  
                New-ItemProperty -Name $FontName -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Fonts" -PropertyType string -Value $FontFile.Name -Force -ErrorAction SilentlyContinue | Out-Null  
                If ((Get-ItemPropertyValue -Name $FontName -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Fonts") -eq $FontFile.Name) {  
                     Write-Host ('Success') -ForegroundColor Yellow  
                } else {  
                     Write-Host ('Failed') -ForegroundColor Red  
                }  
                $AddKey = $false  
           }  
             
      } catch {  
           If ($Copy -eq $true) {  
                Write-Host ('Failed') -ForegroundColor Red  
                $Copy = $false  
           }  
           If ($AddKey -eq $true) {  
                Write-Host ('Failed') -ForegroundColor Red  
                $AddKey = $false  
           }  
           write-warning $_.exception.message  
      }  
      Write-Host  
 }  
   
 #Get a list of all font files relative to this script and parse through the list  
 foreach ($FontItem in (Get-ChildItem -Path $PSScriptRoot | Where-Object {  
                ($_.Name -like '*.ttf') -or ($_.Name -like '*.OTF')  
           })) {  
      Install-Font -FontFile $FontItem  
 }  
   

1 comments:

  1. Yo!
    This was super helpful for me, currently having to deploy fonts to over 200 laptops in my organization and this has made it a dream.
    Thank you so much for sharing Mick you legend!!

    ReplyDelete