Skip to content
font installation intune
Home » Install fonts with Intune

Install fonts with Intune

Many fonts are already present in Windows 10 and 11. However, a company often has its own font, which is required for compliance with CI/CD on all devices. This can be, for example, "Open Sans", the "German-Swiss basic font" or another font. In such cases I use a PowerShell script within a Win32 package to install / distribute the fonts via Intune.

Table of Contents

Win32 for fonts

Like most of my packages, I build the Win32 package according to the same logic. I mentioned this earlier in the post "my take on win32 apps - Intune" described.
In this example I am installing the font OpenSans by Google, which is used in many websites. Incidentally, to install additional fonts via Intune, you only have to place them in the "Fonts" folder in the package and regenerate the intunewin.

Installing fonts

To install the font on a device, we have to copy it to the "C:\Windows\Fonts" directory and also register it in the Windows Registry under "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts".

Since most fonts consist of several TTF or OTF files, I have structured the package so that you can store them in the Fonts subdirectory. The copying process, including the creation of a registry key, is then carried out automatically for each TTF and/or OTF file within this folder.

Incidentally, in order to be able to reinstall the same package with an extended font if necessary, I store a version in the validation file.

$PackageName = "Company-Fonts" $Version = "1" $Path_4netIntune = "$Env:Programfiles\4net\EndpointManager" Start-Transcript -Path "$Path_4netIntune\Log\$PackageName-install.log" -Force $WorkingPath = "$Path_4netIntune\Data\Fonts" New-Item -ItemType "directory" -Path $WorkingPath -Force Copy-Item -Path ".\Fonts\*" -Destination $WorkingPath -Recurse $AllFonts = Get-ChildItem -Path "$WorkingPath\*.ttf" $AllFonts += Get-ChildItem -Path "$WorkingPath\*.otf" foreach($FontFile in $AllFonts){ try{ Copy-Item -Path "$WorkingPath\$($FontFile.Name)" -Destination "$env:windir\Fonts" -Force -PassThru -ErrorAction Stop New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" -Name $FontFile.Name -PropertyType String -Value $FontFile.Name -Force }catch{ Write-Host $_ } } Remove-Item $WorkingPath -Force -Recurse New-Item -Path "$Path_4netIntune\Validation\$PackageName" -ItemType "file" -Force -Value $Version Stop-Transcript
Code language: PowerShell (powershell)

Uninstalling fonts

When uninstalling, I basically use the same logic as installing, simply that here a delete process is performed as opposed to a copy process and registry creation. I also delete the validation file.

$PackageName = "Company-Fonts" $Path_4netIntune = "$Env:Programfiles\4net\EndpointManager" Start-Transcript -Path "$Path_4netIntune\Log\uninstall\$PackageName-install.log" -Force $WorkingPath = "$Path_4netIntune\Data\Fonts" New-Item -ItemType "directory" -Path $WorkingPath -Force Copy-Item -Path ".\Fonts\*" -Destination $WorkingPath -Recurse $AllFonts = Get-ChildItem -Path "$WorkingPath\*.ttf" $AllFonts += Get-ChildItem -Path "$WorkingPath\*.otf" foreach($FontFile in $AllFonts){ try{ Remove-Item -Path "$WorkingPath\$($FontFile.Name)" -Force Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" -Name $FontFile.Name -Force }catch{ Write-Host $_ } } Remove-Item $WorkingPath -Force -Recurse Remove-Item -Path "$Path_4netIntune\Validation\$PackageName" -ItemType "file" -Force -Value $Version Stop-Transcript
Code language: PowerShell (powershell)

Detection rule

The recognition rule is very simple and checks whether the validation file is available with the corresponding target version as content. If so, "Found it!" output and the Endpoint Manager or Intune knows that the package is available on the end device.

$PackageName = "Company-Fonts" $Version = "1" $ProgramVersion_current = Get-Content -Path "$Env:Programfiles\4net\EndpointManager\Validation\$PackageName" if($ProgramVersion_current -eq $Version){ Write-Host "Found it!" }
Code language: PowerShell (powershell)

Create and distribute Win32 package

With the Intune Win32 Prep Tool the package is created after the CSV and/or the desktop folder is filled:

intunewin creation fonts

We then create a "Windows app (Win32)" and upload the created «install.intunewin» file to MEM/Intune with the appropriate parameters. (Red mandatory, orange optional, but helpful when using the company portal.)

create win32 app intune
Intune win32 app fonts
win32 Intune fonts program
win32 Intune fonts requirements
SurnameFonts or custom name
descriptionNote on the fonts
editorindividually
iconfreely selectable, appears in the company portal
installation command%SystemRoot%\sysnative\WindowsPowerShell\v1.0\powershell.exe -executionpolicy bypass -command .\install.ps1
uninstall command%SystemRoot%\sysnative\WindowsPowerShell\v1.0\powershell.exe -executionpolicy bypass -command .\uninstall.ps1
conditionsx64 and 2004 (Windows version not relevant)
Detection rulecustom script, check.ps1
dependencynone
allocationdepending on requirements

Now you have created the package, uploaded it to the Endpoint Manager and can distribute it to the desired devices. When making changes to the package, don't forget to change the version in both "install.ps1" and "check.ps1".

Video Walkthrough

27 thoughts on “Schriftarten mit Intune installieren”

  1. Pingback: Normal.dotm with Intune (Word template) | scloud

  2. Keep up the good work! Looks like a perfect solution for my needs, but keep running in to a problem.

    I have 18 fonts in the subfolder but only 1 gets installed and I get the following log error:
    Method invocation failed because [System.IO.FileInfo] does not contain a method named 'op_Addition'.
    At C:\WINDOWS\IMECache\698de435-f476-4e88-9b8a-485b822faa63_1\install.ps1:12 char:1
    + $AllFonts += Get-ChildItem -Path "$WorkingPath\*.otf"

    Not a coder so can't decipher how I should correct the install.ps1 to correct this, any chance you know of a fix to fix this error?

    1. Thanks!
      Could be because of the Array "$AllFonts". Did you have only one ".tff" file and multiple ".oft"?
      Anyway, I've made a small update thanks to your feedback.
      Could you test it again with the newest install.ps1 from my repo?

      1. Hi,

        Yes, I have mutiple .otf files and one .tff.

        Yes, I have tried the updated install.ps1 and now i works correctly! Thank you so much for quick response and fix! Works wonderfull!

  3. Hi Florian,

    Thanks for sharing this. I have deployed this as per your demonstration and within EPM I can see successful install status. I checked that the fonts were within C:\Windows\Fonts and have also checked within office. The fonts have not installed. Any ideas?

    Thanks.

    1. Hi Daniel, can you send me the log and your package in a link via the contact form?
      Log location: "C:\Program Files\4net\EndpointManager\Log\Company-Fonts-install.log"

      1. Hi Florian,
        I have found a resolution. I decided to create a ps1 and ran it from my machine and found that the ttf fonts applied, but the otf hadn't. On the back of this, I converted the otf fonts to ttf, recreated as per your demo and then re-deployed. Success 🙂

        Thanks very much for this, it's been really helpful and thanks for replying 🙂

        Side note- (Kind of cheeky) Do you have a similar routine for deploying fonts into Outlook 365 - using mailsettings in reg?
        I have created a ps script using a combo of notepad++ and taking the binary from the mailsettings (in regedit) which works if I run locally, but it fails miserabley- when deployed in InTune using Scripts.

        1. Haven't had the problem with OFT's before. But thanks for the hint, may this help someone else 🙂

          Regarding Outlook 365, no haven't had this challenge so far.

  4. Note that if the 'try' fails, your script still adds the validation showing it installed.
    On my script I changed the catch to the following so that if the try section fails, it will not create the validation file:
    }catch{
    Write-Host $_
    Stop-Transcript
    Exit 1618
    }

  5. I used your example with the Open-Sans font and it's working and I can see the font in the C:\Windows\Fonts folder. I have 2 other fonts that I would like to install via Endpoint Manager/Intune. In Intune they are installed, but I can't find them in the C:\Windows\Fonts folder.

    Do you have any idea?

    Many thanks.

    Great and helpfull script! 🙂

        1. It's still not working properly. The application is installed, but the font is still missing in the Fonts folder (C:\Windows\Fonts).

    1. hi there,
      i am having same issue.
      it says install but there is no fonts in c drive fonts folder.
      how do you solved this issue ?

  6. I followed your directions and on two machines everything was successful, however on a few other machines I see the install failed. Within Intune I see "Access is denied. (0x80070005)". Upon investigating further it looks like Cylance blocked the Install.ps1 script.
    Any thoughts why I might be receiving this error?

      1. Florian, Thank you for your response. Cylance is our Ant-virus, mal-ware, and script protection. No I have never had an Intune script blocked before. I'm wondering if the script is getting blocked because it's calling powershell from a specific location? I do have "\Program Files (x86)\Microsoft Intune Management Extension" whitelisted, thus never have had this issue. I tried to use .\install.ps1 for the install command, but it never installed. I assume this all needs to be done via powershell and no way to install via batch file?
        Thank you for any help you can give me.

        1. Florian,
          Great news I've figured out the issue. The first issue is that Cylance has script control block except when powershell is run from within a particular folder. Since the install path called powershell in a folder which isn't whitelisted it was blocked. The second issue I ran into was the install script for some reason install the 4net folder to program files (x86). So when the check ran, it said the installation failed since it couldn't find the 4net folder. To overcome this, I generated a registry key, which I can use for detection.
          If interested, here's the install command I used. powershell -executionpolicy bypass -file install.ps1.
          I do want to thank you for sharing the scripts and your knowledge with installing font. Without the scripts you wrote, I would have never gottn this far.

          Thank you,
          David

          1. Hi David, thanks for your feedback and the clarification. Happy it works now!
            FYI: your command and the provided from my side do the same, except that mine calls PowerShell in x64 context. It's not necessary in this scenario, but I do it in all my packages, just in case.

  7. Florian,

    Thank you for your script. It does work with new fonts, but i need to overwrite existing fonts as well, such as the Segoe fonts. Most of them fail with the following error below:

    PS>TerminatingError(Copy-Item): "The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: Access to the path 'C:\Windows\Fonts\segoepr.ttf' is denied."
    Access to the path 'C:\Windows\Fonts\segoepr.ttf' is denied.
    PS>TerminatingError(Copy-Item): "The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: Access to the path 'C:\Windows\Fonts\segoeprb.ttf' is denied."

    Any way we can get past this? I have an application that when installed via intune, has issues displaying text. The fix is to overwrite the segoe fonts from a working pc. Works fine if i do it manually, but would like to script it and push out via intune.

    All help is much appreciated!

Leave a Reply

Your email address will not be published. Required fields are marked *