NetworkTimeProtocol(NTP)提供了准确时间,但因种种原因,我们的企业服务器、核心交换机、或者客户终端没能与之同步或者因时间源问题同步了错误的数据,可想而知造成一系列的后果。当然,因NTP服务是典型的CS架构,本着高效简洁,我们可以在核心交换机里配置两个或更多个的时间源,我们可以在企业内部构建NTP服务......那么,终端层面上所有的问题都解决了么?显然不是。
公司某台终端域用户打电话,无法登录进域了,后发现因其电脑时间是"2009/10/1514:00:06"之类;
因公司某终端系统时间错误,其某老版本的企业版卡巴杀毒变红色失效了......
该死,公司的指纹打卡系统的时间不对了,大家怨声载道.....
因系统时间不正确,我们电脑上一些软件也工作不正常了.....
那么,对应的,及时地通过网络给客户端校时,给企业内部NTP源校时似乎就OK了。
可是:一些只是工作组环境的中小企业呢?没有外网只有局域网环境的企业呢?为此,一个好友电话来电问到局域网终端校时的种种可能性及解决方法:
1.若公司有活动目录,通过其组策略部署如下脚本下去,实现终端与domain进行时间同步(弊端是客户端误差若超过5分钟会返回失败,相关链接:http://gnaw0725.blog.51cto.com/156601/660268):
net time \\domain /set /y
2.通过网维通道、GPO(比如作为开机策略)及CS架构的应用等等里边推送网络校时,应朋友要求,结合网上一些开源的资源,经过加工修改整理如下,希望他能用得上。
A:使用时间源:time.windows.com(大家都懂这个源的,缺点是偶尔速度有点慢)进行的时间同步:
#cs Au3 版本: v3.3.9.21 (Beta) 脚本作者:boyhong 技术介绍: http://boyhong.blog.51cto.com 脚本功能: 网络校时 #ce #Include <Date.au3> ;若用于策略静默推送,请自行去掉msgbox If _Hdate() Then MsgBox(0,_Now(),"时间已同步",3) Else MsgBox(16,"错误","同步失败",30) EndIf Func _Hdate() Local $oHTTP,$H_time,$str,$Date Local $mon[13]=[12,"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"] $oHTTP = ObjCreate("microsoft.xmlhttp") $oHTTP.Open("get","http://time.windows.com/",false) $oHTTP.setRequestHeader("ver", "1.2") $oHTTP.Send() $str = StringTrimLeft($oHTTP.getResponseHeader("Date"),4) For $i = 1 To 12 $str = StringReplace($str,$mon[$i],$i) Next $str = StringSplit($str," :") $tNew=_Date_Time_EncodeSystemTime($str[3],$str[2],$str[4],$str[5],$str[6],$str[7]) Return _Date_Time_SetSystemTime(DllStructGetPtr($tNew)) EndFunc
B:使用百度(www.baidu.com)的时间源进行时间同步:
#cs Au3 版本: v3.3.9.21 (Beta) 脚本作者:boyhong 技术介绍: http://boyhong.blog.51cto.com 脚本功能: 网络校时 #ce #Include <Date.au3> ;若用于策略静默推送,请自行去掉msgbox If TimeSync() Then MsgBox(0,_Now(),"时间已同步",3) Else MsgBox(16,"错误","同步失败",30) EndIf Func TimeSync() $http = ObjCreate("microsoft.xmlhttp") $http.Open("Get","http://www.baidu.com/?" & _Now(),False) $http.Send("") $baidutime = $http.GetResponseHeader("Date") $S = StringSplit("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec",",") For $i = 1 To 12 $baidutime = StringReplace($baidutime,$S[$i],$i) Next $S = StringSplit($baidutime,", :") $tNew = _Date_Time_EncodeSystemTime($S[4],$S[3],$S[5],$S[6],$S[7],$S[8]) Return _Date_Time_SetSystemTime(DllStructGetPtr($tNew)) EndFunc
C:使用某台WEB服务器上的时间来进行校时:
#cs Au3 版本: v3.3.9.21 (Beta) 脚本作者:boyhong 技术介绍: http://boyhong.blog.51cto.com 脚本功能: 网络校时 #ce #include <Inet.au3> #Include <Date.au3> $SHIJIAN = _INetGetSource('http://www.timedate.cn/worldclock/ti.asp') If $SHIJIAN <> "" Then Local $DATA = StringRegExp($SHIJIAN, "[nyear|nmonth|nday|nhrs|nmin|nsec]=(.{1,4});", 3) If IsArray($DATA) Then If StringLen($DATA[1]) < 2 Then $DATA[1] = "0" & $DATA[1] If StringLen($DATA[2]) < 2 Then $DATA[2] = "0" & $DATA[2] If StringLen($DATA[4]) < 2 Then $DATA[4] = "0" & $DATA[4] If StringLen($DATA[5]) < 2 Then $DATA[5] = "0" & $DATA[5] If StringLen($DATA[6]) < 2 Then $DATA[6] = "0" & $DATA[6] Dim $D_RIQI = $DATA[0] & "-" & $DATA[1] & "-" & $DATA[2] Dim $D_SHIJ = $DATA[4] & ":" & $DATA[5] & ":" & $DATA[6] If _DateIsValid($D_RIQI & " " & $D_SHIJ) Then RunWait(@ComSpec & " /c date " & $D_RIQI, @ScriptDir, @SW_HIDE) RunWait(@ComSpec & " /c time " & $D_SHIJ, @ScriptDir, @SW_HIDE) EndIf EndIf EndIf
在此,不难看出,若没有外网环境没有活动目录呢?上边的C方案若变通一下让其架构在公司局域网环境呢?答案是可行的。朋友正好有一个PHP环境,在其服务器目录下放置一个页面:test.php,内容如下:
<? echo date ('Y-m-d G:i:s'); ?>
然后在每个终端的部分是:
#cs Au3 版本: v3.3.9.21 (Beta) 脚本作者:boyhong 技术介绍: http://boyhong.blog.51cto.com 脚本功能: 网络校时 #ce #include <Inet.au3> #Include <Date.au3> $lanSHIJIAN = _INetGetSource('http://172.16.128.49/test.php') If $lanSHIJIAN <> "" Then If _DateIsValid($lanSHIJIAN) Then $lanSHIJIAN = StringSplit($lanSHIJIAN, " ", 1) If IsArray($lanSHIJIAN) Then RunWait(@ComSpec & " /c date " & $lanSHIJIAN[1], @ScriptDir, @SW_HIDE) RunWait(@ComSpec & " /c time " & $lanSHIJIAN[2], @ScriptDir, @SW_HIDE) EndIf EndIf EndIf
至此,该问题告一段落,朋友还是坚持问我,那若在活动目录环境下呢,可不可以将这个编译出来的Gpo.EXE通过GPO下发到终端?当然,VBS如此即可:
On error resume next wscript.sleep 8000 Set wshShell = CreateObject("Wscript.Shell") strPath = wshShell.CurrentDirectory wshshell.run "\\172.16.128.9\gpo\Gpo.exe"
最后,不容置否的是,同步校时不光有源的可靠性问题,还有就是精度问题,结合以上脚本适当修改可以在多个源上进行判断选择及对比...在此,省略若干文字,希望能给大家带去些许思路。