Quản lý các mạng Windows dùng Script
Mitch Tulloch
Phần 1: Những khái niệm cơ bản
Đây là phần đầu tiên trong loạt bài về các mạng Windows scripting. Phần này đề cập đến
những khái niệm cơ bản nhất về kỹ thuật scripting (kỹ thuật viết kịch bản) trong các mạng
chạy hệ điều hành Windows. Những phần còn lại của loạt bài sẽ chuyển đến các bạn nội
dung chi tiết của nhiều khía cạnh khác nhau trong chủ đề này.
Có một câu nói như thế này, không rõ của vĩ nhân hay thường dân nào nhưng tôi thấy quả rất chí
lý: “Đưa cho một anh chàng sắp chết đói một con cá, bạn nuôi được anh ta một ngày; nhưng nếu
dạy cho anh ta cách câu cá, bạn nuôi anh ta cả đời”.
Còn gì đúng hơn thế, và càng đúng hơn trong thế giới bận rộn của các chuyên gia công nghệ thông
tin (mà chúng ta vẫn quen miệng gọi là dân IT) khi làm việc với kỹ thuật scripting: “Đưa cho một
admin một script, bạn giúp anh ta giải quyết một vấn đề; nhưng nếu dạy anh ta cách viết script
như thế nào, bạn giúp anh ta làm được công việc gắn liền với cả đời anh ta”.
Giá mà tự động hoá được công việc quản trị hàng ngày bằng các script, cuộc sống của những
admin sẽ thoải mái và nhẹ nhàng hơn nhiều. Tại sao cần phải biết và dùng script? Không phải đã
có hàng trăm script được viết sẵn trôi nổi trên thế giới mạng mà bạn có thể tải về dùng một cách
dễ dàng, như lấy từ nguồn trung tâm Script Center Script Repository của Microsoft chẳng hạn.
Vậy tại sao? Hàng trăm kịch bản (script) viết sẵn, xin thưa rằng đúng. Tải về dùng dễ dàng, xin
thưa rằng lại càng đúng. Ấy vậy mà đúng nhưng chưa đủ. Chúng hữu ích và giúp đỡ bạn rất nhiều,
nhưng nhiều khi đòi hỏi riêng theo cấu hình cụ thể trong môi trường của bạn lại làm khó chúng.
Có khi trong hàng trăm hàng nghìn script tải về bạn chỉ chọn lọc được một script phù hợp mà vẫn
phải điều chỉnh đôi chút. Đơn giản vì tác giả viết ra nó không nằm trong tổ chức của bạn, không
thực hiện theo cấu hình của bạn và mối quan tâm của họ lại hướng đến một cái gì khác cơ. Khi đó
các admin phải trở thành những ông thợ sửa chữa lành nghề, thay đổi chỗ này một chút, thay đổi
chỗ kia một tý, ghép ghép nối nối để biến vài scrip nhỏ lẻ thành một script hợp nhất lớn hơn hay
dùng dữ liệu đầu ra của script này làm thành dữ liệu đầu vào cho script khác, hay biến nó thành
công cụ hoạt động cho một máy từ xa… Quả là rất nhiều việc!
Anh thợ máy muốn sửa chữa được máy móc thì phải hiểu cấu trúc của nó, đó là điều không ai
phản bác. Bởi vậy mà anh “thợ” admin muốn biến đổi, điều chỉnh script thì phải hiểu về nó, phải
biết cách xây dựng và viết ra nó, biến những cái mới hay cái có sẵn thành cái của riêng mình, phù
đây là Netsh. Song, khi sử dụng lệnh này bạn cần cẩn trọng vì nó có nhiều ngữ cảnh, lệnh và tham
số khác nhau rất khó nhớ. Thực hiện sai một thao tác cũng có thể dẫn đến hậu quả nghiêm trọng.
Nếu chưa thực sự chắc chắn, hãy nhờ sự giúp đỡ của phần trợ giúp Help hoặc quay trở lại cách thứ
nhất.
Nhưng mục đích của chúng ta ở đây là học về script. Do đó, chúng ta sẽ xem xét cách thay đổi địa
chỉ IP của máy dùng VBScript và WMI như thế nào mà trước hết là phải biết đến một số khái
niệm cơ bản như đối tượng (object), phương thức (method), thuộc tính (property), namespace…
Để bắt đầu, hãy chạy script trên một máy cục bộ:
strComputer = "."
Ở đây, tiền tố str- được đặt đầu đối tượng là để chỉ strComputer là một biến có chứa xâu, còn dấu
chấm là ký hiệu tham chiếu tới máy cục bộ và được dùng như một điểm bắt đầu của namespace
WMI. Vậy không gian tên WMI là gì? Thực ra, đó là một tập hợp phân cấp các lớp đối tượng khác
nhau, có thể được dùng để quản lý nhiều mặt khác nhau của máy tính Windows. Ví dụ, có một
namespace gốc và bên dưới nó là hàng tá namespace con khác như SECURITY, CIMV2,
perfmon… Hầu hết các lớp WMI hữu ích nằm trong không gian tên root\cimv2 và trước khi làm
việc với bất kỳ lớp nào trong số đó, chúng ta cần diễn giải chúng thành các đối tượng. Sau đó là
xem xét thuộc tính của các đối tượng này và gọi phương thức để thao tác chúng.
Lớp, đối tượng, thuộc tính, phương thức - chúng là những gì? Dưới đây là một phân tích đơn giản
có thể giúp bạn hiểu về chúng: xem xét lớp MicrowaveOven, tức tập hợp trừu tượng của tất cả các
lò vi sóng (không có một lò thực nào được đưa vào trong đó cả). Lớp này có thể có các thuộc tính:
màu sắc (Color), kích thước theo khối lập phương (CubicInches), mặt quay tròn (HasTurntable)…
Có lẽ bạn hiểu thuộc tính chính là các đặc điểm, tính chất đặc trưng cho một lớp. Nói cách khác,
các lò vi sóng này sẽ có một màu nào đó, có một kích thước bên trong nào đó và chúng có thể
quay tròn hoặc không.
Lớp MicrowaveOven cũng có các phương thức. Phương thức, tức là một hàm tính toán hoặc được
định nghĩa theo một quy luật nhất định để lớp có thể thao tác hoặc bạn có thể thao tác với lớp. Với
lớp cụ thể này, một số phương thức có thể dùng là SetCookingTime (thiết lập thời gian nấu),
SetPowerLevel (thiết lập mức điện sử dụng), Reset (nấu lại)… Thông thường, để gọi một phương
thức bạn phải đưa tham số vào cho nó. Ví dụ, để gọi phương thức SetCookingTime (thiết lập thời
gian nấu), chúng ta có thể định nghĩa biến CookingTime (thời gian nấu) trong một số giây nhất
Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
Dòng lệnh này chạy như thế nào? Đầu tiên, bạn có thể thấy đối tượng có tên objWMIService mà
chúng ta vừa mô tả một phút trước ở dòng bên trên. Sau đối tượng này là ExecQuery, có thể là
thuộc tính mà cũng có thể là phương thức (cấu trúc của lệnh luôn luôn là doituong.thuoctinh hoặc
doituong.phuongthuc). Chúng ta có thể dễ dàng đoán ra đó là một phương thức vì đằng sau nó là
một câu truy vấn. Phương thức ExecQuery được gọi bằng cách thêm một tham số vào nó. Tham
số ở đây là một lệnh SQL (SELECT), trả ra tập hợp (được đánh dấu bởi tiền tố “col-”) của tất cả
(dấu hoa thị) cấu hình bộ điều hợp mạng trên máy có đường bao TCP/IP và được cho phép trên bộ
điều hợp. Tập hợp trả về sau khi thực hiện phương thức này sẽ được gán với biến colNetAdapters.
Chúng ta có thể làm gì với tập hợp này? Khi có một tập hợp trong tay, bạn phải lặp vòng nó, dùng
một lệnh lặp như For Each. Vòng lặp tiếp theo sẽ như thế này:
For Each objNetAdapter in colNetAdapters
' do something to each network adapter's configuration
Next
Bạn luôn phải lặp vòng các tập hợp cho dù tập hợp đó chỉ có một đối tượng.
Bây giờ, điều chúng ta thực sự muốn là thay đổi địa chỉ IP cho adapter của mình. Vì thế, hãy định
nghĩa thêm một số biến:
arrIPAddress = Array("172.16.11.99")
arrSubnetMask = Array("255.255.255.0")
Chú ý là các biến định nghĩa địa chỉ IP và subnet mask mới phải là các biến mảng. Tại sao lại như
thế? Lý do đầu tiên là các máy tính Windows nhiều khi không phải chỉ có một địa chỉ IP, một cổng
vào mặc định… Vậy thì tại sao không dùng biến mảng cho tất cả các thiết lập IP được nhất quán.
Và lý do thứ hai, nếu tìm kiếm lớp Win32_NetworkAdapterConfiguration trong WMI Reference
trên MSDN, bạn sẽ thấy được phải dùng đến biến mảng. Chúng ta sẽ nghiên cứu sâu hơn về WMI
Reference trong tương lai, còn bây giờ thì tạm thời chấp nhận ở mức độ chưa rõ ràng một chút.
Cuối cùng, cần gọi phương thức EnableStatic của lớp Win32_NetworkAdapterConfiguration để
thay đổi địa chỉ IP và cổng vào mặc định của bộ điều hợp mạng sang thiết lập mới chúng ta đã
định nghĩa trong các biến mảng. Thực hiện như sau:
errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)
Ở đây, biến err- là cần thiết, giống như một nơi lưu trữ đoạn mã lỗi trả về khi phương thức chạy.
Windows IP Configuration
Ethernet adapter Local Area Connection:
Connection-specific DNS Suffix . :
IP Address. . . . . . . . . . . . : 172.16.11.99
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 172.16.11.1
Vâng, nó đã làm việc! Địa chỉ IP của máy đã được thay đổi thành công từ .45 thành .99 như hiển
thị trên lệnh Ipconfig thứ hai.
Phần 2: Hoàn chỉnh script
Ở phần trước chúng ta đã biết đến một số khái niệm cơ bản về kỹ thuật scripting như đối tượng
(object), phương thức (method), thuộc tính (property) và viết ra một scritp đơn giản thay đổi địa
chỉ IP gán cho bộ điều hợp mạng. Sau đó, chúng ta đã sử dụng bốn script đầu tiên, được gọi là
ChangeIPAddress.vbs:
strComputer = "."
arrIPAddress = Array("172.16.11.99")
arrSubnetMask = Array("255.255.255.0")
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colNetAdapters = objWMIService.ExecQuery("Select * from
Win32_NetworkAdapterConfiguration")
For Each objNetAdapter in colNetAdapters
errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress,
arrSubnetMask)
Next
Khi chạy script này trên server Windows, nó thay đổi thành công địa chỉ IP của máy từ .45 sang .
99. (Kiểm tra bằng lệnh ipconfig trước và sau khi chạy script). Kết quả hoàn toàn tốt.
Nhưng script chúng ta đã xây dựng mới từng lại ở mức khá đơn giản. Còn thiếu nhiều yếu tố quan
trọng khác như các định nghĩa biến, điều khiển lỗi, dùng dữ liệu đầu vào và xác nhận dữ liệu đầu
ra cần phải bổ sung vào để có được một script tương đối hoàn chỉnh. Chúng ta sẽ thực hiện điều
đó trong phần hai này.
Các định nghĩa biến
Dim colNetAdapters
Dim errEnableStatic
strComputer = "."
arrIPAddress = Array("172.16.11.93")
arrSubnetMask = Array("255.255.255.0")
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colNetAdapters = objWMIService.ExecQuery("Select * from
Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
For Each objNetAdapter in colNetAdapters
errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress,
arrSubnetMask)
Next
Chú ý là khi dùng Option Explicit (tuỳ chọn khai báo tường minh), bạn phải khai báo tất cả biến
trong script của mình, gồm cả đối tượng, xâu, mảng, tập hợp, biến cho đoạn mã lỗi… Nghe có vẻ
rất rắc rối phức tạp nhưng thực tế chỉ cần chạy một số trang dài, ngay cả khi chạy chương trình gỡ
lỗi rungning time, bạn sẽ biết nó hữu ích như thế nào. Cũng chú ý là không cần khai báo biến theo
trình tự, chỉ cần nhớ khai báo cho từng biến trước khi dùng là được. Thông thường người ta đặt tất
cả khai báo biến vào một phần riêng trên đầu script như chúng ta đã làm ở trên.
Điều khiển lỗi
Bây giờ, chúng ta đã loại bỏ được các lỗi gõ nhầm khi chạy script đã được soát lại, script hoạt
động. Nhưng nếu nó không hoạt động thì sao? Ví dụ, chuyện gì sẽ xảy ra nếu chúng ta thay đổi
script đi một chút để chạy trên một máy từ xa thay vì máy cục bộ mà trong đó máy từ xa không
nằm trên mạng? Một lần nữa lỗi thời gian chạy (tức lỗi xảy ra khi script đang được thực thi, ngược
lại với lỗi cú pháp mà VBScript có thể nhận ra khi biên dịch script trước khi chạy nó) sẽ xuất hiện
và script sẽ bị ngừng lại, hiển thị một thông báo lỗi tương tự như thông báo chúng ta đã thấy ở
trên. Chuyện gì sẽ xảy ra nếu chúng ta viết ra một script để thực hiện một số thao tác? Trong
trường hợp này tất nhiên chúng ta không muốn có một lỗi thời gian chạy khiến script phải dừng lại
giữa chừng mà ít nhất script cũng phải thực hiện tất cả các thao tác khác đã được xây dựng. Một ví
dụ điển hình là script giám sát các thiết lập trên một số máy tính mà không thay đổi các thiết lập
đó. Trong trường hợp này bạn sẽ cần xây dựng script chạy liên tục cho dù một hay một số máy bị
Wscript.Echo "Usage: ChangeIPAddress.vbs new_IP_address"
WScript.Quit
End If
strComputer = "."
strAddress = Wscript.Arguments.Item(0)
arrIPAddress = Array(strAddress)
arrSubnetMask = Array("255.255.255.0")
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colNetAdapters = objWMIService.ExecQuery("Select * from
Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
For Each objNetAdapter in colNetAdapters
errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress,
arrSubnetMask)
Next
Chúng ta hãy phân tích từng phần một. Đầu tiên là khai báo một biến mới:
Dim strAddress
Đây là một biến xâu (string) sẽ chứa tham số (địa chỉ IP) chúng ta mô tả khi chạy script. Tiếp theo
là thêm các dòng bên dưới vào sau phần khai báo:
If WScript.Arguments.Count = 0 Then
Wscript.Echo "Usage: ChangeIPAddress.vbs new_IP_address"
WScript.Quit
End If
Các dòng này thực hiện điều gì? Thuộc tính Arguments của đối tượng WScript trả về tập hợp các
tham số được mô tả khi chạy script. Phương thức Count trả ra số lượng tham số chúng ta nhập vào
và mục đích của phần đoạn mã này là kiểm tra xem liệu chúng ta có quên nhập bất kỳ tham số (số
tham số bằng 0) nào không. Nếu có, nó sẽ báo hiệu (hoặc hiển thị) một thông báo nói cho bạn biết
cách sử dụng script phù hợp như thế nào và chương trình chạy của script bị ngừng lại hoàn toàn.
Cuối cùng, dòng cũ:
arrIPAddress = Array("172.16.11.93")
nơi chúng ta viết mã cho địa chỉ IP mới theo kiểu gán mảng bây giờ đã được thay thế bằng hai
Chương trình chạy khá tuyệt!
Kiểm chứng đầu ra
Nếu bạn thấy chán khi phải gõ mãi lệnh ipconfig sau khi chạy script để kiểm tra kết quả, còn một
cách khác giúp bạn: sử dụng các dòng như bên dưới:
For Each objNetAdapter in colNetAdapters
errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress,
arrSubnetMask)
Next
Mục đích của đoạn mã này là thay đổi địa chỉ IP được gán cho bộ điều hợp mạng, dùng phương
thức objNetAdapter.EnableStatic. Nhưng bạn nên chú ý là cần phải có một biến err- (ở đây là
errEnableStatic) dùng làm nơi lưu trữ đoạn mã lỗi trả về khi chạy phương thức. Danh sách mã lỗi
có thể được trả về từ phương thức EnableStatic của lớp Win32_NetworkAdapterConfiguration bạn
có thể tham khảo trên MSDN. Và từ danh sách này chúng ta có thể thấy kết quả trả về bằng 0
nghĩa là thao tác script thực hiện đã thành công (ví dụ như địa chỉ IP của bộ điều hợp đã được thay
đổi thành công). Cách đơn giản nhất để kiểm tra là thêm dòng bên dưới vào cuối script:
Wscript.Echo errEnableStatic
Chạy script lại một lần nữa:
C:\Documents and Settings\Administrator.DC-1\Desktop>ChangeIPAddress.vbs
172.16.11.237
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
0
C:\Documents and Settings\Administrator.DC-1\Desktop>ipconfig
Windows IP Configuration
Ethernet adapter Local Area Connection:
Connection-specific DNS Suffix . :
IP Address. . . . . . . . . . . . : 172.16.11.237
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 172.16.11.1
Chắc chắn như vậy là đủ. Kết quả trả về bằng 0 cho thấy địa chỉ IP đã được thay đổi thành công.
'AUTHOR: Mitch Tulloch
'DATE: October 2006
'
ARGUMENTS:
'1. new_IP_address
'=========================-
Option Explicit
On Error Resume Next
Dim objWMIService
Dim objNetAdapter
Dim strComputer ' Can specify IP address or hostname or FQDN
Dim strAddress 'Contains the new IP address
Dim arrIPAddress
Dim arrSubnetMask
Dim colNetAdapters
Dim errEnableStatic
'Check for missing arguments
If WScript.Arguments.Count = 0 Then
Wscript.Echo "Usage: ChangeIPAddress.vbs new_IP_address"
WScript.Quit
End If
strComputer = "."
strAddress = Wscript.Arguments.Item(0)
arrIPAddress = Array(strAddress)
arrSubnetMask = Array("255.255.255.0")
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colNetAdapters = objWMIService.ExecQuery("Select * from
Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
For Each objNetAdapter in colNetAdapters
errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress,
WMI ra đời từ thời kỳ của Windows 98 hoặc sớm hơn. Trước đây nó được gọi với cái tên khác
Web-Based Enterprise Management (WBEM), tức Công cụ quản lý doanh nghiệp dựa trên nền
tảng Web. WBEM là công nghệ hợp tác phát triển bởi Microsoft, Cisco, Intel, Compaq và BMC
Software nhằm hỗ trợ quản lý các hệ thống máy chủ và máy để bàn trong môi trường doanh
nghiệp. WMI cung cấp mô hình thể hiện, lưu trữ và truy vấn cấu hình, thông tin trạng thái hay
nhiều khía cạnh hoạt động khác của các máy Windows. Các nhà phát triển có thể dùng WMI để
viết script hoặc quản lý mã nguồn để xem hay chỉnh sửa các thiết lập cấu hình trên máy Windows,
xem trạng thái của các ứng dụng, dịch vụ Windows và thực hiện toàn bộ nhiều công việc hữu ích
khác của một quản trị viên như triển khai, bảo trì, gỡ lỗi các mạng Windows.
Nói cách khác, nói tới WMI tức là nói tới:
• Hệ điều hành Windows: làm việc trên môi trường Windows và cho các máy chạy
Microsoft Windows.
• Management: có thể được dùng để quản lý các máy tính này.
• Instrumentation: cung cấp nhiều công cụ để xem và chỉnh sửa những thứ chạy bên trong
các máy tính này.
Bạn có thể ví máy tính Windows giống như một chiếc xe ô tô và WMI giống như nguồn điện hay
các thiết bị điện cho phép bảng đo đồng hồ hiển thị tốc độ, nhiệt độ động cơ, RPM… của ô tô.
Bản thân các điều khiển bảng đo đồng hồ này không phải là WMI. Bạn cần phải đưa ra cách lấy
thông tin từ bảng điện và thể hiện nó ở dạng có thể đọc được. Viết VBScript sử dụng WMI cũng
giống như tạo các bảng đo đồng hồ trung gian, liên hệ với thiết bị bên dưới ô tô và hiển thị thông
tin đối tượng để có thể cho bạn biết cần phải làm gì và điều khiển nào động cơ đang thực hiện. Nói
cách khác, Windows tích hợp tất cả công cụ dựng sẵn này qua WMI. Bạn chỉ cần biết cách làm sao
lấy chúng ra để thực hiện những điều mình muốn như thay đổi địa chỉ IP, xem múi giờ, khởi động
lại máy từ xa, hiển thị danh sách các bản vá đã được cài đặt…
WMI Namespace
Đến giờ, chúng ta vẫn chưa biết gì về cách thức hoạt động của WMI? Cũng không hẳn thế. Thực
ra, để hiểu được về WMI đòi hỏi chúng ta cần phải kiên nhẫn và có một chút kiến thức cơ sở. Hãy
bắt đầu bằng cách xem xét các namespace WMI. Trong thuật ngữ WMI, namespace là một cơ sở
dữ liệu logic của các lớp và các thể hiện của chúng. Dưới đây là một script đơn giản có tên
ShowNamespaces.vbs, liệt kê tất cả các namespace WMI bên dưới namespace gốc:
ms_409
Applications
Thực tế, root\CIMV2 là namespace WMI mặc định trên các máy Windows. Điều này có nghĩa là
nếu bạn không mô tả một namespace để kết nối tới trong dòng đầu tiên của script, WMI sẽ mặc
định tự động kết nối tới namespace root\CIMV2. Vì thế, nếu chúng ta thay đổi dòng đầu tiên
thành:
Set objWMIService = GetObject("winmgmts:\\")
thì kết quả cũng giống như trên. Chú ý là chúng ta có thể bỏ phần trước trong
winmgmts:\\.\root\CIMV2 đi. Nhớ lại trong bài một, phần trước thể hiện máy cục bộ và mặc định
WMI cho rằng bạn muốn làm việc với máy cục bộ. Nhưng thực tế, khi viết script người ta thường
sử dụng các biến (và định nghĩa chúng). Vì thế ở đây chúng ta có thể dùng một script phổ biến hơn
để hiển thị các namespace:
Option Explicit
On Error Resume Next
Dim strComputer
Dim strWMINamespace
Dim objWMIService
Dim colNamespaces
Dim objNamespace
strComputer = "."
strWMINamespace = "\root\CIMV2"
Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace)
Set colNamespaces = objWMIService.InstancesOf("__NAMESPACE")
For Each objNamespace In colNamespaces
WScript.Echo objNamespace.Name
Next
Tại sao chúng ta cần tìm hiểu tất cả các vấn đề này? Lý do chính là bởi tính linh hoạt! Ví dụ, nếu
cần chạy script trên một máy từ xa, chúng ta có thể thay đổi biến strComputer thành địa chỉ của
máy từ xa. Hoặc nếu cần hiển thị một phần khác của namespace, chúng ta có thể thêm một vài
dòng vào script để nó nhận dữ liệu đầu vào của người dùng trên biến strWMINamespace.
HiPerfCooker_v1
WMIPingProvider
Microsoft WMI Forwarding Event Provider
Win32_WIN32_TSNETWORKADAPTERSETTING_Prov
SystemConfigurationChangeEvents
Win32_WIN32_TERMINALSERVICE_Prov
Win32_WIN32_TSREMOTECONTROLSETTING_Prov
Win32_WIN32_TSNETWORKADAPTERLISTSETTING_Prov
Win32_WIN32_COMPUTERSYSTEMWINDOWSPRODUCTACTIVATIONSETTING_Prov
Win32_WIN32_TSSESSIONDIRECTORY_Prov
CmdTriggerConsumer
Standard Non-COM Event Provider
SessionProvider
WBEMCORE
RouteEventProvider
WhqlProvider
Win32_WIN32_TSSESSIONSETTING_Prov
Win32_WIN32_TERMINALTERMINALSETTING_Prov
Win32_WIN32_TSCLIENTSETTING_Prov
Win32_WIN32_TERMINALSERVICESETTING_Prov
WMI Kernel Trace Event Provider
Win32_WIN32_PROXY_Prov
NamedJobObjectProv
MS_Shutdown_Event_Provider
SECRCW32
Win32ClockProvider
MS_Power_Management_Event_Provider
Win32_WIN32_WINDOWSPRODUCTACTIVATION_Prov
RouteProvider
Cimwin32A
Dim strWMINamespace
Dim objWMIService
Dim colClasses
Dim objClass
strComputer = "."
strWMINamespace = "\root\CIMV2"
Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace)
Set colClasses = objWMIService.SubclassesOf()
For Each objClass In colClasses
WScript.Echo objClass.Path_.Path
Next
Và một số kết quả sau khi chạy script này trên máy Windows XP:
C:\scripts>cscript ShowClasses.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
\\XP\ROOT\CIMV2:__SystemClass
\\XP\ROOT\CIMV2:__thisNAMESPACE
\\XP\ROOT\CIMV2:__Provider
\\XP\ROOT\CIMV2:__Win32Provider
\\XP\ROOT\CIMV2:__IndicationRelated
\\XP\ROOT\CIMV2:__EventGenerator
\\XP\ROOT\CIMV2:__TimerInstruction
\\XP\ROOT\CIMV2:__IntervalTimerInstruction
...
\\XP\ROOT\CIMV2:MSFT_WMI_GenericNonCOMEvent
\\XP\ROOT\CIMV2:MSFT_WmiSelfEvent
\\XP\ROOT\CIMV2:Msft_WmiProvider_OperationEvent
\\XP\ROOT\CIMV2:Msft_WmiProvider_ComServerLoadOperationEvent
\\XP\ROOT\CIMV2:Msft_WmiProvider_InitializationOperationFailureEvent
\\XP\ROOT\CIMV2:Msft_WmiProvider_LoadOperationEvent
On Error Resume Next
Dim strComputer
Dim strWMINamespace
Dim strWMIQuery
Dim objWMIService
Dim colItems
Dim objItem
strComputer = "."
strWMINamespace = "\root\CIMV2"
strWMIQuery = "SELECT * FROM Win32_TimeZone"
Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace)
Set colItems = objWMIService.ExecQuery(strWMIQuery)
For Each objItem In colItems
WScript.Echo objItem.Caption
Next
Và đây là kết quả chạy của script:
C:\scripts>cscript DisplayTimeZone.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
(GMT-06:00) Central Time (US & Canada)
Hãy xem script này hoạt động như thế nào. Đầu tiên, bạn có thể thấy chúng dựa trên rất nhiều các
script đã được tạo ở trên. Nói cách khác, chúng ta bắt đầu bằng cách kết nối WMI, dùng lệnh sau:
Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace)
Nhưng lệnh tiếp theo là mới:
Set colItems = objWMIService.ExecQuery(strWMIQuery)
Điều chúng ta thực hiện ở đây là thực thi một truy vấn trên WMI để thu thập thông tin từ nó. Truy
vấn được định nghĩa trước đó, dùng lệnh sau:
strWMIQuery = "SELECT * FROM Win32_TimeZone"
Câu lệnh SELECT theo kiểu cấu trúc SQL này sẽ trả ra tất cả (dấu hoa thị) những gì nhà cung cấp
Win32_TimeZone có cho chúng ta và lưu trữ kết quả trong một tập hợp có tên colItems. Sau đó,
End If
strComputer = "."
strAddress = Wscript.Arguments.Item(0)
arrIPAddress = Array(strAddress)
arrSubnetMask = Array("255.255.255.0")
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colNetAdapters = objWMIService.ExecQuery("Select * from
Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
For Each objNetAdapter in colNetAdapters
errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress,
arrSubnetMask)
Next
'Display result or error code
If errEnableStatic=0 Then
Wscript.Echo "Adapter's IP address has been successfully changed to " &
strAddress
Else
Wscript.Echo "Changing the adapter's address was not successful. Error
code " & errEnableStatic
End If
Script trên thay đổi địa chỉ IP của một bộ điều hợp mạng, dùng
Win32_NetworkAdapterConfiguration, một trong những lớp WMI hữu ích nhất để quản lý cầu
hình mạng TCP/IP cho các máy chạy trên nền Windows. Ở phần ba, chúng ta đã dạo một vòng sơ
lược qua WMI với những namespace (không gian tên), provider (nhà cung cấp) và class (lớp) của
nó. Nhờ đó, chúng ta có thể hiểu kỹ càng hơn những dòng mã nằm ở giữa script:
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Nếu bạn nhớ lại ở bài trước, dòng này có tác dụng kết nối tới namespace root\cimv2 trên máy cục
bộ bằng cách định nghĩa một đối tượng có tên objWMIService và đặt nó bằng với giá trị trả về của
phương thức GetObject. Tất nhiên, sau khi kết nối tới namespace này, bạn có thể thu thập thông
tin từ nó.
thay đổi lệnh SELECT như sau:
Select * from Win32_NetworkAdapterConfiguration where DHCPEnabled=TRUE
Thông tin tương tự cũng sẽ được tìm thấy trên một trang MSDN giống như vậy. Hình 2 cho chúng
ta thấy điều này:
Hình 2: Thuộc tính DHCPEnabled của lớp Win32_NetworkAdapterConfiguration
Còn các phương thức của lớp thì sao? Nhớ lại rằng phương thức (method) là các hàm gọi đến để
thực hiện một số thao tác khác nhau dùng WMI. Kết quả tìm kiếm cho thấy
Win32_NetworkAdapterConfiguration cũng có rất nhiều phương thức, tổng cộng là 41. Bạn có thể
tìm các phương thức cho lớp này nằm trên cùng một trang bên dưới các thuộc tính, như trong Hình
3:
Hình 3: Các phương thức của lớp Win32_NetworkAdapterConfiguration
Trở lại một chút với phần quan trọng sau trong script:
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colNetAdapters = objWMIService.ExecQuery("Select * from
Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
For Each objNetAdapter in colNetAdapters
errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress,
arrSubnetMask)
Next
Đầu tiên chúng ta dùng thuộc tính IPEnabled của lớp Win32_NetworkAdapterConfiguration để trả
về tập hợp các bộ điều hợp mạng có giới hạn TCP/IP và được cho phép hoạt động. Sau đó gọi
phương thức EnableStatic của cùng lớp này để thay đổi địa chỉ IP và subnet mask của các bộ điều
hợp mạng này, dùng các biến mảng arrIPAddress và arrSubnetMask, đã được định nghĩa trước đó
trong script. Chúng ta sẽ cần phải thêm hai biến vào như là các tham số cho phương thức này. Đơn
giản là bởi khi kích vào liên kết EnableStatic trong Hình 3 ở trên, trang MSDN hiển thị thông tin
như Hình 4, cung cấp cho chúng ta những điều cần thiết để có thể sử dụng được lớp này:
Hình 4: Thông tin chi tiết về phương thức EnableStatic của lớp
Win32_NetworkAdapterConfiguration
Không chỉ cung cấp cho chúng ta cú pháp về cách gọi lớp, MSDN còn cho chúng ta biết giá trị trả
về và cách biên dịch các điều kiện lỗi khác có thể phát sinh. Đó là lý do vì sao chúng ta dùng biến
'DATE: December 2006
'
'ARGUMENTS: