Wie kann ich einen Font mit Powershell deinstallieren bzw. den entsprechenden Registry-Eintrag löschen ?
Hallo in die Runde!
Es gibt schon sehr viele Anleitungen und Informationen zum Installieren von Fonts mit Powershell.
Das nutze ich auch schon eine ganze Weile zum automatischen Verteilen von Fonts.
Was mir jedoch Kopfzerbrechen bereitet, ist die scriptgesteuerte Deinstallation (die meisten Fonts sind ja lizenzpflichtig und müssen auch wieder deinstalliert werden, wenn die Lizenz abgelaufen ist).
Das Installieren über den Namespace (0x14) schreibt automatisch die notwendigen Werte in die Registry, was natürlich sehr angenehm ist.
Beispiel Powershell Fonts installieren und existierende überschreiben
Das Deinstallieren funktioniert aber nicht so einfach, da der Registry-Pfad für die Fonts nur Namen und Werte enthält, keine Unterschlüssel pro Font.
Wenn man den Registry-Pfad nach dem Fontnamen durchsuchen kann, ist es auch noch relativ einfach
Es lässt sich aber der Name eines Fonts nicht direkt aus der Installations-Datei auslesen
Beispiele:
die Font-Datei upcil.ttf erzeugt einen Font mit Namen IrisUPC (TrueType)
die Font-Dateigeorgiaz.ttf erzeugt einen Font mit Namen Georgia Bold Italic (TrueType)
die Font-Datei framdit.ttf erzeugt einen Font mit Namen Franklin Gothic Medium Italic (TrueType)
Es will mir einfach nicht gelingen, mit get-ChildItemProperty ..... aus dem Wert (Name der Fontdatei, der in einer Variable steht) den Namen des Fonts zu ermitteln, um den Registry-Eintrag zu löschen.
Get-ItemChildPropertyValue kann ich nicht verwenden, da es noch flächendeckend an Powershell 6.0 fehlt.
Mit der Hoffnung, dass ein Wissender auch schon vor diesem Problem stand und es lösen konnte........
GlintofGold
Es gibt schon sehr viele Anleitungen und Informationen zum Installieren von Fonts mit Powershell.
Das nutze ich auch schon eine ganze Weile zum automatischen Verteilen von Fonts.
Was mir jedoch Kopfzerbrechen bereitet, ist die scriptgesteuerte Deinstallation (die meisten Fonts sind ja lizenzpflichtig und müssen auch wieder deinstalliert werden, wenn die Lizenz abgelaufen ist).
Das Installieren über den Namespace (0x14) schreibt automatisch die notwendigen Werte in die Registry, was natürlich sehr angenehm ist.
Beispiel Powershell Fonts installieren und existierende überschreiben
Das Deinstallieren funktioniert aber nicht so einfach, da der Registry-Pfad für die Fonts nur Namen und Werte enthält, keine Unterschlüssel pro Font.
Wenn man den Registry-Pfad nach dem Fontnamen durchsuchen kann, ist es auch noch relativ einfach
Es lässt sich aber der Name eines Fonts nicht direkt aus der Installations-Datei auslesen
Beispiele:
die Font-Datei upcil.ttf erzeugt einen Font mit Namen IrisUPC (TrueType)
die Font-Dateigeorgiaz.ttf erzeugt einen Font mit Namen Georgia Bold Italic (TrueType)
die Font-Datei framdit.ttf erzeugt einen Font mit Namen Franklin Gothic Medium Italic (TrueType)
Es will mir einfach nicht gelingen, mit get-ChildItemProperty ..... aus dem Wert (Name der Fontdatei, der in einer Variable steht) den Namen des Fonts zu ermitteln, um den Registry-Eintrag zu löschen.
Get-ItemChildPropertyValue kann ich nicht verwenden, da es noch flächendeckend an Powershell 6.0 fehlt.
Mit der Hoffnung, dass ein Wissender auch schon vor diesem Problem stand und es lösen konnte........
GlintofGold
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 398675
Url: https://administrator.de/contentid/398675
Ausgedruckt am: 24.11.2024 um 02:11 Uhr
5 Kommentare
Neuester Kommentar
Dafür gibts ne extra WIn32-Funktion mit der man das richtig macht bevor man einen Font aus der Registry entfernt:
https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/nf-wingdi-re ...
Gruß A
https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/nf-wingdi-re ...
Gruß A
Servus @GlintofGold ,
ich nutze dazu meine Funktion:
(Deinstalliert installierte Fonts automatisch für den aktuellen User oder das ganze System und benachrichtigt laufende Anwendungen über die Änderung so dass diese Ihre Font-Liste aktualisieren können. Bitte beachten: Nach dem Nutzen der Funktion sollte die Powershell-Session unbedingt geschlossen werden da ansonsten bei erneutem Aufruf der Funktion die Liste der installierten Fonts nicht mehr aktuell ist und noch die bereits installierten Fonts enthält. Die Session aktualisiert diese leider nicht, auch wenn man das Objekt nur initialisiert)
Als Name des Fonts ist der anzugeben der intern im Font verwendet wird. Mit der weiter unten stehender Funktion erhältst du den passenden Namen.
Liefert dir als Ergebnis den intern verwendeten Namen des Fonts.
Viel Spaß
Grüße Uwe
ich nutze dazu meine Funktion:
(Deinstalliert installierte Fonts automatisch für den aktuellen User oder das ganze System und benachrichtigt laufende Anwendungen über die Änderung so dass diese Ihre Font-Liste aktualisieren können. Bitte beachten: Nach dem Nutzen der Funktion sollte die Powershell-Session unbedingt geschlossen werden da ansonsten bei erneutem Aufruf der Funktion die Liste der installierten Fonts nicht mehr aktuell ist und noch die bereits installierten Fonts enthält. Die Session aktualisiert diese leider nicht, auch wenn man das Objekt nur initialisiert)
<#
.Synopsis
Uninstalls Fonts
.DESCRIPTION
Uninstalls System- and User-Fonts from the current system
.EXAMPLE
Remove single font
-> Uninstall-Font -Fontname "Font1"
.EXAMPLE
Remove multiple fonts
-> Uninstall-Font -Fontname "Font1","Font2"
or with pipeline support
-> "Font1","Font2" | Uninstall-Font
.INPUTS
[string] or [string[]] for the font names when using pipeline
.OUTPUTS
None
#>
function Uninstall-Font {
[CmdletBinding()]
param(
[parameter(mandatory=$true,ValueFromPipeline=$true)][ValidateNotNullOrEmpty()][string[]]$fontname
)
Begin {
# Add functions and assemblies
if (!("gdi.font" -as [type])){
Add-Type -AssemblyName System.Drawing
Add-Type -MemberDefinition '
[DllImport("user32.dll")] public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, String lParam);
[DllImport("gdi32.dll")] public static extern int RemoveFontResource(string lpszFilename);
' -Namespace gdi -Name font -EA Stop
}
# Get installed font collection
$installedfonts = (New-Object System.Drawing.Text.InstalledFontCollection).Families
$myWindowsID = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
$UserisAdmin = $myWindowsPrincipal.IsInRole($adminRole)
$keyuser = get-item 'HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Fonts' -EA SilentlyContinue
$keymachine = get-item 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Fonts' -EA SilentlyContinue
}
Process{
foreach ($font in $fontname){
if ($font -notin $installedfonts.Name){
write-Error "Font '$font' is not installed." -Category InvalidArgument
continue
}
if ($keyuser){
$keyuser.Property | ?{$_ -like "$font*"} | %{
$file = $keyuser.GetValue($_)
# remove open font resources
write-verbose "Removing open resources for Font '$_'"
[gdi.font]::RemoveFontResource($file) | out-null
# remove registry value
write-verbose "Removing font registry entry with name '$_'."
Remove-ItemProperty $keyuser.PSPath -Name $_
# Remove font file
write-verbose "Removing font file '$file'."
remove-item $file -Force
}
}
if ($keymachine){
$keymachine.Property | ?{$_ -like "$font*"} | %{
if (!$UserisAdmin){
write-error "Function needs to run elevated to uninstall the font '$_' from the system!" -Category PermissionDenied
continue
}
$file = $keymachine.GetValue($_)
# remove open font resources
write-verbose "Removing open resources for Font '$_'."
[gdi.font]::RemoveFontResource($file) | out-null
# remove registry value
write-verbose "Removing font registry entry with name '$_'."
Remove-ItemProperty $keymachine.PSPath -Name $_
# Remove font file
write-verbose "Removing font file '$file'."
remove-item "$([System.Environment]::GetFolderPath(20))\$file" -Force
}
}
}
}
End {
# inform all top level windows of font-change
write-verbose "Notify all top level windows of font-change with broadcast message."
[gdi.font]::SendMessage(0xffff,0x001D,[IntPtr]::Zero,[IntPtr]::Zero) | out-null
}
}
Uninstall-Font -FontName "Name des Fonts" -Verbose
Als Name des Fonts ist der anzugeben der intern im Font verwendet wird. Mit der weiter unten stehender Funktion erhältst du den passenden Namen.
Es lässt sich aber der Name eines Fonts nicht direkt aus der Installations-Datei auslesen
Auch das gehtfunction Get-FontNameFromFile([string]$file){
Add-Type -A System.Drawing
$fc = New-Object System.Drawing.Text.PrivateFontCollection
$fc.AddFontFile($file)
return $fc.Families.Name
}
Viel Spaß
Grüße Uwe
Wenns das dann war, den Beitrag bitte noch auf gelöst setzen, und Lösungen markieren. Merci.