Im Windows Netzwerk Schriftarten zu verteilen war komplexer als gedacht. Daher möchte ich mal oberflächlich die möglichen Verteilungsmethoden erläutern und meine Empfehlung geben. Die besten Lösung ist ganz unten, Stichwort FontReg.exe. Ziel ist die Verteilung (also Installation zur Verwendung) von Schriftarten in Windows Netzwerken über Gruppenrichtlinien.

Dafür gibt es verschiedene Methoden: Batch, GPO, VBS und FontReg.

Batch (nicht empfohlen)

REM alle Schriftarten aus dem fonts Unterordner in den Fonts Systemordner kopieren
xcopy fonts\*.* "%windir%\Fonts\" /v /c /l /y /i
REM jede Schriftart einzeln in der Registry anmelden
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" /v "OpenSans-Bold (True Type)" /t REG_SZ /d "OpenSans-Bold.ttf" /f
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" /v "OpenSans-BoldItalic (True Type)" /t REG_SZ /d "OpenSans-BoldItalic.ttf" /f
...

Der Registry Befehl muss für jede gewünschte Schriftart ausgeführt werden.

GPO (nicht empfohlen)

Wie schon GPO Meister Heitbrink erklärt hat:
In der Gruppenrichtlinie unter Computerkonfiguration\Einstellungen\Windows-Einstellungen\Dateien folgende Einstellung für jede Schriftart erstellen:
schriftarten-über-das-netzwerk-verteilen-mit-batch-gpo-vbs-register-font-file-gpo
In der Quelle bitte den korrekten \\server\pfad\ angeben. Dadurch werden die Schriften in den Windows Ordner kopiert.

Nun noch in Computerkonfiguration\Einstellungen\Windows-Einstellungen\Registry folgende Einstellungen, ebenfalls einmal pro Schriftart:
schriftarten-über-das-netzwerk-verteilen-mit-batch-gpo-vbs-copy-font-file-gpo
Den Registry Pfad so übernehmen wie auf dem Bild, „Name“ enthält den Anzeigenamen innerhalb von Programmen, bei der Fontdatei kein Pfad mehr davor packen, nur der Dateiname.

Nachteil

Beide Lösungen sind nicht sehr aufwändig, 2 Batch Befehle bzw. 2 GPO Einstellungen, simpel. Viel eher hat es den Nachteil, dass man bei einer größeren Menge an Schriftarten dann doch recht viel zu tun hat. 20 Schriftarten? Das bedeutet viel rumgetippe.
Besser ist in diesem Fall folgende Lösung:

VBS (nicht empfohlen)

Dieses VBS installiert alle Fontdateien, die sich in einem bestimmten Ordner befinden. Der Ordner wird in strFontSourcePath angegeben.

' via http://www.morovia.com/kb/Installing-Fonts-command-script-10008.html
' didnt work as is, some more lines were needed to make it work

Option Explicit
Dim objShell, objFSO, wshShell
Dim strFontSourcePath, objFolder, objFont, objNameSpace, objFile, oWinFonts

Set objShell = CreateObject("Shell.Application")
Set wshShell = CreateObject("WScript.Shell")
Set objFSO = createobject("Scripting.Filesystemobject")

strFontSourcePath = "\\server\Deployment\Sonstiges\fonts\fonts\"

If objFSO.FolderExists(strFontSourcePath) Then

Set objNameSpace = objShell.Namespace(strFontSourcePath)
Set objFolder = objFSO.getFolder(strFontSourcePath)
Const FONTS = &H14&
Set oWinFonts = objShell.Namespace(FONTS)

