调试客户端部署问题 -- 将ccmsetup作为系统服务运行

我在过去一些年中常见的一个客户端部署的问题是将ccmsetup程序用作一个系统服务。绝大多数情况下,我们可以将ccmsetup程序作为系统服务正常使用。然而,也有一些情况中这么做会带来预料不到的结果,随后导致客户端部署的失败。这篇文章介绍了一些这样做带来的后果,同时介绍了这么做如何导致了客户端部署失败。

当ccmsetup运行时,它能运行于两种模式:系统服务模式或者可执行文件模式。在许多情况下,例如客户端推送(client push)安装过程中,ccmsetup默认运行于系统服务模式。当ccmsetup作为系统服务运行时,安装被分为几个不同的阶段。在第一个阶段,ccmsetup将自身拷贝到64位系统的%windir%\ccmsetup目录和32位系统的 %windir%\system32\ccmsetup目录,并且将自己注册为windows的 系统服务。这样做的目的是在客户端部署过程中利用windows系统服务的内置重试机制。如果客户端的安装因为客户机器的重启而失败,ccmsetup会在重启完成后重试。在ccmsetup.log文件中,这个阶段的记录如下:

==========[ ccmsetup started in process 2348 ]========== ccmsetup 3/4/2009 11:16:10 AM
Version: 4.0.6221.1000 ccmsetup 3/4/2009 11:16:10 AM

Downloading c:\myinstalldir\ccmsetup.exe to C:\Windows\ccmsetup\ccmsetup.exe
File download 43% complete (262144 of 602112 bytes). ccmsetup 3/4/2009 11:16:11 AM
File download 87% complete (524288 of 602112 bytes). ccmsetup 3/4/2009 11:16:11 AM
File download 100% complete (602112 of 602112 bytes). ccmsetup 3/4/2009 11:16:11 AM
Download complete. ccmsetup 3/4/2009 11:16:11 AM
Successfully created the ccmsetup service ccmsetup 3/4/2009 11:16:11 AM

从log文件中可见ccmsetup把自身拷贝到windows目录并且创建了对应的windows系统程序。随后ccmsetup退出了当前进程,作为一个windows系统服务重新开始运行。可以从ccmsetup.log中找到对应的线程重起的事实。例如,ccmsetup.log的下一行类似下面的内容:

Download complete. ccmsetup 3/4/2009 11:16:11
Successfully created the ccmsetup service ccmsetup 3/4/2009 11:16:11 AM
==========[ ccmsetup started in process 2608 ]========== ccmsetup 3/4/2009 11:16:11 AM
Version: 4.0.6221.1000 ccmsetup 3/4/2009 11:16:11 AM

需要注意的是,从当前进程改变为系统服务后:ccmsetup重新启动以后以本地系统帐户(local system)运行,而不是最初运行安装程序的帐户。这些信息同样也可以从ccmsetup.log文件中找到,看上去例如:

Running as user "SYSTEM" ccmsetup 3/4/2009 11:16:32 AM

当本地系统帐户对于客户端安装所需数据不具有访问权限时,这就会带来问题。例如,你从网络共享目录运行ccmsetup,这个网络共享目录包含了所有客户安装所需文件。有可能的情况是:你的当前帐户具有对其访问权限,而本地系统帐户却没有。所以当你运行ccmsetup时,第一阶段可以顺利完成,ccmsetup文件被拷贝到本地文件夹,因为这些工作通过当前帐户执行。然而当ccmsetup作为系统服务重新启动时,本地系统帐号则可能因为权限不足无法访问网络共享目录,导致ccmsetup无法下载所需的安装文件。当这个问题发生时,通常可以看到类似的消息出现:

Failed to access source file (…). Waiting for retry...

对于这个问题有几个解决方法,其中最简单的方法是将ccmsetup作为一个独立进程运行,而非系统服务。当ccmsetup作为一个独立进程运行时,整个客户端部署过程都运行于一个账户。所以,如果你的帐户具有对网络共享资源的访问权限,ccmsetup也就会具有对该资源的访问权限。

你可以通过几个不同的命令行选项来明确指定ccmsetup如何运行。如果你加上 /service 选项,ccmsetup则总是作为一个服务运行。相反地,如果你加上 /noservice选项, ccmsetup则总是作为一个独立线程运行。对于已经熟悉SMS 2003的用户来说,/noservice选项和2003中的/useronly选项具有完全相同的功能。我们在Configuration Manager中将/useronly选项重命名为/noservice,这是因为/useronly选项让人感觉客户端安装会通过低权限帐户运行,而事实却从来不是这样。

原文链接:https://blogs.technet.com/configmgrteam/archive/2009/03/13/troubleshooting-client-deployment-issues-running-ccmsetup-as-a-service.aspx

-- Configuration Manager 研发团队 Ben Yim

陈晓铮 译