这是一个经常被问到的问题,但是标准解决方案对我来说似乎不起作用。
我有一台 Windows Server 2012-R2 AD,其中大部分是 Windows 7 客户端。我有一个 GPO,它执行以下操作:
计算机配置\首选项\Windows 设置\文件:
Action: Update
Source: <Network drive domain computers have read access to>\fonts\*
Destination: %WindowsDir%\Fonts
然后我还单独更新每个字体的注册表:
Action: Update
Hive: HKLM
Value name: <fontname> <(TrueType)|(OpenType)>
Value type: REG_SZ
Value data: <font file name>
当我这样做时gpupdate
,注册表更改会被部署,但字体永远不会到达字体文件夹。这不是访问问题,因为当我将目标更改为我的桌面时,所有字体都会出现。我也可以从那里手动安装它们。
我试过:
- 将操作更改为 CREATE 或 REPLACE
- 使用完整路径作为目标,而不是 %WindowsDir%
- 使用源的完整路径(因此没有通配符)
- 重新启动目标机器
它们永远不会被复制到字体文件夹。有没有办法在不创建 MSI 的情况下做到这一点?
答案1
有很多方法可以解决这个问题。我个人认为字体文件的“安装”动词/操作是最可靠的。这可以在 Powershell 或 VBS 中使用 SYSTEM 计划任务轻松完成。
我使用这个的变体来处理文件夹中的所有字体。
$path = "\\font-server\Fonts"
$shell = New-Object -ComObject Shell.Application
$shell.Namespace($path).Items().InvokeVerbEx("Install")
答案2
@Tim-Brigham 的想法是正确的,但是它稍微复杂一些。
首先,创建计算机拥有的网络共享域读访问。由于您将从此共享中调用具有系统权限的脚本,因此他们只能读取,这一点很重要。
在此网络共享上,还创建一个文件夹,其中安装了您喜欢的所有字体。
然后在网络文件夹上创建此脚本:
$path = "<path to font folder on network share>"
$shell = New-Object -ComObject Shell.Application
$fonts = $shell.Namespace($path).Items()
# check if font already exists in windows font folder, if not, install
foreach($font in $fonts)
{
$sourcepath = $font.path
$filename = Split-Path -Leaf $sourcepath
$destinationpath = 'C:\Windows\fonts\' + $filename
if (![System.IO.File]::Exists($destinationpath))
{
$font.InvokeVerbEx("Install")
}
}
接下来,根据 GPO 创建一个计划任务:
Computer Configuration -> Preferences -> Control Panel Settings -> Scheduled Task
Action: Update
Use the following User Account: S-1-5-18
Run with highest privileges
Triggers: At logon
Actions: Start a program: powershell.exe -NonInteractive -WindowStyle Hidden -ExecutionPolicy bypass -File <scriptpath>
这里使用用户帐户 S-1-5-18 很重要,这是 NT-Authority/SYSTEM,但如果您使用文字 NT-Authority/SYSTEM,则用户映射将不起作用。
用户需要注销/登录两次。一次用于安装字体,但字体缓存直到登录后才会刷新。