For Each objFile In objFolder.files
 If LCase(right(objFile,4)) = ".ttf" Then
  If objFSO.FileExists(wshShell.SpecialFolders("Fonts") & "\" & objFile.Name) Then
   
  Else
   Set objFont = objNameSpace.ParseName(objFile.Name)
   oWinFonts.CopyHere objNameSpace.ParseName(objFile.Name)
   objFont.InvokeVerb("Install")
   Set objFont = Nothing
  End If
 End If
Next
Else
 Wscript.Echo "Font Source Path does not exists"
End If

Die Einbindung in das Netzwerk könnte direkt als Startscript erfolgen. Wenn man jedoch einen leichten Überblick haben möchte, welche Computer die Schriften schon installiert haben, empfiehlt sich dieses Script:

@echo on && color 9f && setlocal
set wd=\\server\Deployment\Sonstiges\fonts
set log=%wd%\install-fonts.txt

echo %date% %time:~0,8% - %computername% startet die Fontinstallation >> %log%

cmd /c cscript //nologo "%wd%\install-fonts.vbs"

::REM Test mit zwei beliebigen Schriftarten
if exist "%windir%\fonts\OpenSans-SemiboldItalic.ttf" echo %date% %time:~0,8% - %computername% hat OpenSans installiert >> %log%
if exist "%windir%\fonts\Lato-ThinItalic.ttf" echo %date% %time:~0,8% - %computername% hat Lato installiert >> %log%

:end
endlocal

Das Script loggt Start und Ende der Schriftinstallation und prüft die erfolgreiche Installation mit 1 beliebigen Schriftart. Ein Neustart muss aber auch bei dieser Methode sein.
Aber egal ob dieser Code, diese Kurzfassung oder anderen Varianten, und egal wie man es dreht und wendet – zu 100% zuverlässig sind die Skripte nicht. Auch in meinem Netzwerk wollten ca. 10% der Rechner diese Variante nicht annehmen.

FontReg.exe (empfohlen)

Nach weiterer Recherche fand ich eine Lösung, die SO einfach ist, dass es mich schon fast aufregt, auf dem Weg dorthin etliche Stunden nicht nicht 100% funktionierende Skriptlösungen investiert zu haben. FontReg ist die Lösung, eine Weiterentwicklung des älteren Windows Utilities fontinst.exe.
Das Tool, wenn es ohne weitere Parameter aufgerufen wird, repariert fehlerhafte oder fehlende Schriftartenverknüpfungen und ermöglicht damit einen einfachen Zweizeiler für die Schriftverteilung:

xcopy "\\server\Deployment\Sonstiges\fonts\fonts\*.*" "c:\Windows\Fonts" /y
"\\server\Deployment\Sonstiges\fonts\FontReg.exe"

Awesome! 🙂

Dieser Artikel soll nochmal als eine Kurzfassung meines kürzlich veröffentlichten Reader Deployment Guides, inklusive einer Anleitung für das Update der Verteilung auf Version 11.0.05, die kürzlich veröffentlicht wurde.

Die Schritte bleiben sehr ähnlich:

Schritt 1: Installer laden

Beachtet, dass das Update 11.0.04 als Grundlage braucht. Also holt euch 11.0.0, 11.0.04 und 11.0.05.
you know how…

Schritt 2: AIP lokal erstellen

msiexec /a AcroRead.msi

und einen lokalen Pfad angeben (z.B. „C:\Reader11.0.0mui“)

Schritt 3: Patchen

Erst 11.0.04 integrieren, dann 11.0.05:

X:\Software\Reader\installer>cd 11.0.04.63-mui
X:\Software\Reader\installer\11.0.04.63-mui>msiexec /a "C:\Reader11.0.0mui\AcroRead.msi" /p "AdbeRdrUpd11004_MUI.msp"
X:\Software\Reader\installer\11.0.04.63-mui>cd..
X:\Software\Reader\installer>cd 11.0.05-all
X:\Software\Reader\installer\11.0.05-all>msiexec /a "C:\Reader11.0.0mui\AcroRead.msi" /p "AdbeRdrSecUpd11005.msp"

adobe-reader-11-0-05-update-deployment-install

Schritt 4: Customization Wizard

Mit dem Customization Wizard die .msi bearbeiten und speichern. Wenn dabei ein setup.ini Fehler kommt, einfach eine leere setup.ini im selben Ordner wie die Installation erstellen, der Wizard füllt die dann.
adobe-reader-11-0-05-update-deployment-customization-wizard

Schritt 5: MST Eigenschaften überprüfen

Wie schon im letzten Artikel erwähnt, kann es sein, dass trotz Customization Wizard Anpassung einige Einstellungen der MST nicht ganz stimmen und dadurch z.B. die Sprache nicht korrekt auf Deutsch gestellt wird.
Öffnet also die Installationsdatei .msi und ladet die angepasste .mst Datei mit Orca über Transform -> “Apply Transform” ein.
Überprüft in der Property Tabelle folgende Wertepaare:

Propertyalter Wertneuer Wert
ProductLanguage10331031
ISLANGFLAGENUDEU
ProductCode{AC76BA86-7AD7-FFFF-7B44-AB0000000001}{AC76BA86-7AD7-1031-7B44-AB0000000001}
AgreeToLicenseNoYes
ENABLE_CACHE_FILESYesNo
EULA_ACCEPTNoYes
RebootYesNoYesNo

Schritt 6: Deployment

Nun könnt ihr dieses fertig geschnürte Paket in den deploy/[version] Ordner ablegen und das Verteilungsscript (siehe Deployment Artikel) anpassen, damit die neue Version verteilt wird. Dazu reicht es, die neue Version (muss dem Ordnernamen im deploy Ordner entsprechen) in Zeile 11 einzutragen.

Fertig!
Dieser Prozess, inklusive Tests auf einigen Rechnern, dauerte bei mir weniger als 30 Minuten. Ein Update ist also relativ schnell eingespielt.

Es gibt bestimmte Zeichen, die im Zeichensatz der Schriftart der Windows Konsole nicht vorhanden sind. Beispielsweise das Copyright Zeichen ©.
Auch Umlaute sind so eine Sache, das habe ich aber damals schon in einem Beitrag aufgeklärt.

Nach ersten Recherchen meinerseite kurz gefasst: nur mit Fummelei ist das Copyright Symbol in der deutschen Konsole möglich. Die Darstellung des Symbols inklusive Umlaute ist aber vom System, von der Konsole, der Schriftart der Konsole und anderen Faktoren abhängig. Eine 100% zuverlässige Lösung gibt es nicht. Für gewöhnlich arbeitet man, wenn nötig, mit (C)opyright oder (C)Copyright stattdessen.

Aber ich hätte keinen Blog, wenn ich nicht bis zum Erbrechen recherchieren und testen würde, bis mir eine Lösung gut genug gefällt.

Ich habe mir die Windows Standards angesehen und 1, 2 Stunden rumprobiert.
Das Copyright Zeichen und Umlaute gleichzeitig sind möglich, jedoch nur mit ein wenig Fummelei.

Wer einfach nur schnell wissen will wie es geht kann hier das Video dazu sehen, der letzte Code unten im Artikel ist die finale Version. Alle ITler sollten zum eigenen Verständnis weiterlesen.

Wie funktioniert das alles und warum?

Basteln wir uns eine neue Batch im Notepad++, echo rein, schauen was passiert:

echo ©
pause

Simpel, oder? Funktioniert nicht, was ein Wunder.
copyright-symbol-in-batch-simple-try-2

Codepages (mehr dazu) sagen der CMD, mit welchem Zeichensatz die Batch Ausgaben dargestellt werden sollen. Über einen Trick, in dem das ® Zeichen aus der Codepage 1252 abgespeichert wird, lässt sich das © Zeichen in der deutschen Konsole (850 ist die normale westeuropäische Codepage) darstellen:

chcp 1252
set c=©
chcp 850
echo %c%

copyright-symbol-in-batch-codepage-try-2
copyright-symbol-in-batch-codepage-try-1Erläuterung: Der selbe Hexadezimalcode, der in der Codepage 1252 also hinter ® steht, steht in der Codepage 850 hinter ©, was mit diesem Trick ausgenutzt wird.
Trick via

Das heißt, um jederzeit ein Copyright Symbol darstellen zu lassen genügt es die aktuelle Codepage zu wechseln, in der Codepage 1252 das Copyright Symbol in eine Variable zu speichern und wieder auf die deutsche Codepage zurückzuwechseln.
Dazu bietet sich folgender Code an:

for /f "tokens=2 delims=:." %%x in ('chcp') do set cp=%%x
chcp 1252
set c=©
chcp %cp%
echo %c%

copyright-symbol-in-batch-codepage-try-3

Für die Umlaute müsst ihr nun meinen alten Trick anwenden und hinnehmen, dass im Code das Copyright Symbol durch ein anderes Symbol ersetzt wird. Aber mit

%c%

kann es weiterhin gesetzt werden.
copyright-symbol-in-batch-codepage-final-symbol-und-umlaute

Eine Sache stört mich bei neu installierten Computern oft: die Windows Explorer Verknüpfung in der Taskleiste öffnet die Übersicht der – meiner Ansicht nach – völlig sinnlosen Bibliotheken.
windows-explorer-computer-statt-bibliotheken-ansicht

Ein simples Problem mit einer ebenso einfachen Lösung:
Rechtsklick auf die Explorer Verknüpfung -> Eigenschaften -> an das Ziel folgenden String anhängen:
[text]/e,::{20d04fe0-3aea-1069-a2d8-08002b30309d}[/text]
windows-explorer-computer-statt-bibliotheken-verknüpfung-ziel windows-explorer-computer-statt-bibliotheken-computer

Problem gelöst!

Für die Ansicht einer bestimmten Partition mit dem Explorer nutzt ihr eine Verknüpfung mit mit diesem Ziel:
[text]%windir%\explorer.exe /e, /root, c:[/text]
windows-explorer-computer-statt-bibliotheken-laufwerk-c

Mich persönlich stört es weniger, da ich sowieso den Total Commander anstelle des Windows Explorers nutze. Ein Tipp für alle IT-versierten Nutzer! Etwas Umgewöhnung ist nötig aber das Tool ist pure Power, wenn man es beherrscht.

Das Systemsteuerungselement „Mail (32bit)“ dient der einfachen Konfiguration der E-Mail Konten und Eigeschaften von Outlook. Diese Einstellungoberfläche ist teilweise sogar zwingend erforderlich, da z.B. systemsteuerung-mail-32bit-funktioniert-nicht-großneue E-Mail (Exchange) Konten nicht während des Betriebes von Outlook eingerichtet werden können. Umso ärgerlicher, wenn beim Klick auf das Element nichts passiert oder es in der Übersicht der Systemsteuerung nicht vorhanden ist.

Es gibt ein paar Tipps, die helfen können, das wieder in den Griff zu bekommen:

Den Mail Dialog manuell öffnen:

Sucht im Installationordner von Office, beispielsweise

c:\Program Files (x86)\Microsoft Office\Office12\

, nach der Datei MLCFG32.CPL. Diese müsste existieren und beim Doppelklick das gewünschte Mailkonfigurationsfenster öffnen. Ihr könnt diesen Dialog jederzeit auf diesem Weg öffnen.

Eine neue Verknüpfung erstellen:

Egal, ob das Element „Mail (32bit)“ nicht funktioniert oder gar nicht vorhanden ist, ihr könnt euch einfach selber eine Verknüpfung erstellen, diese macht dann genau das gleiche wie die Verknüpfung in der Systemsteuerung.
Erstellt eine neue Verknüpfung, beispielsweise auf dem Desktop oder in einem Ordner eurer Wahl, und tragt als Ziel die MLCFG32.CPL Datei aus eurem Office Installationsordner ein.
Dann könnt ihr noch in den Eigenschaften der Verknüpfung mit „Anderes Symbol…“ eine passenderes Icon wählen.

systemsteuerung-mail-32bit-funktioniert-nicht-shotcut

Systemsteuerungselement reparieren:

Am wahrscheinlichsten wird eine Office Reparatur das Problem beheben. Geht dazu in die Systemsteuerung zu euren installierten Programmen, Rechtsklick auf euer Office, „Ändern“ und wählt Reparieren.
systemsteuerung-mail-32bit-funktioniert-nicht-outlook-repair
Startet nach der Installation euren Rechner neu.

Sollte das Element immernoch nicht funktionieren, überprüft bitte folgenden Registry Key:

HKEY_LOCAL_MACHINE\SOFTWARE\Clients\Mail\Microsoft Outlook\shell\Properties\command

Dieser sollte auf die CPL Datei in eurem Office Verzeichnis hinweisen, mit ein paar Wörtern davor.
Der Inhalt sollte also in etwa so aussehen:

rundll32.exe shell32.dll,Control_RunDLL "C:\PROGRA~2\MICROS~1\Office12\MLCFG32.CPL"

Ihr könnt die Richtigkeit des Pfades überprüfen, in dem ihr diesen einfach kopiert und in Start -> Ausführen eintragt.
systemsteuerung-mail-32bit-funktioniert-nicht-test-office-path
Dies sollte den gewünschten Dialog öffnen.

Java, ein Grundpfeiler von Windows PCs, der schnell bröckelt und regelmäßig aktualisiert werden muss. Fast immer installiert und leider oftmals nicht auf dem neuesten Stand, wodurch sehr schnell sehr große Sicherheitslücken entstehen können; denn Java wird gerne von Exploits ausgenutzt.

Ein flexible, schnell konfigurierte und scriptbasierte Java Verteilung soll dieses Problem und den damit verbundenen Aufwand auf ein Minimum reduzieren.
Bei dieser wird ein Startscript im AD auf den Zielcomputern, die vom Clientfilter akzeptiert werden, Java sowohl in der 32bit als auch in der 64bit Version installieren.
Die Installation beider Bit-Varianten ist notwendig, da die meisten Browser immernoch ausschließlich als 32bit Fassung existieren. Ein 32bit Browser würde selbst auf einem 64bit System mit installiertem 64bit Java keine existierende Java Installation finden.

Der Aufbau

java-deployment-working-dir-neu
Bei einem neuen Java Update werden die beiden .exe Installer benötigt, diese müssen entsprechend dem Muster im Bild umbenannt werden. Abschließend müssen noch 2 Zeilen im Script angepasst werden. Das ist der komplette „Aufwand“, wenn ein neues Java Update veröffentlicht wird.

Das Script

Stand: 13.3.2015 (Java 8u31), working

@echo on & Color 9f & setlocal
 
set wd=\\lea\Deployment\Software\Flash
set log=%wd%\flash-log.txt
REM --- Version hier ändern ---
set version=16.0.0.305
REM ---------------------------
set tools=\\lea\Deployment\Sonstiges\tools
set flashieEL=999
set flashplEL=999
set combinedEL=999
set versionEL=999
set instversion=000
set retry=0
 
REM Clientfilter: nur die Computer aus der allowedPCs.txt dürfen installieren
::for /f %%f in (%wd%\allowedPCs.txt) do if "%computername%"=="%%f" goto check
::goto end
 
REM Clientfilter: die Computer aus der deniedPCs.txt dürfen nicht installieren
for /f %%f in (%wd%\deniedPCs.txt) do if "%computername%"=="%%f" goto end
 
:check
REM check installed version
for /f "tokens=1,2,3 delims= " %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Macromedia\FlashPlayerPlugin" /v "Version"^|findstr "Version"') do set instversion=%%c
if "%instversion%"=="000" goto install
%tools%\VersionCompare.exe %instversion% %version%
set versionEL=%errorlevel%
if "%versionEL%"=="-1" goto install
if "%versionEL%"=="0" echo %date% %time:~0,8% - %computername% hat bereits %instversion% installiert >> %log% & goto end
if "%versionEL%"=="1" echo %date% %time:~0,8% - %computername% hat bereits %instversion% (neu) installiert >> %log% & goto end
 
:install
echo %date% %time:~0,8% - %computername% (%instversion%) startet die Installation... >> %log%
start /w %wd%\flash-%version%_IE.exe -install
set flashieEL=%errorlevel%
start /w %wd%\flash-%version%_OTHER.exe -install
set flashplEL=%errorlevel%
 
if %flashieEL%==1618 goto retry REM msiexec process in use, installation already in progress
if %flashieEL%==1602 goto retry REM user canceled installation
if %flashieEL%==1603 goto retry REM fatal error, some use it for "already installed" (eg. java)
if %flashplEL%==1618 goto retry REM msiexec process in use, installation already in progress
if %flashplEL%==1602 goto retry REM user canceled installation
if %flashplEL%==1603 goto retry REM fatal error, some use it for "already installed" (eg. java)
if %flashieEL%==1041 echo %date% %time:~0,8% - %computername% strange 1041 open browser fail, end >> %log% & goto end
if %flashplEL%==1041 echo %date% %time:~0,8% - %computername% strange 1041 open browser fail, end >> %log% & goto end
 
set combinedEL=%flashieEL%%flashplEL%
echo %date% %time:~0,8% - %computername% hat die Installation von %version% abgeschlossen, errorlevel: %combinedEL% >> %log%
goto finish
 
:retry
if %retry%==1 goto retryfailed
echo %date% %time:~0,8% - %computername% hat nicht Errorlevel 00 erreicht, retry in 200Sek... >> %log%
set retry=1
ping localhost -n 200 > nul
goto install
 
:retryfailed
echo _!_ %date% %time:~0,8% - %computername% hat die Installation abgebrochen, RETRY FAILED! EL: %flashieEL% %flashplEL% >> %log%
goto end
 
:finish
REM copy flash config file for silent background updates
if "%processor_architecture%"=="x86" xcopy "%wd%\mms.cfg" "%systemroot%\System32\Macromed\Flash" /y & goto end
xcopy "%wd%\mms.cfg" "%systemroot%\SysWOW64\Macromed\Flash" /y
xcopy "%wd%\mms.cfg" "%systemroot%\System32\Macromed\Flash" /y
goto end
 
:end
endlocal
exit

Um einzelne Computer für die Ausführung eines bestimmten Scripts ein- bzw. auszuschließen, verwende ich seit Langem in fast allen produktiven Scripts einen – von mir so benannten – „Clientfilter„. In einem alten Beitrag hatte ich die zugrunde liegende Technik bereits erklärt, möchte das jetzt nochmal ein wenig ausführlicher, in 2 verschiedenen Ausführungen, zeigen.

Das Prinzip müsste klar sein: eine Textdatei enthält einen oder mehrere Computernamen, 1 pro Zeile. Der Clientfilter vergleicht den Computernamen des ausführenden Computers mit jeder Zeile der Textdatei und reagiert entsprechend.

Zwei typische Anwendungen baue ich immer in die Scripte mit ein:

Fall 1: nur bestimmte Computer dürfen ausführen

In einem Unternehmen mit XXX Computern möchte ich ein neues Script vorerst testen. Dazu soll dieses Script erst einmal nur von 1 oder 2 Computern gestartet werden können. Ich konfiguriere also folgenden Clientfilter:

set wd=\\server\working\dir
REM Clientfilter: nur die Computer aus der allowedPCs.txt dürfen installieren
for /f %%f in (%wd%\allowedPCs.txt) do if "%computername%"=="%%f" goto nextstep
goto end

:nextstep
...
:end
...

Das Script prüft also an dieser Stelle, ob der ausführende Computer(name) in der allowedPCs.txt Datei im %wd% Verzeichnis vorhanden ist. Wenn ja, geht es zur Sprungmarke

nextstep

, wenn nicht, zu

end

. Somit erlaube ich das Script nur für einzelne aus einer Gruppe von vielen Rechnern.

Fall 2: nur bestimmte Computer dürfen nicht ausführen

Nun habe ich das Script also getestet und möchte es auf XXX Computer installieren. Dabei möchte ich aber einzelne Rechner ausschließen. Hierfür ist folgender Clientfilter gedacht:

set wd=\\server\working\dir
REM Clientfilter: die Computer aus der deniedPCs.txt dürfen nicht installieren
for /f %%f in (%wd%\deniedPCs.txt) do if "%computername%"=="%%f" goto end
goto nextstep

:nextstep
...
:end
...

Das Script wird also von allen Computern ausgeführt, deren Name nicht in der deniedPCs.txt steht. Ist die deniedPCs.txt leer, so wird das Script von allen Computern ausgeführt.

Beides baue ich in meine Scripte ein und kommentiere den gerade nicht benötigten Bereich aus.
clientfilter-script-execution-check-standard

clientfilter-script-execution-check-standard-filesSomit ist es für meine Verteilungen also normal, wenn neben dem Script auch immer diese beiden Textdateien allowedPCs.txt und deniedPCs.txt im Verzeichnis enthalten sind. In der allowedPCs.txt stehen meisten die Testrechner, die deniedPCs.txt ist meistens leer.