客户诉求
客户是一家集团公司,下辖四个报社一个新媒体,还有印刷厂等等分部,除机房服务器、网络产品、安全产品等等需要维护外,还有过千台终端设备的运维工作,终端电脑中,有品牌机,有组装机,有笔记本,有台式机,各种高配低配应有尽有,客户同我司签订了常年外包的服务协议,我方派员两名技术人员常驻现场进行设备的运维工作。
集团信息部门的运维工作量特别大,我司两位同事每天都在维修电脑、装系统、装软件。为了让运维工作能够上一个台阶,能够更有效的服务于集团的各使用人,信息部门决定对集团电脑进行登记工作,登记使用人、电脑配置、所安装的软件。
用户提出诉求后,我们也希望用户的运维工作能够越做越顺利,也希望后期我们同事的工作能够得到比较好的考核,也希望运维人员不用每天都陷入在繁杂并且意义不大的劳动中。
实际的困难
现有运维人员已经被当时的工作拖累,无法再抽出时间来进行这样的登记工作。
电脑配置的登记,是比较复杂的事情,会耽误别人的工作,单位美工、编辑们的工作比起电脑配置登记要重要太多,更何况还有领导的工作更是耽误不得。信息部门突然牵头,在单位内部做这么一件其他部门包括集团领导都不能理解的工作,部门领导可能会被领导约谈。
集团办公地点分布在不同的地方,有些记者经常外出甚至长期驻外,电脑不出状况,网络不出问题,也没人会理会信息部门的登记请求。
没有地利、没有人和,但是不甘心就这么放任运维工作一直被动下去,咱学计算机的高知识人才,不能只会拧螺丝装系统呀!
好在用户一直坚持用的域控环境,所有人员都有自己的账号,多地办公的都有硬件VPN连接到单位内网,出外的记者等人也都是通过VPN拨号到单位内网进行办公。有了这个条件,开动脑筋,这个登记工作就变成了可能。
具体的思路
思路其实很简单,那就是,当客户机连接到域做验证的时候,让客户机自动执行一个程序,完成登记工作,问题就解决了。
前期给用户部署杀毒软件的时候就操作过,客户机登陆域后自动执行程序,这个没啥难度。各位如果有兴趣可以留言,后期再专门撰文介绍。那么只要解决几个问题就可以了:
1、所有机器访问域控的时候,只执行一次程序就可以了,对已经执行过的要有所判断;
2、执行的程序需要能够读取到计算机的硬件配置信息;
3、执行的程序需要能够读取到计算机所安装的软件信息;
4、执行的程序需要能够读取到登录的账号而来判断读取的这些信息来自于哪位同事;
5、执行的程序能够将以上信息直接写入数据库。
只要问题能够具化出来,那么解决方案就出来了,如果只是收集信息不写数据库的话,用一个批处理的脚本差不多就能完成。至于批处理脚本的使用,前期写了一篇类似的文章,那是一篇文件操作类脚本应用的文章,结合本文内容,很容易自行完成,具体内容请关注公众号后查看。通过编程的话,可用的方法就非常多了,介绍一下我的解决经过。
我用的是vs.net做的程序,一个不需要界面的程序就可以了,程序启动起来后完全后台运行,运行完成后程序自动退出。
读取硬件信息,使用调用进程命令,调用系统自带的程序dxdiag.exe,将结果写到系统盘的一个文件中,代码如下:
'执行dxdiag.exe命令,屏蔽执行界面,将结果放到diag.txt文件中
Dim p As Process
p = New Process()
'命令名称
p.StartInfo.FileName = "dxdiag.exe"
'命令参数
p.StartInfo.Arguments = "/t C:\diag.txt"
'让执行的界面不可见
p.StartInfo.UseShellExecute = False
p.StartInfo.CreateNoWindow = True
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
'执行命令
p.Start()
这样还有一个好处就是,如果这台电脑的相应位置已经有了这样的一个文件,那么我们就可以认为这台电脑已经登记过了, 不需要再次登记。代码如下:
'检查是否存在diag.txt文件,如果存在,程序自动退出
If System.IO.File.Exists("C:\diag.txt") Then
Me.Dispose()
Application.Exit()
Else
...
End If
软件信息可以通过读取注册表拿到,代码如下:
'遍历注册表,找到已安装的软件名称,然后显示出来
Dim regaa As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.LocalMachine
Dim raa As Microsoft.Win32.RegistryKey = regaa.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall")
Dim name As String = ""
Dim subkey As Microsoft.Win32.RegistryKey
For Each site As String In raa.GetSubKeyNames()
subkey = raa.OpenSubKey(site)
For Each m As String In subkey.GetValueNames()
If Trim(m).ToLower = "displayname" Then
name = "软件名称:" + subkey.GetValue(m).ToString + " " + name
End If
Next
Next
通过以上代码,已经拿到了想要的信息了,当然dxdiag.exe命令可能还没有执行完,所以需要做一个计时器,每隔30秒检查一下,文件是否生成完成。
文件生成结束后,就是两个工作了,一个就是文件操作,一个就是数据库操作。
文件操作代码如下:
'将DIAG.TXT文件的内容放到字符串里面
Dim DiagStr As String = System.IO.File.ReadAllText("c:\diag.txt", System.Text.Encoding.Default)
'将DIAGSTR字符串里面每一行赋值给数组的一个单元
Dim DiagLine() As String
DiagLine = DiagStr.Split(Chr(10))
'定义循环体计数
Dim i As Integer
'定义三个标记
Dim j, k, l As Integer
'定义硬盘容量字符串
Dim xx As String = ""
Dim Memory, MachineName, OperatingSystem, Language, SystemManufacturer, SystemModel, Processor, DisplayMemory As String
Dim Monitor, VideoCard, OpticalDriver, Disk As String
'开始在每一行找需要的数据
For i = 0 To DiagLine.Length - 1
'定义一个数组,存放每一行“:”前后的数据
Dim DiagSect() As String
DiagSect = DiagLine(i).Split(":")
'根据“:”前的数据做选择,如果值正确,则取值“:”后的值
Select Case Trim(DiagSect(0)).ToLower
'内存容量
Case "memory"
Memory = DiagSect(1)
'计算机名
Case "machine name"
MachineName = DiagSect(1)
'操作系统
Case "operating system"
OperatingSystem = DiagSect(1)
'操作系统语言
Case "language"
Language = DiagSect(1)
'设备厂家
Case "system manufacturer"
SystemManufacturer = DiagSect(1)
'设备型号
Case "system model"
SystemModel = DiagSect(1)
'处理器名称
Case "processor"
Processor = DiagSect(1)
'显存
Case "display memory"
DisplayMemory = DiagSect(1)
'显示器,XP版本
Case "monitor"
Monitor = DiagSect(1)
'显示器,WIN7版本
Case "monitor model"
Monitor = DiagSect(1)
'到了显示设备时,开始做一个标记
Case "display devices" + Chr(13)
j = 0
'到了磁盘和光驱选项时,开始做一个标记
Case "disk & dvd/cd-rom drives" + Chr(13)
k = 0
'到了文件系统是,开始做一个标记
Case "file system"
l = 0
'将所有驱动器的容量相加
Case "total space"
xx = xx + DiagSect(1).Replace(Chr(13), "") + " +"
End Select
'记录离最初的标记的行数
l += 1
j += 1
k += 1
'在标记J开始的10行以内,出现card name,认为是显卡的值
If Trim(DiagSect(0)).ToLower = "card name" Then
If j > 0 And j < 10 Then
VideoCard = DiagSect(1)
End If
End If
'在标记K的50行以内,标记L的3行以上,出现model,认为是光驱的值
If Trim(DiagSect(0)).ToLower = "model" Then
If k > 0 And k < 50 And l > 3 Then
'读到第一条光驱的值后,后面就不再读了
OpticalDriver = DiagSect(1)
k = 50
End If
End If
Next
'循环结束后将硬盘的容量字符串显示出来,最后一个+号去掉
Disk = xx.Remove(xx.LastIndexOf("+"), 1)
数据库操作是通过自定义函数+数据库命令的方式,直接将拿到的信息写入到数据库中,这块涉及到用户的数据结构,就暂不分享出来了,后期可以专门撰文写这块内容。
后记
程序代码的分享,没啥意思,即占篇幅又实为无聊。本文分享最主要是解决问题的思路,希望对大家有所启发。想要实现啥功能的代码,网上搜一下特别多,一遍读不懂多读一遍也就懂了。所以说了解各方面的知识才是最重要的。
了解计算机的应用理论,操作系统基础,网络知识后,码代码才显得有意义。像很多搞笑视频上面展示的,键盘敲得快,屏幕刷的快的是高手;一个程序员百思不得解的问题,一个送外卖的三下五除二搞定了;。。。那些都是娱乐,各位不要当真,真正的高手可能不会编程,就像韩信可能箭法一般一样。
感谢各位的阅读,本公众号会持续分享实际的服务案例,若感兴趣请关注该公众号。
需要上门解决问题时,请及时联系我们!




