-
-
Save anthonyeden/0088b07de8951403a643a8485af2709b to your computer and use it in GitHub Desktop.
# Run this as a Computer Startup script to allow installing fonts from C:\InstallFont\ | |
# Based on http://www.edugeek.net/forums/windows-7/123187-installation-fonts-without-admin-rights-2.html | |
# Run this as a Computer Startup Script in Group Policy | |
# Full details on my website - https://mediarealm.com.au/articles/windows-font-install-no-password-powershell/ | |
$SourceDir = "C:\InstallFont\" | |
$Source = "C:\InstallFont\*" | |
$Destination = (New-Object -ComObject Shell.Application).Namespace(0x14) | |
$TempFolder = "C:\Windows\Temp\Fonts" | |
# Create the source directory if it doesn't already exist | |
New-Item -ItemType Directory -Force -Path $SourceDir | |
New-Item $TempFolder -Type Directory -Force | Out-Null | |
Get-ChildItem -Path $Source -Include '*.ttf','*.ttc','*.otf' -Recurse | ForEach { | |
If (-not(Test-Path "C:\Windows\Fonts\$($_.Name)")) { | |
$Font = "$TempFolder\$($_.Name)" | |
# Copy font to local temporary folder | |
Copy-Item $($_.FullName) -Destination $TempFolder | |
# Install font | |
$Destination.CopyHere($Font,0x10) | |
# Delete temporary copy of font | |
Remove-Item $Font -Force | |
} | |
} |
Thanks for the script.
I have a bit of an issue, the script seems to work fine on some devices while other with trigger the install and request an admin account to proceed. did you encounter a similar behaviour ? I have Windows 2016 LTSB and 2019 LTSC the newer version seems to process the script without issues.
Has this been resolved? Did you try adjusting script security using Set-ExecutionPolicy
?
From a designer's perspective, this script seems to be ideal for ensuring that all of the fonts necessary for a project have been installed on the working machine. I might tweak it to recursively scan the folders contained in the same directory as the script ($PSScriptRoot
not $Source
). Thanks @anthonyeden
For me this script installs the fonts in the User space, C:\Users\xxxxx\AppData\Local\Microsoft\Fonts...
But it checks if the font is installed in C:\Windows\Fonts, meaning that the IF-block doesn't add anything.
I would rather have the font's installed in C:\Windows\Fonts than in the User space.
I'm new to PowerShell so perhaps I'm doing something wrong? I have tried to debug the script in a "terminal" in Admin mode but it doesn't help.
For me this script installs the fonts in the User space, C:\Users\xxxxx\AppData\Local\Microsoft\Fonts...
But it checks if the font is installed in C:\Windows\Fonts, meaning that the IF-block doesn't add anything.
I would rather have the font's installed in C:\Windows\Fonts than in the User space.I'm new to PowerShell so perhaps I'm doing something wrong? I have tried to debug the script in a "terminal" in Admin mode but it doesn't help.
After debugging the script, it seems that it is not working for me as well.
$SourceDir = "<you path to fonts>"
$Destination = (New-Object -ComObject Shell.Application).Namespace(0x14)
Get-ChildItem -Path $SourceDir -Include '*.ttf','*.ttc','*.otf' -Recurse | ForEach {
# Install font
$Destination.CopyHere($_.FullName,0x10)
}
works for me...
For me this script installs the fonts in the User space, C:\Users\xxxxx\AppData\Local\Microsoft\Fonts...
But it checks if the font is installed in C:\Windows\Fonts, meaning that the IF-block doesn't add anything.
I would rather have the font's installed in C:\Windows\Fonts than in the User space.
True. If you are not an admin this is fine and also the intended functionality. If there is no need to install them system wide its fine like this
The solution I finally found to install fonts system wide was:
foreach($FontFile in Get-ChildItem $fontSourceFolder -Include '*.ttf','*.ttc','*.otf' -recurse ) {
$targetPath = Join-Path $SystemFontsPath $FontFile.Name
if(Test-Path -Path $targetPath){
$FontFile.Name + " already installed"
}
else {
"Installing font " + $FontFile.Name
#Extract Font information for Reqistry
$ShellFolder = (New-Object -COMObject Shell.Application).Namespace($fontSourceFolder)
$ShellFile = $ShellFolder.ParseName($FontFile.name)
$ShellFileType = $ShellFolder.GetDetailsOf($ShellFile, 2)
#Set the $FontType Variable
If ($ShellFileType -Like '*TrueType font file*') {$FontType = '(TrueType)'}
#Update Registry and copy font to font directory
$RegName = $ShellFolder.GetDetailsOf($ShellFile, 21) + ' ' + $FontType
New-ItemProperty -Name $RegName -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Fonts" -PropertyType string -Value $FontFile.name -Force | out-null
Copy-item $FontFile.FullName -Destination $SystemFontsPath
"Done"
}
}
@Sansoria thank you so much! This is exactly what I was looking for, a small code that fits perfectly in a function (plus it works better than others I had found). Tested on Windows 10 Pro 20H2 x64, installs fonts system wide and shows them in Settings and Control Panel.
Also may I suggest you an improvement, although I'm new to PowerShell:
when executing New-ItemProperty
, use $null = New-ItemProperty ...
instead of New-ItemProperty ... | Out-Null
for better performance.
Source: https://powershell-guru.com/powershell-best-practice-12-avoid-out-null/
Thanks again, I wish you a great day :)
I've taken some of the work in this thread along with my own work. It's aimed at storing the fonts in a zip file on a file server share in each AD site and copying the zip file of the font(s) locally then expanding it.
https://gist.github.com/cosine83/e83c44878a6bdeac0c7c59e3dbfd1f71
nice stript dude. It's funny I just showed this to a designer and it blew his mind as the fonts just get installed one by one! I love coding!
Thanks for the script.
I have a bit of an issue, the script seems to work fine on some devices while other with trigger the install and request an admin account to proceed. did you encounter a similar behaviour ? I have Windows 2016 LTSB and 2019 LTSC the newer version seems to process the script without issues.