111
List Phần 1: Những khái niệm cơ bản Phần 2: Hoàn chỉnh script Phần 3: Hiểu về WMI Phần 4: Sử dụng Win32_NetworkAdapterConfiguration Phần 5: Vượt qua thử thách Phần 6: Những bước đầu tiên về scripting remote Phần 7: Xử lý sự cố lỗi Phần 8: Xử lý lỗi kịch bản điều khiển từ xa bằng Network Monitor 3.0 Phần 9: Tìm hiểu kịch bản điều khiển xa Phần 10: Các thủ thuật của kịch bản điều khiển xa Phần 11: Các thủ thuật kịch bản khác Phần 12: Các thuộc tính của lớp WMI Phần 13: Kịch bản trả về tất cả các giá trị Quản lý các mạng Windows dùng Script - 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

Quản lý các mạng Windows dùng Script

Embed Size (px)

Citation preview

Page 1: Quản lý các mạng Windows dùng Script

List Phần 1: Những khái niệm cơ bản

 Phần 2: Hoàn chỉnh script Phần 3: Hiểu về WMI  Phần 4: Sử dụng Win32_NetworkAdapterConfiguration  Phần 5: Vượt qua thử thách  Phần 6: Những bước đầu tiên về scripting remote Phần 7: Xử lý sự cố lỗi Phần 8: Xử lý lỗi kịch bản điều khiển từ xa bằng Network Monitor 3.0 Phần 9: Tìm hiểu kịch bản điều khiển xa Phần 10: Các thủ thuật của kịch bản điều khiển xa Phần 11: Các thủ thuật kịch bản khác Phần 12: Các thuộc tính của lớp WMI Phần 13: Kịch bản trả về tất cả các giá trị

Quản lý các mạng Windows dùng Script - 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ù hợp nhất với mình. Và lúc đó người ta gọi anh là “thợ lành nghề”. Muốn được như vậy, ai cũng phải bắt đầu với những điều cơ bản nhất, ở đây là

Page 2: Quản lý các mạng Windows dùng Script

Windows scripting. Nói đến script, nhiều người tưởng chừng rất khó, thực sự khó vì trước hết… script rất khó dịch sang tiếng Việt! Script nghĩa là “kịch bản”, nhưng dân công nghệ chúng ta đâu phải là người làm phim nên kịch bản của thế giới IT chỉ toàn những đoạn mã loằng ngoằng mà chỉ có các chuyên gia mới hiểu, còn nhiều người “thường thường bậc trung” như… sinh viên công nghệ thì chịu! Chính bởi vậy mà hôm nay chúng ta sẽ bắt đầu từ những cái cơ bản nhất, sau đó nâng cao dần khả năng hiểu những khía cạnh sâu xa hơn trong viết và dùng script ở các mạng Windows. Mục đích cuối cùng mà chúng ta hướng tới là kể cả những người mới bắt đầu tìm hiểu như bạn, như tôi đều có thể script hoá tự động công việc, để cuộc sống của các admin an nhàn hơn. Chúng ta sẽ thực hiện điều này trên cả script do chính bạn viết ra hoặc download về từ nhiều nguồn khác nhau. Chúng ta cũng sẽ được biết một số tài nguyên liên quan đáng tìm hiểu để có cái nhìn sâu sắc hơn về Windows scripting, cũng như một số công cụ trợ giúp có thể sẽ rất hữu ích trong tương lai.

Các thiết lập TCP/IP scripting

Hầu như admin nào cũng dùng Visual Basic Script (VBScript) để viết kịch bản quản trị Windows (Windows admin script). VBScript không chỉ là một ngôn ngữ mạnh mà cú pháp của nó còn khá đơn giản để học và làm. VBScript có thể dùng chung với Windows Management Instrumentation (WMI) và Active Directory Services Interfaces (ADSI) để viết kịch bản cho bất kỳ khía cạnh nào của một hệ thống chạy hệ điều hành Windows hay một mạng dùng Active Directory. Chúng ta sẽ bắt đầu học về Windows scripting bằng cách dùng VBScript với WMI để thực hiện một điều sẽ rất hữu ích: thay đổi địa chỉ IP của một network adapter.

Tại sao lại cần thực hiện điều này? Đó là do chúng ta sẽ phải sử dụng nhiều đến một máy chủ ảo và một PC ảo để thiết lập môi trường kiểm tra. Chúng ta sẽ cần phải chuyển một máy ảo (VM) chạy hệ điều hành Windows Server 2003 từ mạng ảo này sang mạng ảo khác để sử dụng lại server (máy chủ) cho một số mục đích khác. Như thế có nghĩa là chúng ta sẽ cần thay đổi địa chỉ IP trên server (cũng có thể là cổng vào mặc định nữa). Bạn có thể thực hiện điều này bằng cách mở Network Connections trong Control Panel và kích phải chuột lên Local Area Connections, chọn Properties > Internet Protocol (TCP/IP) trên tab General và bấm chọn Properties, nhập địa chỉ IP mới rồi ấn OK hai lần. Đây là cách thực hiện phổ biến nhưng nghe qua bạn đã thấy khá dài dòng và mệt mỏi. Với những chuyên gia, họ thích sử dụng Command Promt hơn, lệnh dùng ở đâ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

Page 3: Quản lý các mạng Windows dùng Script

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 định và sau đó đưa biến này vào phương thức SetCookingTime thiết lập cho một trường hợp cụ thể của lớp này (một trường hợp thực, không phải là lò vi sóng trong lớp trừu tượng). Với WMI VBScript, chúng ta có thể thực hiện như sau:

intCookingTime = 120 errSetCookingTime = objMicrowave.SetCookingTime(intCookingTime)

Nhưng đối tượng lò vi sóng (objMicrowave) ở đâu ra? Chúng ta vẫn chưa tạo nó, vì vậy hãy tạo bằng cách dùng lệnh Set và phương thức CreateObject:

Set objMicrowave = CreateObject("MicrowaveOven")

Thực ra, nếu xét kỹ hơn thì objMicrowave không phải là đối tượng của lớp MicrowaveOven. Chính xác hơn nó là một đối tượng tham chiếu tới một thể hiện của lớp MicrowaveOven. Nhưng hiện tại chúng ta mới chỉ bắt đầu với những gì cơ bản nhất nên các khía cạnh sâu hơn này sẽ được tìm hiểu ở sau.

Tiếp theo, tạo thêm biến strColor để thiết lập thuộc tính màu sắc cho lò vi sóng của chúng ta. Đặt giá trị biến là Green (màu xanh là cây), script sẽ có dạng như bên dưới (với một số chú thích bên cạnh):

strColor = "Green" 'gán màu cho lò vi sóng intCookingTime = 120 'quy định thời gian nấu (tính theo giây) Set objMicrowave = CreateObject("MicrowaveOven") 'tạo một thể hiện của đối tượng errSetCookingTime = objMicrowave.SetCookingTime(intCookingTime) 'gọi một phương thức để

                                             ‘thiết lập thời gian nấu và ghi lại đoạn mã lỗi kết quả

objMicrowave.Color = strColor 'thiết lập giá trị thuộc tính Color (màu sắc)

Cũng không quá khó phải không các bạn!

Trở lại với script

Muốn truy cập các thiết lập cấu hình TCP/IP của máy dùng WMI, bạn cần viết mã:

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Lệnh này sẽ kết nối bạn 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à thiết lập nó bằng với giá trị trả về của phương thức GetObject. Sau khi kết nối tới namespace này, bạn có thể thu thập thông tin như bên dưới:

Set colNetAdapters = objWMIService.ExecQuery("Select * from

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

Page 4: Quản lý các mạng Windows dùng Script

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.

Mang tất cả lại với nhau

Bây giờ, ghép tất cả các phần lại với nhau và hãy xem chúng ta có những gì:

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

Bạn biết đấy, đoạn mã này đưa ra các định nghĩa biến, điều khiển lỗi, dùng dữ liệu đầu vào và kiểm chứng

Page 5: Quản lý các mạng Windows dùng Script

kết quả trả về. Chúng ta sẽ sử dụng lại đoạn mã này trong những phần sau của loạt bài, nhưng đầu tiên hãy xem liệu nó có làm việc hay không. Ghi script lại với tên ChangeIPAddress.vbs (nhớ là phải tắt Word Wrap trong Notepad) và copy nó lên desktop của máy chủ có địa chỉ tĩnh 172.16.11.45. Sau đó, mở cửa sổ dòng lệnh Command Promp với vai trò người dùng Administrator, chuyển tới thư mục Desktop và chạy script, dùng Cscript.exe. Kết quả trả về:

C:\Documents and Settings\Administrator\Desktop>ipconfig

Windows IP Configuration

Ethernet adapter Local Area Connection:

Connection-specific DNS Suffix . : IP Address. . . . . . . . . . . . : 172.16.11.45 Subnet Mask . . . . . . . . . . . : 255.255.255.0 Default Gateway . . . . . . . . . : 172.16.11.1

C:\Documents and Settings\Administrator.DC-1\Desktop>cscript ChangeIPAddress.vbs

Microsoft (R) Windows Script Host Version 5.6 Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

C:\Documents and Settings\Administrator\Desktop>ipconfig

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.

Còn nhiều điều thú vị nữa về Windows scripting, nhưng xin hẹn các bạn ở phần hai. Và bây giờ thì xin tạm biệt!

Quản lý các mạng Windows dùng script - 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

Page 6: Quản lý các mạng Windows dùng Script

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

Việc đầu tiên chúng ta cần làm để sắp xếp gọn gàng script là định nghĩa các biến sẽ dùng. VBScript cho phép định nghĩa ngầm các biến đơn giản bằng cách dùng nó trong một câu lệnh, nhưng sẽ tốt hơn nếu bạn khai báo tường minh chúng ngay khi bắt đầu script. Khai báo một biến sẽ nói cho VBScript biết về sự tồn tại của nó để cấp phát bộ nhớ lưu trữ. Vì sao khai báo biến tường minh lại hay hơn? Ví dụ như trong một script dài, bạn thường phạm phải một hay một số lỗi gõ phím nhầm. Và khi gõ nhầm tên của một biến, script của bạn sẽ không chạy được. Nếu khai báo biến tường mình ở đầu script thì bất kỳ biến nào được khai báo ngầm về sau trong script (có thể là nguyên nhân gây ra lỗi gõ nhầm) sẽ tạo ra một lỗi runtime. Các thông báo lỗi có thể sẽ giúp bạn xác định được vị trí nhầm lẫn và gỡ lỗi cho script của bạn.

Để VBScript biết bạn khai báo tường minh tất cả các biến trong script, thêm lệnh sau vào đầu script:

Option Explicit

Nếu thêm lệnh này vào đầu script ChangeIPAddress.vbs và chạy nó từ Command Prompt, kết quả là:

C:\Documents and Settings\Administrator.DC-1\Desktop>ChangeIPAddress.vbsMicrosoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

C:\Documents and Settings\Administrator.DC-1\Desktop\ChangeIPAddress.vbs(2, 1) Microsoft VBScript runtime error: Variable is undefined: 'strComputer'

Điều mà VBScript (hay cơ chế script đã đăng ký của Windows Script Host để chạy các script VBScript) muốn nói ở đây là có một lỗi trong dòng 2 của script:

strComputer = "."

Vì sao lại xuất hiện lỗi này? Đó là do chúng ta đang gán giá trị cho một biến xâu (strComputer) chưa được khai báo. Vì thế, bây giờ chúng ta cần thêm các khai báo cho biến dùng trong script:

Option ExplicitDim objWMIServiceDim objNetAdapterDim strComputerDim arrIPAddressDim arrSubnetMaskDim colNetAdaptersDim 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

Page 7: Quản lý các mạng Windows dùng Script

     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ị hư hỏng không chạy được.

Cách đơn giản nhất để kiểm soát các lỗi thời gian chạy là lờ chúng đi khi chúng xuất hiện. Bạn có thể nói với VBScript thực hiện điều này bằng cách thêm lệnh sau vào gần nơi bắt đầu của script, chẳng hạn như ngay sau Option Explicit:

On Error Resume Next

Tất nhiên, bạn còn muốn thực hiện thêm nhiều thứ khác trong kiểm soát lỗi. Ví dụ như kiểm tra sự tồn tại của một điều kiện lỗi thời gian chạy ở một số điểm nào đấy trong script (như ngay sau khi kết nối tới dịch vụ WMI trên một máy từ xa) để xác định xem liệu một hoạt động nào đó script được quy định để thực hiện có thành công hay không. Sau đó, dựa trên kết quả kiểm tra điều kiện lỗi, bạn có thể quyết định script các hoạt động tiếp theo của script. Ví dụ, nếu một lỗi xuất hiện, bạn có thể nhận được thông báo nói rằng: “Computer X not found” (không tìm thấy máy tính X) và sau đó script tiếp tục chạy. Chúng ta sẽ tìm hiểu sâu hơn về kiểm soát lỗi trong một số bài khác, còn bây giờ bạn chỉ cần thêm lệnh trên vào để bỏ qua bất kỳ lỗi thời gian chạy nào xuất hiện.

Dữ liệu đầu vào của người dùng

Sẽ phải làm gì nếu chúng ta muốn mô tả địa chỉ IP mới cho máy khi chạy script thay vì viết mã cho nó vào script dưới dạng 172.16.11.99? Trong trường hợp này chúng ta cần chỉnh sửa script để cho phép cung cấp dữ liệu vào của người dùng khi chạy nó. Thực hiện bằng cách thêm vào các tham số khi chạy script từ dòng lệnh. Ví dụ gõ ChangeIPAddress.vbs 172.16.11.188 sẽ thay đổi địa chỉ IP của bộ điều hợp mạng thành 172.16.11.188… Chúng ta có thể thực hiện như sau:

Option ExplicitOn Error Resume Next

Dim objWMIServiceDim objNetAdapter

Page 8: Quản lý các mạng Windows dùng Script

Dim strComputerDim strAddressDim arrIPAddressDim arrSubnetMaskDim colNetAdaptersDim errEnableStatic

If WScript.Arguments.Count = 0 Then     Wscript.Echo "Usage: ChangeIPAddress.vbs new_IP_address"     WScript.QuitEnd 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.QuitEnd 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 dòng bên dưới:

strAddress = Wscript.Arguments.Item(0) arrIPAddress = Array(strAddress)

Dòng đầu tiên lấy ra phần tử đầu tiên (phần tử 0) của tập hợp WScript.Arguments và gán nó trở thành biến xâu strAddress. Dòng thứ hai sau đó lấy biến xâu strAddress này và gán nó trở thành phần tử đầu tiên của mảng arrIPAddress.

Page 9: Quản lý các mạng Windows dùng Script

Hãy xem chuyện gì xảy ra khi chạy script mới này, đầu tiên không mô tả tham số, sau đó là chạy với một tham số:

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.31   Subnet Mask . . . . . . . . . . . : 255.255.255.0   Default Gateway . . . . . . . . . : 172.16.11.1

C:\Documents and Settings\Administrator.DC-1\Desktop>ChangeIPAddress.vbsMicrosoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

Usage: ChangeIPAddress.vbs new_IP_address

C:\Documents and Settings\Administrator.DC-1\Desktop>ChangeIPAddress.vbs 172.16.11.188Microsoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

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.188   Subnet Mask . . . . . . . . . . . : 255.255.255.0   Default Gateway . . . . . . . . . : 172.16.11.1

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

Page 10: Quản lý các mạng Windows dùng Script

Chạy script lại một lần nữa:

C:\Documents and Settings\Administrator.DC-1\Desktop>ChangeIPAddress.vbs 172.16.11.237Microsoft (R) Windows Script Host Version 5.6Copyright (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. Một phương thức hay hơn sẽ hiển thị một thông báo bằng cách thay lệnh báo hiệu lại bằng lệnh sau:

If errEnableStatic=0 Then     Wscript.Echo "Adapter's IP address has been successfully changed to " & strAddressElse     Wscript.Echo "Changing the adapter's address was not successful. Error code " & errEnableStaticEnd If

Thêm các lệnh sau vào cuối script và chạy lại hai lần, một với địa chỉ IP chính xác và một với địa chỉ IP tuỳ ý:

C:\Documents and Settings\Administrator.DC-1\Desktop>ChangeIPAddress.vbs 172.16.11.173Microsoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

Adapter's IP address has been successfully changed to 172.16.11.173

C:\Documents and Settings\Administrator.DC-1\Desktop>ChangeIPAddress.vbs 172.16.11.1492567Microsoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

Changing the adapter's address was not successful. Error code 70

C:\Documents and Settings\Administrator.DC-1\Desktop>

Kết luận

Việc cuối cùng chúng ta cần làm là thêm một vài chú thích vào script để diễn giải cho script. Đây luôn là một ý kiến hay vì có thể một năm sau đọc lại và muốn thay đổi một điểm gì đó trong script, bạn sẽ dễ dàng tìm ra cái mình cần. Đây là script hoàn chỉnh cuối cùng của chúng ta để thay đổi địa chỉ IP bộ điều hợp mạng:

=========================' NAME: ChangeIPAddress.vbs'

Page 11: Quản lý các mạng Windows dùng Script

'AUTHOR: Mitch Tulloch'DATE: October 2006'ARGUMENTS:'1. new_IP_address'=========================-

Option ExplicitOn Error Resume Next

Dim objWMIServiceDim objNetAdapterDim strComputer     ' Can specify IP address or hostname or FQDNDim strAddress     'Contains the new IP addressDim arrIPAddressDim arrSubnetMaskDim colNetAdaptersDim errEnableStatic

'Check for missing arguments

If WScript.Arguments.Count = 0 Then     Wscript.Echo "Usage: ChangeIPAddress.vbs new_IP_address"     WScript.QuitEnd 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 " & strAddressElse     Wscript.Echo "Changing the adapter's address was not successful. Error code " & errEnableStaticEnd If

Quản lý các mạng Windows dùng script - Phần 3: Hiểu về WMI

Phần này sẽ giới thiệu với các bạn về nguyên tắc hoạt động của Windows Management Instrumentation (WMI) cách nó có thể được scrip bằng VBScript.  

Trong hai phần đầu của loạt bài này chúng ta đã biết cách thay đổi địa chỉ IP của một bộ điều hợp mạng trên máy tính Windows dùng VBScript. Chúng ta cũng đã biết về nhiều khái niệm cơ bản của Windows scripting như lớp (class), đối tượng (object), thuộc tính (property), phương thức (method) và các kiểu biến khác nhau như biến xâu (string), biến mảng (array), biến nguyên (integer), biến tập hợp (collection). Kết thúc ở phần

Page 12: Quản lý các mạng Windows dùng Script

một là một script đơn giản thực hiện được nhiệm vụ thay đổi địa chỉ, và phần hai bổ sung thêm nhiều tính năng hỗ trợ quan trọng khác như định nghĩa các biến, triển khai kiểm soát lỗi, nhận thông tin người dùng đầu vào, hiển thị xác nhận dữ liệu đầu ra và dẫn giải script bằng các chú thích.

Script cuối cùng của chúng ta hoạt động tốt như mong đợi, nhưng vẫn còn nhiều thứ rất khó hiểu. Ví dụ như dòng lệnh sau:

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Trong phần đầu chúng ta có chú thích: “Dòng lệnh này 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 điều khiển trả về từ phương thức GetObject”.

Điều này có nghĩa là gì? WMI là gì và nó hoạt động như thế nào? Vì sao khái niệm này lại quan trọng khi muốn viết được một script tốt để quản trị các máy Windows?

Hiểu về WMI

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:

Page 13: Quản lý các mạng Windows dùng Script

Set objWMIService = GetObject("winmgmts:\\.\root")Set colNamespaces = objWMIService.InstancesOf("__NAMESPACE")

For Each objNamespace In colNamespacesWScript.Echo objNamespace.NameNext

Và kết quả chạy script trên một máy Windows XP là:

C:\scripts>cscript ShowNamespaces.vbs

Microsoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

SECURITYRSOPCliSecurityCenterWMICIMV2PolicyMicrosoftDEFAULTdirectorysubscription

Mỗi namespace này có thể là một nguồn cho phép bạn truy vấn thông tin liên quan đến trạng thái hay cấu hình một số yếu tố của máy tính Windows (thông thường cũng có thể chỉnh sửa cấu hình đó). Các namespace này được tổ chức theo kiểu cấu trúc phân tầng như cấu trúc thư mục trên ổ cứng. Ví dụ, chúng ta có thể hiển thị tất cả namespace dưới namespace gốc root\CIMV2 bằng cách thay đổi dòng đầu tiên trong script như sau:

Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")

Khi chạy script đã được thay đổi, kết quả có dạng:

C:\scripts>cscript ShowNamespaces.vbsMicrosoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

ms_409Applications

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

Page 14: Quản lý các mạng Windows dùng Script

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 ExplicitOn Error Resume NextDim strComputerDim strWMINamespaceDim objWMIServiceDim colNamespacesDim objNamespace

strComputer = "."strWMINamespace = "\root\CIMV2"

Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace)Set colNamespaces = objWMIService.InstancesOf("__NAMESPACE")

For Each objNamespace In colNamespacesWScript.Echo objNamespace.NameNext

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.

Nhà cung cấp WMI

Tìm ra đúng namespace là thách thức đầu tiên (mặc dù hầu hết các trường hợp kết nối tới namespace mặc định là đủ). Ngoài ra bạn còn cần tìm ra đúng nhà cung cấp phù hợp để truy vấn hoặc update dữ liệu trên hệ thống bạn đang hướng đến. Dưới đây là script có tên ShowProviders.vbs, hiển thị tất cả nhà cung cấp WMI cho namespace root\CIMV2:

Option ExplicitOn Error Resume NextDim strComputerDim strWMINamespaceDim objWMIServiceDim colWin32ProvidersDim objWin32Provider

strComputer = "."strWMINamespace = "\root\CIMV2"

Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace)Set colWin32Providers = objWMIService.InstancesOf("__Win32Provider")

For Each objWin32Provider In colWin32ProvidersWScript.Echo objWin32Provider.NameNext

Page 15: Quản lý các mạng Windows dùng Script

Và kết quả sau khi chạy script này trên một máy Windows XP là:

C:\scripts>cscript ShowProviders.vbsMicrosoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

Win32_WIN32_TSLOGONSETTING_ProvMS_NT_EVENTLOG_PROVIDERWin32_WIN32_TSENVIRONMENTSETTING_ProvSCM Event ProviderProviderSubSystemVolumeChangeEventsNamedJobObjectLimitSettingProvHiPerfCooker_v1WMIPingProviderMicrosoft WMI Forwarding Event ProviderWin32_WIN32_TSNETWORKADAPTERSETTING_ProvSystemConfigurationChangeEventsWin32_WIN32_TERMINALSERVICE_ProvWin32_WIN32_TSREMOTECONTROLSETTING_ProvWin32_WIN32_TSNETWORKADAPTERLISTSETTING_ProvWin32_WIN32_COMPUTERSYSTEMWINDOWSPRODUCTACTIVATIONSETTING_ProvWin32_WIN32_TSSESSIONDIRECTORY_ProvCmdTriggerConsumerStandard Non-COM Event ProviderSessionProviderWBEMCORERouteEventProviderWhqlProviderWin32_WIN32_TSSESSIONSETTING_ProvWin32_WIN32_TERMINALTERMINALSETTING_ProvWin32_WIN32_TSCLIENTSETTING_ProvWin32_WIN32_TERMINALSERVICESETTING_ProvWMI Kernel Trace Event ProviderWin32_WIN32_PROXY_ProvNamedJobObjectProvMS_Shutdown_Event_ProviderSECRCW32Win32ClockProviderMS_Power_Management_Event_ProviderWin32_WIN32_WINDOWSPRODUCTACTIVATION_ProvRouteProviderCimwin32AMsft_ProviderSubSystemWin32_WIN32_TERMINALSERVICETOSETTING_ProvNamedJobObjectSecLimitSettingProvWin32_WIN32_TSSESSIONDIRECTORYSETTING_ProvWin32_WIN32_TSPERMISSIONSSETTING_ProvWin32_WIN32_TSACCOUNT_ProvWin32_WIN32_TERMINAL_ProvMSIProv

Page 16: Quản lý các mạng Windows dùng Script

DskQuotaProviderNetDiagProvWin32_WIN32_TSGENERALSETTING_ProvCIMWin32NamedJobObjectActgInfoProvNT5_GenericPerfProvider_V1WMI Self-Instrumentation Event ProviderMS_NT_EVENTLOG_EVENT_PROVIDER

Nghe chừng có vẻ quá nhiều! Nhưng dùng danh sách các nhà cung cấp này, bạn có thể dễ dàng tìm kiếm trên MSDN để biết thêm thông tin về một nhà cung cấp cụ thể và tìm kiếm phương thức hỗ trợ.

Các lớp WMI

Bên cạnh namespace và provider (nhà cung cấp), bạn cũng cần phải hiểu về các lớp WMI nếu muốn tăng cường thêm sức mạnh của WMI cho các hoạt động quản trị Windows trên script. Lớp là một mẫu của kiểu đối tượng bạn có thể quản lý bằng WMI. Ví dụ lớp có tên Win32_LogicalDisk là một mẫu đĩa logic trên các máy Windows, và WMI dùng lớp này để tạo một thể hiện của Win32_LogicalDisk cho từng đĩa được cài. 

Dưới đây là một script có tên ShowClasses.vbs hiển thị tất cả các lớp (có khả năng là các đối tượng có thể quản lý) của namespace root\CIMV2:

Option ExplicitOn Error Resume NextDim strComputerDim strWMINamespaceDim objWMIServiceDim colClassesDim objClass

strComputer = "."strWMINamespace = "\root\CIMV2"

Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace)Set colClasses = objWMIService.SubclassesOf()

For Each objClass In colClassesWScript.Echo objClass.Path_.PathNext

Và một số kết quả sau khi chạy script này trên máy Windows XP:

C:\scripts>cscript ShowClasses.vbsMicrosoft (R) Windows Script Host Version 5.6Copyright (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

Page 17: Quản lý các mạng Windows dùng Script

\\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\\XP\ROOT\CIMV2:Msft_WmiProvider_OperationEvent_Pre\\XP\ROOT\CIMV2:Msft_WmiProvider_DeleteClassAsyncEvent_Pre\\XP\ROOT\CIMV2:Msft_WmiProvider_GetObjectAsyncEvent_Pre...\\XP\ROOT\CIMV2:Win32_ComputerSystemEvent\\XP\ROOT\CIMV2:Win32_ComputerShutdownEvent\\XP\ROOT\CIMV2:Win32_SystemTrace\\XP\ROOT\CIMV2:Win32_ModuleTrace\\XP\ROOT\CIMV2:Win32_ModuleLoadTrace\\XP\ROOT\CIMV2:Win32_ThreadTrace\\XP\ROOT\CIMV2:Win32_ThreadStartTrace\\XP\ROOT\CIMV2:Win32_ThreadStopTrace\\XP\ROOT\CIMV2:Win32_ProcessTrace\\XP\ROOT\CIMV2:Win32_ProcessStartTrace\\XP\ROOT\CIMV2:Win32_ProcessStopTrace...

Lại một lần nữa bạn thấy có vẻ quá nhiều và rắc rối, nhưng dùng danh sách này bạn có thể tìm trên MSDN thông tin liên quan đến một lớp WMI cụ thể dễ dàng hơn. Từ đó có thể tìm ra các thuộc tính và phương thức đi kèm với nó.

Sử dụng WMI

Chúng ta hãy sử dụng thực tiễn những thứ đã được nói lý thuyết ở trên. Một trong các lớp script ở trên hiển thị là Win32_TimeZone và chúng ta sẽ dùng nó để hiển thị múi giờ đã cấu hình trên máy tính. Đầu tiên chúng ta cần tìm thêm thông tin về lớp này trên MSDN (gõ từ khoá tìm kiếm "Win32_TimeZone class”). Từ trang kết quả, chúng ta có thể tìm các thuộc tính và phương thức lớp này hỗ trợ (mặc dù thực tế thì lớp cụ thể này chỉ có thuộc tính, không có phương thức) và dùng các thông tin tìm thấy để viết script mình muốn.

Một thử nghiệm cho cho thấy, thuộc tính chúng ta cần tìm là Caption, vì đây là dạng dễ đọc nhất về thông tin múi giờ lưu trữ trên máy. Dưới đây là script có tên DisplayTimeZone.vbs mà chúng ta sẽ dùng để truy vấn thông tin từ WMI và hiển thị nó:

Option ExplicitOn Error Resume NextDim strComputerDim strWMINamespaceDim strWMIQueryDim objWMIServiceDim colItemsDim objItem

Page 18: Quản lý các mạng Windows dùng Script

strComputer = "."strWMINamespace = "\root\CIMV2"strWMIQuery = "SELECT * FROM Win32_TimeZone"

Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace)Set colItems = objWMIService.ExecQuery(strWMIQuery)

For Each objItem In colItemsWScript.Echo objItem.CaptionNext

Và đây là kết quả chạy của script:

C:\scripts>cscript DisplayTimeZone.vbsMicrosoft (R) Windows Script Host Version 5.6Copyright (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 đó, lặp lại thao tác với từng đối tượng trong tập hợp (chỉ có một đối tượng được trả về bằng truy vấn) và hiển thị thuộc tính Caption của đối tượng, là xâu ký tự như bên dưới:

(GMT-06:00) Central Time (US & Canada)

Hãy thử nghiệm bài tập này

Chúng ta sẽ nghiên cứu sâu hơn về WMI scripting trong những bài sau, còn bây giờ hãy thử nghiệm một bài tập nhỏ. Copy nội dung của script DisplayTimeZone.vbs ở trên vào Notepad (nhớ tắt Word Wrap) và ghi nó lại dưới tên file PageFile.vbs. Bây giờ, thay đổi một dòng trong script (thực ra là một phần nhỏ của dòng) để khi script chạy, nó sẽ hiển thị đường dẫn và tên pagefile của hệ thống thay vì múi giờ. Mẹo: Tìm trên MSDN để có thêm thông tin về lớp Win32_PageFile. Chúng tôi sẽ đưa ra câu trả lời cho thử nghiệm này ở phần tiếp theo của loạt bài.

Page 19: Quản lý các mạng Windows dùng Script

Quản lý các mạng Windows dùng script - Phần 4: Sử dụng Win32_NetworkAdapterConfiguration

Sử dụng lớp WMI Win32_NetworkAdapterConfiguration để quản lý các thiết lập TCP/IP trên các mạng Windows thông qua VBScript.

Trong hai phần đầu của loạt bài này chúng ta đã xem xét một số khái niệm cơ bản của kỹ thuật Windows scripting trong quản lý các thiết lập mạng TCP/IP. Để minh hoạ và thực hành, chúng ta đã phát triển một script đơn giản sau với chức năng thay đổi địa chỉ của một bộ điều hợp mạng:

Option ExplicitOn Error Resume Next

Dim objWMIServiceDim objNetAdapterDim strComputer     ' Can specify IP address or hostname or FQDNDim strAddress     'Contains the new IP addressDim arrIPAddressDim arrSubnetMaskDim colNetAdaptersDim errEnableStatic

'Check for missing arguments

If WScript.Arguments.Count = 0 Then     Wscript.Echo "Usage: ChangeIPAddress.vbs new_IP_address"     WScript.QuitEnd 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 " & strAddressElse     Wscript.Echo "Changing the adapter's address was not successful. Error code " & errEnableStaticEnd 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")

Page 20: Quản lý các mạng Windows dùng Script

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ó.

Còn trong bài ngày hôm nay, dòng mã lệnh chúng ta sẽ tập trung vào theo sau dòng trên và sử dụng lớp Win32_NetworkAdapterConfiguration:

Set colNetAdapters = objWMIService.ExecQuery("Select * from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")

Nhớ lại bạn sẽ thấy, dòng lệnh thứ hai gọi phương thức ExecQuery cho đối tượng objWMIService mà chúng ta đã mô tả ở dòng đầu. Lệnh SELECT được đưa vào phương thức này với vai trò như một tham số. Và tập hợp tất cả cấu hình bộ điều hợp mạng trên hệ thống có giới hạn TCP/IP, được cho phép trên bộ điều hợp sẽ được trả lại và gán bằng biến colNetAdapters. Sau khi có tập hợp này, chúng ta có thể lặp vòng nó bằng lệnh For Each… Nhớ rằng, bạn  luôn phải chạy vòng lặp cho các tập hợp dù có tập hợp đó chỉ bao gồm một đối tượng.

Câu hỏi sẽ được đưa ra ở đây là: Chúng ta có thể làm thêm điều gì với lớp Win32_NetworkAdapterConfiguration?

Sử dụng các thuộc tính và phương thức của Win32_NetworkAdapterConfiguration

Bạn đã biết, thuộc tính thể hiện thông tin có thể truy vấn từ một hệ thống dùng WMI. Một lớp WMI càng có nhiều thuộc tính thì thông tin có thể lấy ra từ nó càng nhiều. Lớp Win32_NetworkAdapterConfiguration thực tế có 61 thuộc tính khác nhau. Một trong số chúng là duy nhất, hoàn toàn riêng của Win32_NetworkAdapterConfiguration, còn một số khác là do kế thừa từ nhiều lớp khác. Bạn có thể tìm thấy danh sách hoàn chỉnh các thuộc tính của lớp Win32_NetworkAdapterConfiguration trên MSDN. Khi học về sử dụng Windows scripting để quản lý các mạng Windows dùng script, một điều hết sức quan trọng là cần phải quen với những thông tin WMI trên MSDN như thế này. Hình 1 thể hiện một số thuộc tính của lớp Win32_NetworkAdapterConfiguration:

Page 21: Quản lý các mạng Windows dùng Script

Hình 1: Một số thuộc tính của lớp Win32_NetworkAdapterConfiguration

Ở hình trên, phần màu vàng minh hoạ là thể hiện thuộc tính nhị phân IPEnabled được kích vào, dùng để nhận dạng tất cả các bộ điều hợp mạng trên hệ thống có giới hạn TCP/IP và được cho phép hoạt động. Thực hiện bằng cách đưa lệnh SQL sau vào như một tham số cho phương thức objWMIService.ExecQuery:

Select * from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE

Lệnh Select * from sẽ mở rộng tính năng cho script bằng cách truy vấn tất cả các thuộc tính khác của lớp. Ví dụ, nếu muốn chọn tất cả bộ điều hợp mạng trên hệ thống có DHCP, đơn giản chỉ cầ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:

Page 22: Quản lý các mạng Windows dùng Script

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:

Page 23: Quản lý các mạng Windows dùng Script

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:

Page 24: Quản lý các mạng Windows dùng Script

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 lỗi trong dòng sau ở script:

errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)

Và đó cũng là lý do vì sao chúng ta sử dụng các dòng sau để ghi nhận mã lỗi nếu có lỗi nào đó xuất hiện khi script chạy:

If errEnableStatic=0 Then     Wscript.Echo "Adapter's IP address has been successfully changed to " & strAddressElse     Wscript.Echo "Changing the adapter's address was not successful. Error code " & errEnableStaticEnd If

Page 25: Quản lý các mạng Windows dùng Script

Một lần nữa chúng ta có thể mở rộng thêm tính năng cho script bằng cách gọi một số phương thức khác của lớp. Ví dụ, nếu muốn ngắt NetBIOS qua TCP/IP (NetBT) trên tất cả các bộ điều hợp mạng có giới hạn TCP/IP, chúng ta có thể dùng phương thức SetTcpNetbios như ở Hình 5:

Hình 5: Phương thức SetTcpipNetbios của lớp Win32_NetworkAdapterConfiguration

Kích chuột lên một liên kết trong trang MSDN ở trên, nó sẽ mở ra với các thông tin hướng dẫn sử dụng phương thức (Hình 6):

Page 26: Quản lý các mạng Windows dùng Script

Hình 6: Thông tin chi tiết về phuơng thức SetTcpipNetbios

Chúng ta có thể thấy rằng nếu muốn loại bỏ NetBT trên các bộ điều hợp, tất cả việc cần làm là thay đổi dòng sau trong script:

errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)

thành:

errEnableStatic = objNetAdapter.SetTcpipNetbios(2)

Sau khi thực hiện thay đổi này và “dọn dẹp” script bằng cách loại bỏ các biến không còn cần dùng đến, đặt lại tên cho các biến khác, chúng ta có script sau, có thể ngắt NetBT trên tất cả các bộ điều hợp mạng đã nói ở trên:

'=========================' NAME: DisableNetbios.vbs'

Page 27: Quản lý các mạng Windows dùng Script

'AUTHOR: Mitch Tulloch'DATE: December 2006''ARGUMENTS:'1. None'=========================-

Option ExplicitOn Error Resume Next

Dim objWMIServiceDim objNetAdapterDim strComputer     ' Can specify IP address or hostname or FQDNDim colNetAdaptersDim errDisableNetbios

strComputer = "."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.SetTcpipNetbios(2)Next

'Display result or error code

If errDisableNetbios=0 Then     Wscript.Echo "NetBIOS has been successfully disabled on the adapters"Else     Wscript.Echo "Disabling NetBIOS was not successful. Error code " & errDisableNetbiosEnd If

Hãy xem nó hoạt động ra sao. Hình 7 hiển thị thẻ WINS của hộp thoại Advanced TCP/IP Properties cho kết nối vùng cục bộ (Local Area Connection) trên máy Windows Server 2003:

Page 28: Quản lý các mạng Windows dùng Script

Hình 7: Các thiết lập NetBIOS cho TCP/IP trên máy Windows Server 2003

Chú ý là thiết lập NetBT hiện thời cho máy này là “Default” tương ứng với giá trị 0 của phương thức SetTcpipNetbios (xem Hình 6 ở trên). Copy script mới vào Notepad (nhớ tắt chức năng Word Wrap) và ghi nó với tên file DisableNetbios.vbs. Sau đó chạy script này trên máy chủ của chúng ta trong cửa sổ dòng lệnh Command Prompt dùng cscript (Hình 8):

Page 29: Quản lý các mạng Windows dùng Script

Hình 8: Ngắt NetBIOS cho TCP/IP dùng một script

Bây giờ hãy xem liệu nó có hoạt động không. Chúng ta cần đóng các trang thuộc tính TCP/IP và mở lại chúng để làm mới thiết lập NetBT trong giao diện GUI, có dạng như hình dưới (Hình 9):

Page 30: Quản lý các mạng Windows dùng Script

Hình 9: NetBT đã được loại bỏ thành công 

Kết luận 

Cách tốt nhất để học Windows scripting là xây dựng các ví dụ thực tiễn. Bạn nên làm các bài tập sau để củng cố những gì đã học trong bài này:

1. Thay đổi script, dùng các tham số như DisableNetbios.vbs 1 để dùng NetBT, DisableNetbios.vbs 2 để loại bỏ nó và DisableNetbios.vbs 0 để trả nó về thiết lập mặc định dùng DHCP để xác định xem liệu NetBT được dùng hay bị loại bỏ trên bộ điều hợp.

2. Chỉnh sửa lệnh SELECT trong script để chọn các bộ điều hợp mạng dựa trên một số thuộc tính khác của lớp Win32_NetworkAdapterConfiguration, và chỉnh sửa nâng cao hơn để gọi một số phương thức khác của lớp thực hiện một số thao tác khác trên cấu hình TCP/IP của các bộ điều hợp mạng.

3. Tìm kiếm trên MSDN để biết thêm về các lớp WMI khác có thể sẽ rất hữu ích trong các hoạt động quản trị Windows khác.

Quản lý các mạng Windows dùng script - Phần 5: Vượt qua thử thách

Ở phần trước của loạt bài này, chúng ta đã bắt đầu khám phá những điều mới mẻ về lớp Win32_NetworkAdapterConfiguration. Lớp WMI mạnh này có 61 thuộc tính và 41 phương thức, có thể được dùng cho truy vấn và thay đổi thiết lập mạng TCP/IP trên các máy Windows.

Để minh hoạ tính năng mạnh của lớp này, chúng ta đã sử dụng script mẫu phát triển tử phần một và hai, cũng như khai thác thông tin hỗ trợ trên MSDN để thay đổi script ban đầu và thực hiện được một số chức năng khác nhau. Cụ thể là thay đổi địa chỉ IP của một bộ điều hợp mạng và tuỳ biến để tạo ra script mới có thể ngắt NetBIOS qua TCP/IP (NetBT) trên tất cả các bộ điều hợp mạng có giới hạn TCP/IP được phép trên

Page 31: Quản lý các mạng Windows dùng Script

chúng.

Chúng ta sẽ cần khám phá thêm tính năng mạnh mẽ của lớp WMI này trong một số bài sau. Nhưng trước khi thực hiện điều đó, đầu tiên hãy nói về những trở ngại khi học script. Vượt qua mọi trở ngại, khó khăn để biết cách sử dụng script trong hoạt động quản trị mạng Windows.

Trở ngại

Sau khi bắt đầu cho đăng loạt bài này, chúng tôi nhận được nhiều câu hỏi từ phía bạn đọc: “Tôi có thể học script theo cách nào?”. Phản ứng đầu tiên của chúng tôi thường là chỉ cho người hỏi một số tài liệu như các sách viết về script, những bài báo, diễn đàn bàn luận về script… Vâng, câu trả lời kiểu này sẽ hữu ích cho những ai muốn chuyên tâm bắt tay làm từ đầu và tự rèn luyện mình nghiêm khắc để có được một kỹ năng. Nhưng như thế cũng thường khiến người ta phát sinh một tâm lý rất phổ biến: Ngại! Vì phải đầu tư quá nhiều thời gian, công sức!

Vậy chúng ta phải làm gì để học được kỹ năng script? Đầu tiên, có vẻ khá hài hước nhưng muốn học được thì bạn phải chuẩn bị tâm lý sẵn sàng đón nhận và chuẩn bị nhiệt tính lắng nghe! Hầu hết các quản trị viên Windows ban đầu khi muốn học về script đều vấp phải một lỗi là bập vào vấn đề chính ngay. Rồi sau đó phát sinh tâm lý ngại vì bị ngập trước quá nhiều vấn đề không dễ nắm bắt: những khái niệm không độc lập mà ràng buộc và liên quan đến nhau. Chẳng hạn, bạn sẽ không thể thực sự hiểu Thuộc tính (Property) là gì nếu không nắm bắt được Phương thức (Method). Và cả thuộc tính lẫn phương thức chỉ có thể sáng tỏ nếu đặt trong ngữ cảnh của Lớp (Class). Nhưng lớp lại phải diễn giải thành Đối tượng (Object) và mỗi đối tượng đều có thuộc tính, phương thức của nó! Chính xác hơn thì các Tham Chiếu Đối Tượng (Object Reference) vào một Thể hiện (Instance) của Lớp phải có Thuộc tính và Phương thức để bạn có thể đọc và thao tác. Nghe quá rối rắm phải không các bạn!

Chúng ta không thể dành ra tới ba năm để học từng Thuộc tính, Phương thức gắn với mỗi lớp WMI làm việc trong mạng Windows. Hoặc học từng khía cạnh trong cú pháp của ngôn ngữ VBScript chỉ để hoàn toàn thông thạo về nó. Trước đây, suốt những năm đầu của thời đại học, tôi đã phải bỏ ra rất nhiều thời gian để học Fortran, viết hết chương trình này đến chương trình khác, đầu tiên là hiển thị 10, sau đó đến 100, rồi đến một nghìn số Fibonacci, … Vì thế, với thời gian, tiền bạc và sự kiên nhẫn có hạn, cộng thêm các yếu tố khó khăn về bản chất của một số lượng lớn khái niệm trong Windows scripting, những quản trị viên như chúng ta cần phải làm gì để vượt qua được trở ngại trong vấn đề học script và biến nó trở thành thứ hữu ích trong tầm tay?

Khắc phục mọi trở ngại

Rõ ràng là chẳng có câu trả lời màu nhiệm nào cho câu hỏi đó, nhưng một số phương thức dưới đây có thể giúp bạn:

1. Chia nhỏ công việc ra: Chĩa súng lên trời tất nhiên sẽ không thể bắn được con chim dưới đất. Cho nên học ngay những cái chuyên sâu không phải là cách bắt đầu cho một vấn đề. Hãy đặt ra mục tiêu cho từng giai đoạn nhất định, như trong tuần này phải viết được script để truy vấn Active Directory cho cấu trúc OU trong một miền và hiển thị cấu trúc đó trong một trang HTML chẳng hạn. Còn tuần sau học các khái niệm mới hơn, viết một script khác minh hoạ cho chúng. Hãy cố gắng tìm kiếm những script đã có sẵn, đọc hiểu và chỉnh sửa chúng để thực hiện các yêu cầu riêng của mình. Ngoài ra, cho dù không cần hiểu sâu sắc toàn bộ từng dòng, từng lệnh trên script, hãy cố gắng tổng hợp chúng, tạo ra một script kết hợp thực hiện được chức năng mong muốn mà thậm chí bạn không cần hiểu gì về cấu trúc bên trong nó. Đó cũng là một cách học script.

2. Tập trung vào một số vấn đề trọng tâm của kỹ thuật scripting: Một trong các nhược điểm lớn nhất khi bắt

Page 32: Quản lý các mạng Windows dùng Script

đầu học một vấn đề là chúng ta luôn muốn biết mọi thứ của tất cả các khía cạnh vấn đề. Vì thế, khi bắt đầu học về script chúng ta thường cố gắng đọc toàn bộ từ đầu đến cuối những quyển sách viết về ngôn ngữ VBScript. Không cần nói bạn cũng hiểu đó là cách đọc cứng nhắc. Tốt hơn hết hãy tập trung vào một phần cụ thể, như các nhiệm vụ trên mạng TCP/IP scripting (mà chúng ta chú trọng trong loạt bài này) trước. Sau khi nắm vững và thông thạo rồi mới chuyển sang chủ đề khác.

3. Hãy bỏ thời gian để học những khái niệm cơ bản: Tập trung vào một số phần trọng tâm nhất định, nhưng đồng thời bạn cũng phải bỏ thời gian ra học những khái niệm cơ bản của vấn đề. Ví dụ như làm sao để nhập thông tin vào script dùng tham số thời gian chạy. Học một số cú pháp lệnh SELECT đơn giản. Học một số kiểu biến khác nhau. Học một số lớp WMI. Học cách dùng Thuộc tính và Phương thức cho từng lớp … Bạn không cần phải trở thành chuyên gia trong tất cả các lĩnh vực, nhưng cần nắm vững những thứ cơ bản để có thể viết được một script hoàn chỉnh thay vì từng đoạn nhỏ của nó.

4. Hãy ghi các chú thích cho những gì bạn học: Trước kia, suốt một thời gian dài tôi không thu được kết quả gì khi học về script, bởi các khái niệm của nó khá khó hiểu. Như bạn đã nói ở trên, suốt thời đại học tôi được làm quen và học những ngôn ngữ lập trình thủ tục như Fortran. Chúng trở thành kiến thức ăn sâu trong đầu óc khiến tôi rất khó chuyển sang kiểu ngôn ngữ hướng đối tượng khi chúng bắt đầu trở nên phổ biến (cho các admin Windows), và khi VBScript được phát triển từ Visual Basic. Bởi vậy mà suốt thời gian dài tôi lúng túng với Đối tượng, Thuộc tính, Phương thức, Lớp. Chúng tạo ra trở ngại rất lớn cho tôi để có thể học được script. Chắc chắn tôi có thể dùng một script của ai đó viết sẵn và nếu nó đơn giản, tôi có thể thay đổi, chỉnh sửa thêm bớt một chút để biến nó hoạt động theo ý mình. Nhưng MSDN lúc bấy giờ giống như một đất nước xa xôi, lạ lẫm và WMI là một thứ siêu nhiên huyền bí! Và rồi tôi bắt đầu viết các dòng chú thích. Một ngày, tôi viết ra một câu đơn giản: “Thuộc tính là những thứ bạn có thể đọc, còn phương thức là những thứ bạn có thể làm”, đột nhiên mọi thứ trở nên rõ ràng. Tôi hiểu được vấn đề và trở ngại không còn. Các khái niệm khác cũng nhanh chóng được nắm bắt và con đường đến với script không còn xa lạ và quá khó khăn nữa.

5. Thu thập tài liệu hữu ích để tham khảo và sử dụng: Nếu bạn tìm thấy một cuốn sách hay về script, đừng ngần ngại mua nó về đọc và làm bài tập thực hành luôn (nếu có). Ngoài ra, bạn có thể tham khảo thêm nhiều thứ tại TechNet Script Center (sẽ được chú ý ở các phần sau của loạt bài này). Một cách học hữu ích khác là tham gia vào các khoá đào tạo ngắn hạn, các cuộc thảo luận nhóm… Tài liệu về script không hề thiếu, thậm chí rất phong phú nếu bạn thực sự muốn học về nó. Quan trọng là bạn có chịu học và thực hành nó hay không mà thôi.

6. Thực hành, thực hành và thực hành: Muốn học tốt bất kỳ một kỹ năng nào cũng đòi hỏi bạn phải kiên nhẫn. Chỉ có làm đi làm lại nhiều lần mới tạo nên sự hoàn hảo. Sẽ còn nhiều trở ngại trên con đường đi tới thành công và đòi hỏi bạn phải có sự quyết tâm, tính bên bỉ để vượt qua chúng. Thông thường, bạn sẽ học được nhiều hơn từ vài trăm script ngắn thay vì tập viết một vài script dài và tổng hợp. Vì thế, hãy tự đặt ra và hoàn thành các bài tập ngắn thực hiện một công việc nào đấy. Bạn sẽ hiểu vấn đề nhanh hơn.

7. Hãy biến nó trở thành niềm đam mê hay một thú vui: Không biết bạn thế nào nhưng với tôi, việc học thu được hiệu quả cao nhất là khi ở trong tâm trạng vui vẻ. Nếu bạn có một số công việc quản trị liên quan đến script, chắc hẳn lúc ấy bạn mới bắt đầu quan tâm đến việc học nó. Và, nếu bạn thực sự bận rộn (mà mấy khi một quản trị viên mạng được rỗi rãi) thì cách dễ dàng nhất là nhờ một ai đó viết script cho bạn. Nhưng nếu coi script như một thú vui để khám phá, tương tự như môn đánh gôn thì bạn sẽ tiếp cận nó nhanh và làm được nhiều hơn những thứ mình học. Và cũng giống như đánh gôn, chơi cờ, có bạn chơi cùng bao giờ cũng thú vị hơn. Thử xem đồng nghiệp hay những người bạn chuyên gia IT có hứng thú chơi trò scripting không. Nếu có, hãy chia sẻ với họ, việc học sẽ vui và hiệu quả hơn nhiều.

Kết luận

Tôi viết ra bài này bởi nhận thấy nhiều bạn đọc gặp nhiều khó khăn và đã bắt đầu nản chí sau khi đọc xong

Page 33: Quản lý các mạng Windows dùng Script

bốn phần đầu tiên của loạt bài này. Hy vọng những gì viết ra ở đây có thể giúp bạn khắc phục được các trở ngại đó và tiếp tục tìm hiểu sâu hơn về scripting, một kỹ thuật không dễ nắm bắt nhưng rất hữu ích trong công việc quản trị mạng. Ở phần tiếp theo chúng ta sẽ trở lại khám phá lớp Win32_NetworkAdapterConfiguration và xem liệu còn có thể làm gì với nó. Đồng thời, chúng ta cũng sẽ học một số khái niệm mới và ôn lại những thứ đã được giới thiệu ở các phần trước. Chúng ta sẽ học thêm về cú pháp VBScript và xem liệu có thể làm gì để script gọn gàng hơn mà hữu ích hơn. Và sau đó là khám phá một số lớp WMI khác, cùng với một số chủ đề scripting nâng cao như chỉnh sửa thông tin thẩm định, viết mã script từ xa, các đối tượng COM, script WSF… Bên cạnh lý thuyết là một số công cụ hữu ích để viết script, nhưng việc học những khái niệm cơ bản đầu tiên là rất quan trọng. Nó giúp bạn hiểu sâu hơn về từng chủ đề và do đó tự tin hơn với các kỹ năng của mình. Tôi cũng sẽ cố gắng đưa ra cho các bạn một số bài tập để hoàn thiện script riêng bạn đã xây dựng. Và nếu thực sự muốn học về script, bạn cần phải tự làm chúng, đừng chỉ nhìn rồi nói: “Tôi có thể làm được!”. Thực hành nhiều sẽ giúp bạn viết được một script hoàn hảo. Vì thế, đừng quên nhiệm vụ quan trọng nhất là thực hành và thực hành.

Quản lý các mạng Windows dùng script - Phần 6: Những bước đầu tiên về scripting remote

Tìm hiểu kỹ thuật scripting remote (viết kịch bản chạy trên các máy từ xa) sử dụng lớp WMI Win32_NetworkAdapterConfiguration đã được giới thiệu ở phần trước.

Trở lại với script ChangeIPAddress.vbs mà chúng ta đã phát triển ở các phần trước để thay đổi địa chỉ IP của một bộ điều hợp mạng:

Option ExplicitDim objWMIServiceDim objNetAdapterDim strComputer     Dim strAddress     Dim arrIPAddressDim arrSubnetMaskDim colNetAdaptersDim errEnableStatic

If WScript.Arguments.Count = 0 Then     Wscript.Echo "Usage: ChangeIPAddress.vbs new_IP_address"     WScript.QuitEnd 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ú ý là các chú thích đã được loại bỏ và phần mã ở cuối hiển thị kết quả.

Điểm qua lại một chút về hoạt động của script này:

Page 34: Quản lý các mạng Windows dùng Script

1. Kết nối tới namespace root\cimv2 trên máy cục bộ. 2. Sử dụng một lệnh SELECT để trả về tập hợp các cấu hình bộ điều hợp mạng có đường bao TCP/IP và

được phép sử dụng. 3. Thay đổi địa chỉ IP của bộ điều hợp thành giá trị được mô tả trong tham số dòng lệnh.

Chúng ta đã ghi lại script này trong thư mục C:\localtest trên một máy Windows XP có địa chỉ IP tĩnh là 172.16.11.43. Sau đó, mở của sổ dòng lệnh Command Prompt với vai trò admin trên máy và sử dụng script này để thay đổi địa chỉ IP của máy thành 172.16.11.54:

C:\locatest>ipconfig

Windows IP Configuration

 

Ethernet adapter Local Area Connection:

        Connection-specific DNS Suffix  . :        IP Address. . . . . . . . . . . . : 172.16.11.43        Subnet Mask . . . . . . . . . . . : 255.255.255.0        Default Gateway . . . . . . . . . : 172.16.11.1

C:\locatest>ChangeIPAddress.vbs 172.16.11.54Microsoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

 

C:\locatest>ipconfig

Windows IP Configuration

 

Ethernet adapter Local Area Connection:

        Connection-specific DNS Suffix  . :        IP Address. . . . . . . . . . . . : 172.16.11.54        Subnet Mask . . . . . . . . . . . : 255.255.255.0        Default Gateway . . . . . . . . . : 172.16.11.1

C:\locatest>

Chú ý 1: Nên nhớ rằng, để thay đổi địa chỉ IP trên máy Windows XP đòi hỏi phải sử dụng đặc quyền quản trị cục bộ. Do đó, nếu bạn hiện đang đăng nhập vào máy với vai trò người dùng miền bình thường, cần phải mở cửa sổ Command Prompt, sau đó gõ lệnh: runas /user:administrator cmd.exe để mở một cửa sổ Command Prompt thứ hai chạy trong ngữ cảnh của vai trò quản trị cục bộ và cuối cùng là chạy script từ cửa sổ Command Prompt thứ hai này.

Nhưng nếu muốn chạy script trên một máy và sử dụng nó để thay đổi địa chỉ IP của một máy khác thì sao? Nói cách khác, chúng ta muốn chạy script từ xa trên một máy Windows XP ở xa thì phải làm như thế nào?

Cố gắng đầu tiên

Page 35: Quản lý các mạng Windows dùng Script

Chúng ta hãy bắt đầu bằng việc đăng nhập vào một trạm làm việc admin xp.contoso.com, sử dụng thông tin thẩm định của một tài khoản admin có tên là Mary Jones. Chúng ta cần thực hiện điều này vì các admin miền có đặc quyền quản trị cục bộ trên tất cả các máy trong miền. Do đó, khi chạy script từ trạm admin trên một máy từ xa, script sẽ hoạt động.

Bây giờ chúng ta đã có script ChangeIPAddress.vbs trong thư mục C:\tools ở trạm admin xp.contoso.com. Mở cửa sổ lệnh Command Prompt trên máy này và gõ vào hai dòng sau:

C:\Documents and Settings\mjones>cd \toolsC:\tools>notepad ChangeIPAddress.vbs

Script được mở trong Notepad, thay đổi dòng bên dưới:

strComputer = "."

thành:

strComputer = "xp2 "

Sau đó vào File/Save để ghi lại thay đổi và đóng Notepad. Bây giờ, chạy script:

C:\tools>ChangeIPAddress.vbs 172.16.11.65Microsoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

C:\tools\ChangeIPAddress.vbs(20, 1) Microsoft VBScript runtime error: The remote server machine does not exist or is unavailable: 'GetObject'

 

C:\tools>

Chú ý là sẽ phải mất một lúc trước khi thông báo lỗi ở trên xuất hiện. Nhưng như vậy script có làm việc không? Nếu đăng nhập vào máy từ xa xp2.contoso.com, mở cửa sổ Command Prompt và gõ ipconfig, kết quả thu được sẽ là:

C:\locatest>ipconfig

Windows IP Configuration

 

Ethernet adapter Local Area Connection:

        Connection-specific DNS Suffix  . :        IP Address. . . . . . . . . . . . : 172.16.11.43        Subnet Mask . . . . . . . . . . . : 255.255.255.0        Default Gateway . . . . . . . . . : 172.16.11.1

C:\locatest>

Bạn có thể thấy địa chỉ của máy vẫn là 172.16.11.43. Tức là script này không hoạt động.

Vậy, sai ở điểm nào? Thông báo lỗi chỉ ra rằng có một vấn đề với dòng 20 của script. Dòng 20 có dạng:

Page 36: Quản lý các mạng Windows dùng Script

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Dường như script không thể kết nối với dịch vụ WMI trên một máy từ xa. Nguyên nhân là do đâu?

Cố gắng thứ hai

Chúng ta có thể làm một điều gì đó với Windows Firewall trên máy từ xa.

Nên nhớ rằng, Windows XP SP2 có một tường lửa sẽ loại bỏ hầu hết mọi lưu lượng đến ngoại trừ lưu lượng được cấu hình riêng. Cách đơn giản nhất để kiểm tra điều này là tắt Windows Firewall trên các máy tính đích. Đăng nhập vào xp2.contoso.com với vai trò admin, mở ứng dụng Windows Firewall trong Control Panel và chọn thiết lập Off trên tab General.

Bây giờ chạy lại script từ trạm admin:

C:\tools>ChangeIPAddress.vbs 172.16.11.65Microsoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

C:\tools\ChangeIPAddress.vbs(23, 6) SWbemObjectEx: The remote procedure call failed.

 

C:\tools>

Lại một lỗi khác, và lại phải mất rất lâu thông báo lỗi này mới xuất hiện. Nhưng ít nhất thì đó là một lỗi khác và được ghi nhận là ở dòng 23:

     errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)

Bây giờ, gõ lệnh ipconfig ở cửa sổ Command Prompt trên máy từ xa, ta có kết quả sau:

C:\locatest>ipconfig

Windows IP Configuration

 

Ethernet adapter Local Area Connection:

        Connection-specific DNS Suffix  . :        IP Address. . . . . . . . . . . . : 172.16.11.65        Subnet Mask . . . . . . . . . . . : 255.255.255.0        Default Gateway . . . . . . . . . : 172.16.11.1

C:\locatest>

Có vẻ như script đã hoạt động! Nhưng vẫn để lại hai vấn đề:

1. Chúng ta không muốn tắt chức năng của Windows Firewall trên các máy từ xa khi chạy script này trên chúng. Vậy, liệu có cần phải thiết lập một ngoại lệ để các máy này cho phép chạy script từ xa trong khi vẫn mở Windows Firewall.

2. Còn về lỗi RPC ở trên? Script hoạt động nhưng vẫn trả ra một lỗi. Tại sao lại như vậy?

Page 37: Quản lý các mạng Windows dùng Script

Ngoại lệ cho scripting từ xa

Mở lại Windows Firewall trên máy từ xa, script sẽ không chạy được. Bây giờ, từ cửa sổ Command Prompt mức admin trên máy, gõ lệnh gpedit.msc để mở Local Group Policy và đặt thiết lập chính sách sau (xem Hình 1):

Computer Configuration\Administrative Templates\Network\Network Connections\Domain Profile\Windows Firewall: Allow remote administration exception

Hình 1: Thiết lập chính sách Windows Firewall để cho phép quản trị từ xa

Kích đúp lên thiết lập chính sách này và cho phép nó trên mạng con cục bộ (Hình 2). Nhớ là trạm admin phải nằm trên cùng một subnet với máy tính đích.

Page 38: Quản lý các mạng Windows dùng Script

Hình 2: Cho phép ngoại lệ quản trị từ xa

Chú ý 2: Tất nhiên, có thể bạn muốn thực hiện điều này khác đi một chút và cấu hình thiết lập chính sách trong một Group Policy Object (GPO) miền thay vì cục bộ. Nhưng nếu như vậy thì bạn không thể cho phép ngoại lệ này trên máy cục bộ để chạy tường lửa cùng với script. 

Bây giờ, chạy lại script từ trạm admin và cố gắng thay đổi địa chỉ IP của máy từ xa từ 172.16.11.65 thành 172.16.11.66:

C:\tools>ChangeIPAddress.vbs 172.16.11.66Microsoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

C:\tools\ChangeIPAddress.vbs(23, 6) SWbemObjectEx: The remote procedure call failed.

 

C:\tools>

Lại một lỗi như trên xuất hiện, nhưng khi gõ lệnh ipconfig vào cửa sổ Command Prompt trên máy từ xa, ta có kết quả như sau:

C:\locatest>ipconfig

Windows IP Configuration

 

Ethernet adapter Local Area Connection:

        Connection-specific DNS Suffix  . :        IP Address. . . . . . . . . . . . : 172.16.11.66

Page 39: Quản lý các mạng Windows dùng Script

        Subnet Mask . . . . . . . . . . . : 255.255.255.0        Default Gateway . . . . . . . . . : 172.16.11.1

C:\locatest>

Nó đã làm việc! Như vậy, chúng ta có thể mở Windows Firewall trên máy từ xa đồng thời dùng Group Policy để mở một ngoại lệ cho quản trị từ xa trong tường lửa và thay đổi từ xa địa chỉ IP của máy bằng cách chạy script từ một trạm admin.

Chúng ta đã giải quyết được vấn đề thứ nhất, còn vấn đề thứ hai thì sao?

Bí mật bao giờ cũng có sức hấp dẫn riêng của nó. Vì thế, hãy tạm thời để vấn đề thứ hai sang phần sau của bài.

Quản lý các mạng Windows dùng script - Phần 7: Xử lý sự cố lỗi

Trong bài viết trước chúng ta đã dùng đến kịch bản ChangeIPAddress.vbs được phát triển trước đó và đã sử dụng nó để thay đổi địa chỉ IP trên máy tính từ xa. Đây là những gì mà chúng ta đã thay đổi kịch bản:

Option ExplicitDim objWMIServiceDim objNetAdapterDim strComputer     Dim strAddress     Dim arrIPAddressDim arrSubnetMaskDim colNetAdaptersDim errEnableStatic

If WScript.Arguments.Count = 0 Then     Wscript.Echo "Usage: ChangeIPAddress.vbs new_IP_address"     WScript.QuitEnd If

strComputer = "xp2"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

Dòng:

strComputer = "xp2"

cho chúng ta biết rằng máy tính được tích hợp bởi kịch bản có tên XP2. Máy tính điều khiển xa XP2 ban đầu có địa chỉ IP là 172.16.11.43.

Page 40: Quản lý các mạng Windows dùng Script

Bây giờ khi chúng ta chạy kịch bản này bằng cách đánh ChangeIPAddress.vbs 172.16.11.65 từ một máy trạm quản lý có tên là XP, những thứ xảy ra được đưa ra dưới đây:

1. Kịch bản đã hoạt động. Ví dụ địa chỉ của XP2 đã thay đổi từ 172.16.11.43 thành 172.16.11.65.

2. Kịch bản cần đến nhiều thời gian để thực thi

3. Kịch bản trả lại lỗi dưới đây: C:\tools\ChangeIPAddress.vbs(23, 6) SWbemObjectEx: The remote procedure call failed.

Làm thế nào chúng ta có thể giải quyết được các kết quả đó?

Giải pháp dễ dàng

Một thứ chúng ta có thể thực hiện là nói rằng “Hãy bỏ qua lỗi”. Đó là những gì được nói với phương pháp này. Sau tất cả, bất kỳ quản trị viên trong thế giới thực nào cũng biết rằng CNTT không phải là một khoa học đúng về mọi chi tiết và chúng thường kết thúc bằng việc áp dụng “cách giải quyết khác” đối với các vấn đề nảy sinh khi không có những giải pháp đúng cho chúng.

Vì vậy làm thế nào chúng ta có thể bỏ qua lỗi? Hãy thêm dòng dưới đây vào gần vị trí bắt đầu của phần đầu (header):

On Error Resume Next

Hay nói cách khác, phần đầu (header) của chúng ta sẽ như sau:

Option Explicit On Error Resume Next Dim objWMIService ...

Bây giờ chúng ta không xem lỗi, và kịch bản của chúng ta làm việc. Tuy nhiên nó vẫn cần đến nhiều thời gian để thực thi, thực tế có thể cần đến vài phút. Vậy cái gì sẽ tiếp diễn?

Xử lý sự cố thông báo lỗi

Các thông báo lỗi đôi khi khá khó hiểu và điều này là một trong những vấn đề đáng quan tâm. Đây là một thông báo lỗi:

SWbemObjectEx: The remote procedure call failed.

Và đây là dòng mã tạo ra nó:

errEnableStatic = objNetAdapter.EnableStatic(arrIPAddress, arrSubnetMask)

Dòng mã này làm việc (ví dụ địa chỉ IP bị thay đổi trên máy tính mục tiêu) nhưng sau đó nó đưa ra một thông báo lỗi. Tại sao lại như vậy? Chúng ta hãy bắt đầu bằng cách tìm hiểu SwebObjectEx có ý nghĩa gì. Tìm kiếm nhanh trong MSDN có thể cho thấy (http://msdn2.microsoft.com/en-us/library/aa393259.aspx):

Extends the functionality of SWbemObject. This object adds the Refresh method for SWbemRefresher objects.

Page 41: Quản lý các mạng Windows dùng Script

(Mở rộng chức năng của SWbemObject. Đối tượng này bổ sung phương pháp Refresh cho các đối tượng SwbemRefresher)

Vì vậy SwbemObjectEx cơ bản chỉ bổ sung thêm chức năng cho SWbemObject. Vậy SwbemObject là gì?

Contains and manipulates a single WMI object class or instance. (Gồm một đối tượng WMI hoặc một sự kiện)

Điều đó có nghĩa gì? Trang này cho chúng ta nhiều thông tin nhưng nó không thích hợp. Mặc dù vậy trong các trường hợp, SwbemObject (SWbemObjectEx) là tất cả những gì bạn quản lý hay truy vấn trong WMI. Trong kịch bản của chúng ta, chúng ta đang truy vấn lớp Win32_NetworkAdapterConfiguration và trả về một bộ sưu tập các đối tượng gọi là colNetAdapter thể hiện các adapter mạng trên máy tính. Vì vậy SWbemObjectEx (hoặc SWbemObject) đã đề cập đến trong thông báo lỗi này làm đơn giản hóa đối tượng đang thể hiện bản thân adapter mạng, ví dụ như objNetAdapter. Vậy tại sao objNetAdapter tạo ra lỗi.

Dẫu sao đây cũng dường như trở thành vấn đề. Theo một trong những chuyên gia có uy tín, có thể một thành phần nào đó có trong hotfix cho Windows XP bị thay đổi cách mà lệnh gọi trả về được tạo và được đệ trình khi câu lệnh gây ra lỗi được thực thi. Thông thường nếu gọi phương pháp EnableStatic của một đối tượng được thuyết minh bằng một ví dụ của lớp Win32_NetworkAdapterConfiguration hoàn toàn thành công nó sẽ trả về 0, có nghĩa là không có lỗi. Còn nếu nó trả về 1 thì điều đó có nghĩa cần phải khởi động lại. Rõ ràng với Windows XP sẽ không cần phải khởi động lại khi bạn thay đổi địa chỉ IP trên adapter mạng. Nếu với một vài lý do, một hotfix có thể thay đổi gì đó trong WMI hoặc thành phần khác để Windows không khởi động lại trước khi địa chỉ mới được thay thế trên máy mục tiêu, điều này có thể tạo ra một lỗi vì cấu hình adapter mạng trên máy rơi vào trạng thái không rõ ràng cho tới khi máy tính này được khởi động lại. Tuy nhiên khi kịch bản vẫn đang chạy trên máy trạm quản trị, khi cấu hình adapter mạng của máy tính mục tiêu đang ở trạng thái không xác rõ ràng thì kết nối RPC giữa hai máy tính là rất tồi trước khi kịch bản này kết thúc. Chính vì vậy sẽ xuất hiện lỗi ở đây.

Chí ít đó cũng là câu trả lời tốt nhất mà chúng tôi có được cho vấn đề này, và chúng tôi vẫn tiếp tục nghiên cứu tỉ mỉ. Tuy nhiên hãy xem nếu chúng ta có thể xác nhận vì một lý do nào đó mà vấn đề này được giải quyết, ví dụ lỗi đó chỉ liên quan với phương pháp EnableStatic của Win32_NetworkAdapterConfiguration. Việc gì sẽ xảy ra nếu chúng ta cố gắng viết một kịch bản khác để thực hiện một việc gì đó khác với adapter mạng trên máy tính mục tiêu thay vì thay đổi địa chỉ IP của nó? Ví dụ, làm cách nào để thay đổi được cổng mặc định thay vì địa chỉ IP trên máy tính mục tiêu? Nếu điều đó được thực hiện thì ít nhất chúng ta cũng có thể kết nối thành công từ máy trạm quản trị đến máy tính từ xa và gọi phương pháp WMI để thay đổi thiết lập mạng trên nó.

Thay đổi cổng mặc định

Ở phần này chung tôi khuyên bạn nên quay lại đọc một chút phần 4 của loạt bài này, ở đó chúng tôi đã giới thiệu cho bạn cách sử dụng MSDN để học cách sử dụng các thuộc tính và phương pháp của Win32_NetworkAdapterConfiguration. Chúng tôi cho rằng bằng cách làm như vậy bạn có thể tự viết một kịch bản như vậy. Hãy thử nó!

TẠM NGƯNG

Khi bạn đã cố gắng viết kịch bản cho riêng mình, đôi khi nó có thể làm việc, đôi khi không làm việc. Nếu nó không làm việc, hãy thực hiện các bước dưới đây:

1. Đầu tiên vào trang MSDN của Win32_NetworkAdapterConfiguration class.

Page 42: Quản lý các mạng Windows dùng Script

2. Tìm trên trang này phương pháp phải thực hiện để thay đổi cổng trên adapter mạng. Kiểm tra nhanh trong trang sẽ cho bạn điều này:

SetGateways - Specifies a list of gateways for routing packets destined for a different subnet than the one this adapter is connected to. (SetGateways – một danh sách cổng dành cho việc định tuyến các gói đã được trù định trước đối với subnet khác so với subnet mà adapter này được kết nối đến)

Đó chính là những gì chúng ta muốn, vì vậy kích chuột vào SetGateways để mở trang SetGateways Method của Win32_NetworkAdapterConfiguration Class

3. Trên trang SetGateways Method này bạn sẽ thấy giải thích này:

The SetGateways WMI class method specifies a list of gateways for routing packets to a subnet that is different from the subnet that the network adapter is connected to. This method only works when the Network Interface Card (NIC) is in the static IP mode. (Phương pháp lớp SetGateways WMI chỉ định một danh sách cổng dành cho việc định tuyến các gói cho một mạng con khác đối với mạng con mà adapter mạng được kết nối đến. Phương pháp này chỉ làm việc khi Network Interface Card (NIC) ở chế độ IP tĩnh)

Chính vì vậy bạn đã học được rằng máy tính mục tiêu phải có địa chỉ tĩnh trước khi bạn gọi phương pháp này. Đọc kỹ hơn bạn có thể tìm thấy cú pháp cho việc gọi phương pháp này như dưới đây:

SetGateways(A,B)

Ở đây A là biến chuỗi gồm địa chỉ IP cho cổng, B là một giá trị nguyên từ 1 đến 9999 chỉ định tham số đó. Bây giờ bạn phải có đủ thông tin để viết kịch bản. Cách đơn giản nhất là bắt đầu với kịch bản ChangeIPAddress.vbs gốc của chúng ta có trong phần 2 và thay đổi nó một chút cho tới khi chúng ta có được một kịch bản mới như dưới đây:

'=========================' NAME: ChangeGateway.vbs''AUTHOR: Mitch Tulloch'DATE: February 2007''ARGUMENTS:'1. gateway_address'2. metric'=========================-

Option Explicit

Dim objWMIServiceDim objNetAdapterDim strComputer Dim strGateway Dim arrGatewayDim intMetricDim arrMetricDim colNetAdaptersDim errGateway

'Check for missing arguments

Page 43: Quản lý các mạng Windows dùng Script

If WScript.Arguments.Count = 0 Then     Wscript.Echo "Usage: ChangeGateway.vbs gateway_address metric"     WScript.QuitEnd If

strComputer = "xp2"strGateway = Wscript.Arguments.Item(0)arrGateway = Array(strGateway)intMetric = Wscript.Arguments.Item(1)arrMetric = Array(intMetric)Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")Set colNetAdapters = objWMIService.ExecQuery("Select * from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")For Each objNetAdapter in colNetAdapters     errGateway = objNetAdapter.SetGateways(arrGateway, arrMetric)Next

'Display result or error code

If errGateway=0 Then     Wscript.Echo "Adapter's gateway has been successfully changed to " & strGatewayElse     Wscript.Echo "Changing the adapter's gateway was not successful. Error code " & errGatewayEnd If

Copy đoạn kịch bản này vào Notepad (trong chế độ Word Wrap đã bị bỏ) và lưu lại với tên ChangeGateway.vbs. Giờ hãy kiểm tra nó. Truy cập vào máy từ xa XP2, mở cửa sổ lệnh nhập vào lệnh ipconfig /all và kết quả như sau:

C:\>ipconfig /all

Windows IP Configuration

        Host Name . . . . . . . . . . . . : XP2        Primary Dns Suffix  . . . . . . . : contoso.com        Node Type . . . . . . . . . . . . : Unknown        IP Routing Enabled. . . . . . . . : No        WINS Proxy Enabled. . . . . . . . : No

Ethernet adapter Local Area Connection:

        Connection-specific DNS Suffix  . :        Description . . . . . . . . . . . : Intel 21140-Based PCI Fast EthernetAdapter (Generic)        Physical Address. . . . . . . . . : 00-03-FF-21-88-8C        Dhcp Enabled. . . . . . . . . . . : No        IP Address. . . . . . . . . . . . : 172.16.11.80        Subnet Mask . . . . . . . . . . . : 255.255.255.0        Default Gateway . . . . . . . . . : 172.16.11.1

C:\>

Bây giờ trên máy trạm quản trị XP, bạn mở cửa sổ lệnh và chạy kịch bản mới này như dưới đây:

C:\tools>ChangeGateway.vbs 172.16.11.2 5Microsoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

Page 44: Quản lý các mạng Windows dùng Script

Adapter's gateway has been successfully changed to 172.16.11.2

C:\tools>

Kịch bản này cần đến khoảng 5 giây để kết thúc, không có lỗi nào xuất hiện (Lưu ý rằng ở đây chúng tôi đã bỏ qua On Error Resume Next từ header của kịch bản đã đưa ra vì chúng tôi muốn quan sát bất kỳ lỗi nào nếu chúng xuất hiện)

Hãy quay trở lại máy tính từ xa XP2 và chạy ipconfig /all một lần nữa:

C:\>ipconfig /all

Windows IP Configuration

        Host Name . . . . . . . . . . . . : XP2        Primary Dns Suffix  . . . . . . . : contoso.com        Node Type . . . . . . . . . . . . : Unknown        IP Routing Enabled. . . . . . . . : No        WINS Proxy Enabled. . . . . . . . : No

Ethernet adapter Local Area Connection:

        Connection-specific DNS Suffix  . :        Description . . . . . . . . . . . : Intel 21140-Based PCI Fast EthernetAdapter (Generic)        Physical Address. . . . . . . . . : 00-03-FF-21-88-8C        Dhcp Enabled. . . . . . . . . . . : No        IP Address. . . . . . . . . . . . : 172.16.11.80        Subnet Mask . . . . . . . . . . . : 255.255.255.0        Default Gateway . . . . . . . . . : 172.16.11.2

C:\>

Nó đã làm việc. Không có lỗi nào xuất hiện – chúng ta đã chạy một kịch bản từ xa đối với một máy tính khác và nó đã thay đổi cổng mặc định của máy tính mục tiêu.

Chúng ta có thể kiểm tra xem tham số đo có bị thay đổi hay không? Lệnh ipconfig không hiển thị thông tin này nhưng chúng ta có thể sử dụng netsh để có được điều này như dưới đây:

C:\>netsh interface ip show address

Configuration for interface "Local Area Connection"    DHCP enabled:                         No    IP Address:                           172.16.11.80    SubnetMask:                           255.255.255.0    Default Gateway:                      172.16.11.2    GatewayMetric:                        5    InterfaceMetric:                      0

C:\>

Đây chính là kết quả cần thấy!

Page 45: Quản lý các mạng Windows dùng Script

Quản trị mạng Windows bằng Script - Phần 8: Xử lý lỗi kịch bản điều khiển từ xa bằng Network Monitor 3.0

Trong phần 7, chúng ta đã bắt đầu xử lý sự cố lỗi xuất hiện khi cố gắng thay đổi từ xa địa chỉ IP trên máy tính XP bằng kịch bản ChangeIPAddress.vbs được phát triển từ trước. Lỗi đó là:

SWbemObjectEx: The remote procedure call failed

Trong phần trước chúng tôi đã đề cập rằng chúng tôi đã liên hệ với một số chuyên gia có uy tín trong việc xử lý lỗi này, và câu trả lời tốt nhất nhận được đó là hotfix có thể làm hỏng chức năng WMI và kết quả là kịch bản này đã làm việc nhưng kèm với nó có một lỗi.

Một độc giả đã liên hệ với tôi với lời nhận xét dưới đây:

Theo tôi đây không phải lỗi trong hotfix. Hãy chú ý rằng bạn đang thay đổi địa chỉ IP của XP2. Thủ tục gọi từ xa đã thất bại vì nó mất kết nối với XP2 trên địa chỉ gốc(172.16.11.43). Sau đó nó phụ thuộc vào thời gian (khoảng 1 phút) để tìm kiếm cho XP2 địa chỉ IP mới (172.16.11.65) trước khi bỏ địa chỉ cũ. Hãy hình dung bạn chỉ thâm nhập vào một máy chủ như quản trị viên và thay đổi địa chỉ IP của máy chủ. Bạn sẽ mất kết nối? Nó sẽ treo trong chốc lát. Nhưng việc thay đổi cổng mặc định trên máy chủ sẽ không ngắt kết nối đang tồn tại (thừa nhận bạn thực hiện điều này từ cùng một subnet). Nếu cố gắng thay đổi thiết lập cổng mặc định từ một vị trí ở xa thì bạn phải chịu bị giữ chậm.

Vậy làm thế nào để chúng ta có thể kiểm tra lời giải thích này?

Sử dụng Network Monitor 3.0

Microsoft gần đây đã phát hành một phiên bản Network Monitor mới, công cụ này là một phần của Microsoft Systems Management Server. Network Monitor 3.0 có vài cải tiến so với phiên bản trước, cụ thể là:

Cải thiện giao diện người dùng hiển thị các khung khi chúng đang hoạt động theo thời gian thực. Nhiều phiên capture đồng thời và capture đồng thời trên nhiều adapter mạng. Khả năng hiển thị “cuộc đàm thoại” mạng, nghĩa là các session protocol cụ thể. Hỗ trợ cho Vista, Windows XP và Windows Server 2003 (cả 32 bit và 64 bit). Panel lọc mới cho phép bạn sử dụng các bộ lọc chỉ định.

Chúng tôi đang sử dụng NM3 để bắt dấu vết từ máy tính trên đó đang chạy kịch bản ChangeIPAddress.vbs. Dưới đây là phần thiết lập để kiểm tra:

Máy trạm quản trị viên Tên: test124.test.com Địa chỉ IP: 172.16.11.124 (tĩnh)

Máy đích Tên: test125.test.com Địa chỉ IP: 172.16.11.125 (tĩnh)

Bộ điều khiển miền Tên: dc181.test.com Địa chỉ IP: 172.16.11.181

Tuy nhiên trước khi chạy ChangeIPAddress.vbs trên test124 để thay đổi địa chỉ IP của test125, hãy quan sát

Page 46: Quản lý các mạng Windows dùng Script

NM3 một chút.

Khi bạn khởi chạy NM3, nó sẽ có giao diện như hình 1:

Hình 1: Cửa sổ Network Monitor 3.0 khi được mở

Trước khi tiếp tục, hãy chọn hộp kiểm Enable Conversations để chúng ta có thể quan sát được kiểu session protocol xuất hiện trong suốt quá trình dò theo.

Bây giờ kích chuột vào tab New Capture. Điều này cho phép mở được một tab mới với tên Capture1 có thể sử dụng để tạo dấu vết mạng.

Page 47: Quản lý các mạng Windows dùng Script

Hình 2: Mở một tab capture mới

Hãy kiểm tra NM3 một cách đơn giản. Kích chuột vào nút Play để bắt đầu một capture, sau đó từ máy tính test124 mở một cửa sổ lệnh và nhập vào ping 172.16.11.125 nghĩa là chúng ta đang ping từ test125 đến test124. Kết quả được cho như hình 3 dưới đây:

Page 48: Quản lý các mạng Windows dùng Script

Hình 3: Vết tích của ping 172.16.11.125

Đây là những gì chúng ta mong đợi: hai gói ARP (một yêu cầu ARP và theo sau là một đáp ứng ARP) và một loạt các gói ICMP (các thông điệp Echo Request được cho sau bởi các thông điệp Echo Reply). Nếu bạn biết kết nối mạng TCP/IP cơ bản thì điều này hoàn toàn dễ dàng có thể hiểu được.

Hãy quan sát tình huống “đàm thoại” đã xảy ra trong hình 4. Mở nút My Traffic để hiển thị điều đó:

Page 49: Quản lý các mạng Windows dùng Script

Hình 4: Các “cuộc đàm thoại”

Lưu ý rằng có hai cuộc “đàm thoại” đã xuất hiện: ARP và IPv4 (ICMP).

Bây giờ chúng ta hãy chọn gói ARP Request và quan sát bên trong nó (hình 5):

Page 50: Quản lý các mạng Windows dùng Script

Hình 5: Việc kiểm tra một gói

Chúng ta đã được giới thiệu sơ bộ về NM3, bây giờ hãy sử dụng nó để xử lý một số lỗi xảy ra.

Lần vết

Chúng tôi bắt đầu bằng việc khởi động lại cả hai máy trạm và xóa bộ nhớ cache (ARP, NDS,…), sau đó mở cửa sổ lệnh trên máy tính test124, đánh ChangeIPAddress.vbs 172.16.11.144 để thay đổi địa chỉ IP của máy tính test125 từ 172.16.11.125 thành 172.16.11.144. Hình 6 dưới đây là những kết quả thu được:

Page 51: Quản lý các mạng Windows dùng Script

Hình 6: Các kết quả thu được khi chạy ChangeIPAddress.vbs 172.16.11.144

Hình 6 là tổng quan những gì đã xảy ra. Giữ lại 90 giây muộn nhất và đã có 274 khung được giữ. Thông báo lỗi xuất hiện ở xung quanh khung 241 và cửa sổ lệnh trả về tại khung 274. Có rất nhiều lưu lượng để chúng ta có thể phân tích! Hãy nhìn vào hình 6 ở trên, chúng ta có thể bắt đầu phân tích nó:

Các khung 3-4 hiển thị tên TEST125 đang tồn tại dưới địa chỉ IP là 172.16.11.125 bằng DNS. Các khung 5-6 hiển thị địa chỉ IP 172.16.11.125 đang tồn tại bên trong địa chỉ MAC bằng ARP. Các khung 7-9 thể hiện thủ tục ‘bắt tay’ TCP (SYN, SYN/ACK, ACK) xuất hiện giữa hai máy tính

test124 và test125. Các khung 10-11 thể hiện ràng buộc RPC đang tồn tại được thành lập giữa hai máy tính. Các khung 12-13 thể hiện DCOM đang tồn tại được sử dụng trên RCP (WMI sử dụng DCOM để ‘bắt

tay’ các cuộc gọi từ xa).

Quan sát sẽ không thể thấy được tất cả 274 khung trong hình vẽ, vì vậy chúng tôi đã copy thông tin về tất cả khung vào một file văn bản. Bạn có thể kích chuột vào đây để xem trang thông tin về tất cả các khung khi chạy ChangeIPAddress.vbs.

Khi xử lý sự cố thông thường bạn phải bắt đầu với những gì bạn biết chứ không phải là những gì không hiểu.

Page 52: Quản lý các mạng Windows dùng Script

Với lưu ý đó chúng tôi hiểu rằng kịch bản khác (ChangeGateway.vbs) mà chúng tôi đã phát triển trong bài viết trước đã làm việc mà không tạo ra bất kỳ một thông báo lỗi nào. Vì vậy trước khi xem xét kỹ trong file ChangeIPAddress.txt, hãy khởi động lại các máy trạm của bạn và thực hiện một capture khác, khi đó nó sẽ thể hiện kết quả chạy lệnh ChangeGateway.vbs 172.16.11.2 1 trên test124 để thay đổi cổng mặc định của test125 từ 172.16.11.1 thành 172.16.11.2 (chỉ ra tham số đo bằng 1). Đây là những gì lần capture thứ hai thể hiện (hình 7):

Hình 7: Kết quả chạy ChangeGateway.vbs 172.16.11.2 1

Lúc này chỉ có 217 khung để phân tích (!) và bạn có thể vào đây để xem tóm tắt toàn bộ các khung.

Phân tích của capture cho ChangeGateway.vbs

Bây giờ chúng ta hãy thử và phân tích lần capture thứ hai này (làm việc mà không phát sinh lỗi) bằng cách chia file tóm tắt các khung thành từng đoạn, đây là một trong số các đoạn đó:

1 0.000000 NetmonFilter NetmonFilter: Updated Capture Filter: None 2 0.000000 NetworkInfo NetworkInfo: Network info for TEST124, Network Adapter Count = 1

Page 53: Quản lý các mạng Windows dùng Script

Chỉ là NM3 header – bỏ qua

3 0.000000 {DNS:3, UDP:2, IPv4:1} 172.16.11.124 dc181.test.local DNS DNS: QueryId = 0x4275, QUERY (Standard query), Query for 124.11.16.172.in-addr.arpa of type SOA on class Internet 4 1.281250 {ARP:4} 172.16.11.181 172.16.11.1 ARP ARP: Request, 172.16.11.181 asks for 172.16.11.1 5 1.890625 {DNS:6, UDP:5, IPv4:1} 172.16.11.124 dc181.test.local DNS DNS: QueryId = 0xEB6E, QUERY (Standard query), Query for test125.test.local of type Host Addr on class Internet 6 1.890625 {DNS:6, UDP:5, IPv4:1} dc181.test.local 172.16.11.124 DNS DNS: QueryId = 0xEB6E, QUERY (Standard query), Response - Success 7 1.906250 {ARP:7} 172.16.11.124 172.16.11.125 ARP ARP: Request, 172.16.11.124 asks for 172.16.11.125 8 1.906250 {ARP:7} 172.16.11.125 172.16.11.124 ARP ARP: Response, 172.16.11.125 at 00-11-D8-E3-EC-84

Tên và địa chỉ (DNS và ARP)

9 1.906250 {TCP:9, IPv4:8} 172.16.11.124 test125.test.local TCP TCP: Flags=.S......, SrcPort=1069, DstPort=DCE endpoint resolution(135), Len=0, Seq=1441244938, Ack=0, Win=65535 (scale factor 0) = 65535 10 1.906250 {TCP:9, IPv4:8} test125.test.local 172.16.11.124 TCP TCP: Flags=.S..A..., SrcPort=DCE endpoint resolution(135), DstPort=1069, Len=0, Seq=871910569, Ack=1441244939, Win=65535 (scale factor 0) = 65535 11 1.906250 {TCP:9, IPv4:8} 172.16.11.124 test125.test.local TCP TCP: Flags=....A..., SrcPort=1069, DstPort=DCE endpoint resolution(135), Len=0, Seq=1441244939, Ack=871910570, Win=65535 (scale factor 0) = 65535

Test124 đã thành lập một kết nối TVP với test125.

12 1.906250 {MSRPC:10, TCP:9, IPv4:8} 172.16.11.124 test125.test.local MSRPC MSRPC: c/o Bind: UUID{99FCFEC4-5260-101B-BBCB-00AA0021347A} DCOM-IObjectExporter Call=0x1 Assoc Grp=0x0 Xmit=0x16D0 Recv=0x16D0 13 1.906250 {MSRPC:10, TCP:9, IPv4:8} test125.test.local 172.16.11.124 MSRPC MSRPC: c/o Bind Ack: Call=0x1 Assoc Grp=0x32E9 Xmit=0x16D0 Recv=0x16D0 14 1.906250 {MSRPC:10, TCP:9, IPv4:8} 172.16.11.124 test125.test.local DCOM DCOM 15 1.906250 {MSRPC:10, TCP:9, IPv4:8} test125.test.local 172.16.11.124 DCOM DCOM

Test124 thành lập một ràng buộc RCP với test125 và gọi DCOM.

16 1.921875 {TCP:11, IPv4:8} 172.16.11.124 test125.test.local TCP TCP: Flags=.S......, SrcPort=1070, DstPort=DCE endpoint resolution(135), Len=0, Seq=3003512395, Ack=0, Win=65535 (scale factor 0) = 65535 17 1.921875 {TCP:11, IPv4:8} test125.test.local 172.16.11.124 TCP TCP: Flags=.S..A..., SrcPort=DCE endpoint resolution(135), DstPort=1070, Len=0, Seq=4088700167, Ack=3003512396, Win=65535 (scale factor 0) = 65535 18 1.921875 {TCP:11, IPv4:8} 172.16.11.124 test125.test.local TCP TCP: Flags=....A..., SrcPort=1070, DstPort=DCE endpoint resolution(135), Len=0, Seq=3003512396, Ack=4088700168, Win=65535 (scale factor 0) = 65535

Bắt tay 3-đường TCP giữa hai máy tính.

19 1.921875 {UDP:12, IPv4:1} 172.16.11.124 dc181.test.local KerberosV5 KerberosV5: TGS Request Realm: TEST.LOCAL Sname: RPCSS/test125.test.local

Page 54: Quản lý các mạng Windows dùng Script

20 1.921875 {UDP:12, IPv4:1} dc181.test.local 172.16.11.124 KerberosV5 KerberosV5: TGS Response Cname: Administrator

Thẩm định Kerberos

21 1.921875 {MSRPC:13, TCP:11, IPv4:8} 172.16.11.124 test125.test.local MSRPC MSRPC: c/o Bind: UUID{000001A0-0000-0000-C000-000000000046} DCOM-IRemoteSCMActivator Call=0x2 Assoc Grp=0x32E9 Xmit=0x16D0 Recv=0x16D0 22 1.921875 {ARP:14} 172.16.11.181 172.16.11.125 ARP ARP: Request, 172.16.11.181 asks for 172.16.11.125 23 1.921875 {MSRPC:13, TCP:11, IPv4:8} test125.test.local 172.16.11.124 MSRPC MSRPC: c/o Bind Ack: Call=0x2 Assoc Grp=0x32E9 Xmit=0x16D0 Recv=0x16D0 24 1.921875 {MSRPC:13, TCP:11, IPv4:8} 172.16.11.124 test125.test.local MSRPC MSRPC: c/o Alter Cont: UUID{000001A0-0000-0000-C000-000000000046} DCOM-IRemoteSCMActivator Call=0x2 25 1.921875 {MSRPC:13, TCP:11, IPv4:8} test125.test.local 172.16.11.124 MSRPC MSRPC: c/o Alter Cont Resp: Call=0x2 Assoc Grp=0x32E9 Xmit=0x16D0 Recv=0x16D0 26 1.921875 {MSRPC:13, TCP:11, IPv4:8} 172.16.11.124 test125.test.local DCOM DCOM 27 1.937500 {MSRPC:13, TCP:11, IPv4:8} test125.test.local 172.16.11.124 DCOM DCOM

Nhiều RPC và DCOM. Chúng tôi nghĩ rằng “Alter Cont” chỉ thị nội dung xen kẽ đang được sử dụng, nhưng thực tế lại không bảo đảm như vậy. Lẽ ra mọi thứ phải là OK khi kịch bản đã làm việc mà không phát sinh ra bất kỳ một lỗi nào.

28 1.937500 {TCP:15, IPv4:8} 172.16.11.124 test125.test.local TCP TCP: Flags=.S......, SrcPort=1072, DstPort=1117, Len=0, Seq=3011418470, Ack=0, Win=65535 (scale factor 0) = 65535 29 1.937500 {TCP:15, IPv4:8} test125.test.local 172.16.11.124 TCP TCP: Flags=.S..A..., SrcPort=1117, DstPort=1072, Len=0, Seq=554832695, Ack=3011418471, Win=65535 (scale factor 0) = 65535 30 1.937500 {TCP:15, IPv4:8} 172.16.11.124 test125.test.local TCP TCP: Flags=....A..., SrcPort=1072, DstPort=1117, Len=0, Seq=3011418471, Ack=554832696, Win=65535 (scale factor 0) = 65535

Một bắt tay TCP khác

31 1.937500 {UDP:16, IPv4:1} 172.16.11.124 dc181.test.local KerberosV5 KerberosV5: TGS Request Realm: TEST.LOCAL Sname: TEST125$ 32 1.937500 {UDP:16, IPv4:1} dc181.test.local 172.16.11.124 KerberosV5 KerberosV5: TGS Response Cname: Administrator

Tiếp tục với Kerberos

33 1.937500 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local MSRPC MSRPC: c/o Bind: UUID{00000143-0000-0000-C000-000000000046} DCOM-IRemUnknown2 Call=0x1 Assoc Grp=0x0 Xmit=0x16D0 Recv=0x16D0 34 1.937500 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 MSRPC MSRPC: c/o Bind Ack: Call=0x1 Assoc Grp=0x333D Xmit=0x16D0 Recv=0x16D0 35 1.937500 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local MSRPC MSRPC: c/o Alter Cont: UUID{00000143-0000-0000-C000-000000000046} DCOM-IRemUnknown2 Call=0x1

36 1.937500 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 MSRPC MSRPC: c/o Alter Cont Resp: Call=0x1 Assoc Grp=0x333D Xmit=0x16D0 Recv=0x16D0 37 1.937500 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local DCOM DCOM 38 1.937500 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 DCOM DCOM 39 1.937500 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local MSRPC MSRPC:

Page 55: Quản lý các mạng Windows dùng Script

c/o Alter Cont: UUID{D4781CD6-E5D3-44DF-AD94-930EFE48A887} WMI-IWbemLoginClientID Call=0x2 40 1.937500 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 MSRPC MSRPC: c/o Alter Cont Resp: Call=0x2 Assoc Grp=0x333D Xmit=0x16D0 Recv=0x16D0 41 1.937500 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local DCOM DCOM 42 1.937500 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 DCOM DCOM 43 1.937500 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local MSRPC MSRPC: c/o Alter Cont: UUID{F309AD18-D86A-11D0-A075-00C04FB68820} WMI-IWbemLevel1Login Call=0x3 44 1.937500 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 MSRPC MSRPC: c/o Alter Cont Resp: Call=0x3 Assoc Grp=0x333D Xmit=0x16D0 Recv=0x16D0 45 1.937500 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local DCOM DCOM 46 1.937500 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 DCOM DCOM 47 1.937500 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local DCOM DCOM 48 1.937500 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 DCOM DCOM 49 1.953125 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local MSRPC MSRPC: c/o Alter Cont: UUID{9556DC99-828C-11CF-A37E-00AA003240C7} WMI-IWbemServices Call=0x5

50 1.953125 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 MSRPC MSRPC: c/o Alter Cont Resp: Call=0x5 Assoc Grp=0x333D Xmit=0x16D0 Recv=0x16D0 51 1.953125 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local DCOM DCOM 52 1.953125 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 DCOM DCOM 53 1.953125 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local DCOM DCOM 54 1.953125 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 DCOM DCOM 55 1.953125 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local MSRPC MSRPC: c/o Alter Cont: UUID{1C1C45EE-4395-11D2-B60B-00104B703EFD} WMI-IWbemFetchSmartEnum Call=0x7 56 1.953125 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 MSRPC MSRPC: c/o Alter Cont Resp: Call=0x7 Assoc Grp=0x333D Xmit=0x16D0 Recv=0x16D0 57 1.953125 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local DCOM DCOM 58 1.953125 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 DCOM DCOM 59 1.953125 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local MSRPC MSRPC: c/o Alter Cont: UUID{423EC01E-2E35-11D2-B604-00104B703EFD} WMI-IWbemWCOSmartEnum Call=0x8 60 1.953125 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 MSRPC MSRPC: c/o Alter Cont Resp: Call=0x8 Assoc Grp=0x333D Xmit=0x16D0 Recv=0x16D0 61 1.953125 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local DCOM DCOM 62 2.015625 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 DCOM DCOM

Có rất nhiều RPC/DCOM ở đây. Nó có vẻ bí ẩn nhưng nếu nhìn kỹ chúng bạn sẽ thấy một số WMI đang có như là WMI-IWbemLoginClientID, WMI-IWbemLevel1Login, WMI-IWbemServices, WMI-IWbemFetchSmartEnum,…. Tìm kiếm trên MSDN cho chúng ta thấy nhiều thông tin hơn về những gì xảy ra. Ví dụ, trang này cho chúng ta biết rằng “ Giao diện IwbemServices được sử dụng cho các máy khách và các nhà cung cấp để có thể truy cập vào các dịch vụ WMI” vì vậy nó giống như các giao diện WMI đang tồn tại được gọi trên máy tính điều khiển xa (sử dụng DCOM) bởi máy trạm chủ đang chạy kịch bản từ nó. Một số giao diện không thực sự gây khó hiểu đối với người đọc.

Những thứ gây khó hiểu cho người đọc đầu tiên đó là các cụm TCP với các gói RPC “Continued Response” dường như chỉ thị các kết nối được thực hiện trước đó đang được sử dụng vào nhiều mục đích khác. Chúng tôi sẽ bỏ qua một số khung trong phần tiếp theo này.

63 2.015625 {TCP:15, IPv4:8} test125.test.local 172.16.11.124 TCP TCP: [Continuation to #62]Flags=....A..., SrcPort=1117, DstPort=1072, Len=1460, Seq=554835972 - 554837432, Ack=3011421991, Win=65061 (scale factor 0) = 65061 64 2.015625 {TCP:15, IPv4:8} 172.16.11.124 test125.test.local TCP TCP: Flags=....A..., SrcPort=1072, DstPort=1117, Len=0, Seq=3011421991, Ack=554837432, Win=65535 (scale factor 0) = 65535 65 2.015625 {TCP:15, IPv4:8} test125.test.local 172.16.11.124 TCP TCP: [Continuation

Page 56: Quản lý các mạng Windows dùng Script

to #62]Flags=....A..., SrcPort=1117, DstPort=1072, Len=1460, Seq=554837432 - 554838892, Ack=3011421991, Win=65061 (scale factor 0) = 65061 66 2.015625 {TCP:15, IPv4:8} 172.16.11.124 test125.test.local TCP TCP: Flags=....A..., SrcPort=1072, DstPort=1117, Len=0, Seq=3011421991, Ack=554838892, Win=65535 (scale factor 0) = 65535 67 2.015625 {TCP:15, IPv4:8} test125.test.local 172.16.11.124 TCP TCP: [Continuation to #62]Flags=...PA..., SrcPort=1117, DstPort=1072, Len=1449, Seq=554838892 - 554840341, Ack=3011421991, Win=65061 (scale factor 0) = 65061 68 2.015625 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 MSRPC MSRPC: c/o Continued Response: WMI-IWbemWCOSmartEnum Call=0x8 Context=0x5 Hint=0x198C Cancels=0x0 . . . 155 2.031250 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 MSRPC MSRPC: c/o Continued Response: WMI-IWbemServices Call=0x9 Context=0x3 Hint=0x904 Cancels=0x0

156 2.031250 {TCP:15, IPv4:8} test125.test.local 172.16.11.124 TCP TCP: [Continuation to #155]Flags=...PA..., SrcPort=1117, DstPort=1072, Len=929, Seq=554924260 - 554925189, Ack=3011422236, Win=64816 (scale factor 0) = 64816 157 2.031250 {TCP:15, IPv4:8} 172.16.11.124 test125.test.local TCP TCP: Flags=....A..., SrcPort=1072, DstPort=1117, Len=0, Seq=3011422236, Ack=554925189, Win=65535 (scale factor 0) = 65535 158 2.031250 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local DCOM DCOM 159 2.031250 {TCP:15, IPv4:8} 172.16.11.124 test125.test.local TCP TCP: [Continuation to #158]Flags=...PA..., SrcPort=1072, DstPort=1117, Len=1, Seq=3011423696 - 3011423697, Ack=554925189, Win=65535 (scale factor 0) = 65535 160 2.031250 {TCP:15, IPv4:8} test125.test.local 172.16.11.124 TCP TCP: Flags=....A..., SrcPort=1117, DstPort=1072, Len=0, Seq=554925189, Ack=3011423697, Win=65535 (scale factor 0) = 65535

Chúng ta có một cụm DCOM theo sau là các kết thúc kết nối TCP bằng FIN/ACK, vì vậy theo dự đoán kịch bản có thể đã thực hiện được công việc của nó và đang quét dọn làm sạch.

161 2.062500 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 DCOM DCOM 162 2.062500 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local DCOM DCOM 163 2.062500 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 DCOM DCOM 164 2.062500 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local DCOM DCOM 165 2.062500 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 DCOM DCOM 166 2.062500 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local DCOM DCOM 167 2.062500 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 DCOM DCOM 168 2.062500 {MSRPC:17, TCP:15, IPv4:8} 172.16.11.124 test125.test.local DCOM DCOM 169 2.062500 {MSRPC:17, TCP:15, IPv4:8} test125.test.local 172.16.11.124 DCOM DCOM 170 2.078125 {TCP:15, IPv4:8} 172.16.11.124 test125.test.local TCP TCP: Flags=F...A..., SrcPort=1072, DstPort=1117, Len=0, Seq=3011424421, Ack=554926046, Win=64678 (scale factor 0) = 64678 171 2.078125 {TCP:15, IPv4:8} test125.test.local 172.16.11.124 TCP TCP: Flags=....A..., SrcPort=1117, DstPort=1072, Len=0, Seq=554926046, Ack=3011424422, Win=64811 (scale factor 0) = 64811 172 2.078125 {TCP:15, IPv4:8} test125.test.local 172.16.11.124 TCP TCP: Flags=F...A..., SrcPort=1117, DstPort=1072, Len=0, Seq=554926046, Ack=3011424422, Win=64811 (scale factor 0) = 64811 173 2.078125 {TCP:15, IPv4:8} 172.16.11.124 test125.test.local TCP TCP: Flags=....A..., SrcPort=1072, DstPort=1117, Len=0, Seq=3011424422, Ack=554926047, Win=64678 (scale factor 0) = 64678 174 2.093750 {TCP:9, IPv4:8} 172.16.11.124 test125.test.local TCP TCP: Flags=....A..., SrcPort=1069, DstPort=DCE endpoint resolution(135), Len=0, Seq=1441245035, Ack=871910766, Win=65339 (scale factor 0) = 65339 175 2.093750 {TCP:11, IPv4:8} 172.16.11.124 test125.test.local TCP TCP: Flags=....A..., SrcPort=1070, DstPort=DCE endpoint resolution(135), Len=0,

Page 57: Quản lý các mạng Windows dùng Script

Seq=3003514721, Ack=4088701653, Win=65535 (scale factor 0) = 65535 176 2.546875 {TCP:18, IPv4:1} 172.16.11.124 dc181.test.local TCP TCP: Flags=.S......, SrcPort=1074, DstPort=DCE endpoint resolution(135), Len=0, Seq=4283854964, Ack=0, Win=65535 (scale factor 0) = 65535 177 2.546875 {TCP:18, IPv4:1} dc181.test.local 172.16.11.124 TCP TCP: Flags=.S..A..., SrcPort=DCE endpoint resolution(135), DstPort=1074, Len=0, Seq=2447011944, Ack=4283854965, Win=16384 (scale factor 0) = 16384 178 2.546875 {TCP:18, IPv4:1} 172.16.11.124 dc181.test.local TCP TCP: Flags=....A..., SrcPort=1074, DstPort=DCE endpoint resolution(135), Len=0, Seq=4283854965, Ack=2447011945, Win=65535 (scale factor 0) = 65535

Ở đây có một số DNS và LDAP xuất hiện giữa test124 và bộ điều khiển miền. Không rõ tại sao nó lại xảy ra, nhưng chúng tôi sẽ bỏ qua một số khung đó khi chúng xuất hiện quá nhiều:

179 2.546875 {MSRPC:19, TCP:18, IPv4:1} 172.16.11.124 dc181.test.local MSRPC MSRPC: c/o Bind: UUID{E1AF8308-5D1F-11C9-91A4-08002B14A0FA} Endpoint Mapper Call=0x1 Assoc Grp=0x0 Xmit=0x16D0 Recv=0x16D0 180 2.546875 {MSRPC:19, TCP:18, IPv4:1} dc181.test.local 172.16.11.124 MSRPC MSRPC: c/o Bind Ack: Call=0x1 Assoc Grp=0x7DAD Xmit=0x16D0 Recv=0x16D0 181 2.546875 {MSRPC:19, TCP:18, IPv4:1} 172.16.11.124 dc181.test.local EPM EPM: Request: ept_map: NDR, Tracking Server Service v1.0, RPC v5, 0.0.0.0:135 (0x87) [DCE endpoint resolution(135)] 182 2.546875 {MSRPC:19, TCP:18, IPv4:1} dc181.test.local 172.16.11.124 EPM EPM: Response: ept_map: 0x16C9A0D6 - EP_S_NOT_REGISTERED 183 2.546875 {DNS:21, UDP:20, IPv4:1} 172.16.11.124 dc181.test.local DNS DNS: QueryId = 0x896A, QUERY (Standard query), Query for _ldap._tcp.Default-First-Site._sites.dc._msdcs.test.local of type SRV on class Internet 184 2.546875 {DNS:21, UDP:20, IPv4:1} dc181.test.local 172.16.11.124 DNS DNS: QueryId = 0x896A, QUERY (Standard query), Response - Success 185 2.546875 {LDAP:23, UDP:22, IPv4:1} 172.16.11.124 dc181.test.local LDAP LDAP: Search Request, MessageID:4, BaseObject: NULL, SearchScope: base Object, SearchAlias: neverDerefAliases 186 2.546875 {LDAP:23, UDP:22, IPv4:1} dc181.test.local 172.16.11.124 LDAP LDAP: Search Result Entry, MessageID:4, Status: Success . . . 212 6.546875 {DNS:32, UDP:5, IPv4:1} 172.16.11.124 dc181.test.local DNS DNS: QueryId = 0x266D, QUERY (Standard query), Query for download.windowsupdate.com of type Host Addr on class Internet 213 6.546875 {ARP:4} 172.16.11.181 172.16.11.1 ARP ARP: Request, 172.16.11.181 asks for 172.16.11.1 214 7.546875 {DNS:32, UDP:5, IPv4:1} 172.16.11.124 dc181.test.local DNS DNS: QueryId = 0x266D, QUERY (Standard query), Query for download.windowsupdate.com of type Host Addr on class Internet 215 8.546875 {DNS:32, UDP:5, IPv4:1} 172.16.11.124 dc181.test.local DNS DNS: QueryId = 0x266D, QUERY (Standard query), Query for download.windowsupdate.com of type Host Addr on class Internet 216 9.281250 {ARP:4} 172.16.11.181 172.16.11.1 ARP ARP: Request, 172.16.11.181 asks for 172.16.11.1

Tại điểm này, kịch bản đã sẵn sàng kết thúc vì vậy chúng tôi đã kết thúc capture.

Phân tích của Capture cho ChangeIPAddress.vbs

Bây giờ chúng ta đã có một chút ý tưởng về những gì một capture của kịch bản điều khiển từ xa thành công trông như thế nào:

Page 58: Quản lý các mạng Windows dùng Script

Một số DNS và ARP Sự thiết lập của các TCP session bằng bắt tay 3 cách. Ràng buộc RPC và DCOM Nhiều bắt tay TCP Kerberos (các máy tính trong một miền) Nhiều RPC/DCOM Nhiều bắt tay TCP, nhiều Kerberos, RPC/DCOM được kết hợp với truyền thông TCP. Nhiều DCOM được theo sau là các TCP session được thành lập trước đó.

Toàn bộ những thứ đó mất khoảng trên 2s.

Bây giờ chúng ta hãy nhìn vào capture cho ChangeIPAddress.vbs (kịch bản đã phát sinh lỗi RPC khi chạy nó từ xa) và xem nó khác như thế nào với các kịch bản trên.

1 0.000000 NetmonFilter NetmonFilter: Updated Capture Filter: None 2 0.000000 NetworkInfo NetworkInfo: Network info for TEST124, Network Adapter Count = 1

 Đó là Netmon

3 0.000000 {DNS:3, UDP:2, IPv4:1} test124.test.local dc181.test.local DNS DNS: QueryId = 0x7869, QUERY (Standard query), Query for test125.test.local of type Host Addr on class Internet 4 0.000000 {DNS:3, UDP:2, IPv4:1} dc181.test.local test124.test.local DNS DNS: QueryId = 0x7869, QUERY (Standard query), Response - Success 5 0.015625 {ARP:4} 172.16.11.124 172.16.11.125 ARP ARP: Request, 172.16.11.124 asks for 172.16.11.125 6 0.015625 {ARP:4} 172.16.11.125 172.16.11.124 ARP ARP: Response, 172.16.11.125 at 00-11-D8-E3-EC-84 7 0.015625 {TCP:6, IPv4:5} test124.test.local test125.test.local TCP TCP: Flags=.S......, SrcPort=1063, DstPort=DCE endpoint resolution(135), Len=0, Seq=539163285, Ack=0, Win=65535 (scale factor 0) = 65535 8 0.015625 {TCP:6, IPv4:5} test125.test.local test124.test.local TCP TCP: Flags=.S..A..., SrcPort=DCE endpoint resolution(135), DstPort=1063, Len=0, Seq=981335265, Ack=539163286, Win=65535 (scale factor 0) = 65535 9 0.015625 {TCP:6, IPv4:5} test124.test.local test125.test.local TCP TCP: Flags=....A..., SrcPort=1063, DstPort=DCE endpoint resolution(135), Len=0, Seq=539163286, Ack=981335266, Win=65535 (scale factor 0) = 65535

ARP, sau đó NDS, bắt tay TCP – như phần trước.

10 0.015625 {MSRPC:7, TCP:6, IPv4:5} test124.test.local test125.test.local MSRPC MSRPC: c/o Bind: UUID{99FCFEC4-5260-101B-BBCB-00AA0021347A} DCOM-IObjectExporter Call=0x1 Assoc Grp=0x0 Xmit=0x16D0 Recv=0x16D0 11 0.015625 {MSRPC:7, TCP:6, IPv4:5} test125.test.local test124.test.local MSRPC MSRPC: c/o Bind Ack: Call=0x1 Assoc Grp=0x32EA Xmit=0x16D0 Recv=0x16D0 12 0.031250 {MSRPC:7, TCP:6, IPv4:5} test124.test.local test125.test.local DCOM DCOM 13 0.031250 {MSRPC:7, TCP:6, IPv4:5} test125.test.local test124.test.local DCOM DCOM 14 0.078125 {TCP:8, IPv4:5} test124.test.local test125.test.local TCP TCP: Flags=.S......, SrcPort=1064, DstPort=DCE endpoint resolution(135), Len=0, Seq=1367843928, Ack=0, Win=65535 (scale factor 0) = 65535 15 0.078125 {TCP:8, IPv4:5} test125.test.local test124.test.local TCP TCP: Flags=.S..A..., SrcPort=DCE endpoint resolution(135), DstPort=1064, Len=0, Seq=3625279350, Ack=1367843929, Win=65535 (scale factor 0) = 65535 16 0.078125 {TCP:8, IPv4:5} test124.test.local test125.test.local TCP TCP: Flags=....A..., SrcPort=1064, DstPort=DCE endpoint resolution(135), Len=0,

Page 59: Quản lý các mạng Windows dùng Script

Seq=1367843929, Ack=3625279351, Win=65535 (scale factor 0) = 65535 17 0.078125 {UDP:9, IPv4:1} test124.test.local dc181.test.local KerberosV5 KerberosV5: TGS Request Realm: TEST.LOCAL Sname: RPCSS/test125.test.local 18 0.078125 {UDP:9, IPv4:1} dc181.test.local test124.test.local KerberosV5 KerberosV5: TGS Response Cname: Administrator

RPC, sau đó là DCOM, bắt tay TCP khác, Kerberos. Trông cũng tương tự như trước.

19 0.078125 {MSRPC:10, TCP:8, IPv4:5} test124.test.local test125.test.local MSRPC MSRPC: c/o Bind: UUID{000001A0-0000-0000-C000-000000000046} DCOM-IRemoteSCMActivator Call=0x2 Assoc Grp=0x32EA Xmit=0x16D0 Recv=0x16D0 20 0.093750 {ARP:11} 172.16.11.125 172.16.11.181 ARP ARP: Request, 172.16.11.125 asks for 172.16.11.181 21 0.093750 {MSRPC:10, TCP:8, IPv4:5} test125.test.local test124.test.local MSRPC MSRPC: c/o Bind Ack: Call=0x2 Assoc Grp=0x32EA Xmit=0x16D0 Recv=0x16D0 22 0.093750 {MSRPC:10, TCP:8, IPv4:5} test124.test.local test125.test.local MSRPC MSRPC: c/o Alter Cont: UUID{000001A0-0000-0000-C000-000000000046} DCOM-IRemoteSCMActivator Call=0x2 23 0.093750 {MSRPC:10, TCP:8, IPv4:5} test125.test.local test124.test.local MSRPC MSRPC: c/o Alter Cont Resp: Call=0x2 Assoc Grp=0x32EA Xmit=0x16D0 Recv=0x16D0 24 0.093750 {MSRPC:10, TCP:8, IPv4:5} test124.test.local test125.test.local DCOM DCOM

25 0.093750 {MSRPC:10, TCP:8, IPv4:5} test125.test.local test124.test.local DCOM DCOM

26 0.093750 {TCP:12, IPv4:5} test124.test.local test125.test.local TCP TCP: Flags=.S......, SrcPort=1066, DstPort=1117, Len=0, Seq=1180773456, Ack=0, Win=65535 (scale factor 0) = 65535 27 0.093750 {TCP:12, IPv4:5} test125.test.local test124.test.local TCP TCP: Flags=.S..A..., SrcPort=1117, DstPort=1066, Len=0, Seq=539972629, Ack=1180773457, Win=65535 (scale factor 0) = 65535 28 0.093750 {TCP:12, IPv4:5} test124.test.local test125.test.local TCP TCP: Flags=....A..., SrcPort=1066, DstPort=1117, Len=0, Seq=1180773457, Ack=539972630, Win=65535 (scale factor 0) = 65535 29 0.093750 {UDP:13, IPv4:1} test124.test.local dc181.test.local KerberosV5 KerberosV5: TGS Request Realm: TEST.LOCAL Sname: TEST125$ 30 0.109375 {UDP:13, IPv4:1} dc181.test.local test124.test.local KerberosV5 KerberosV5: TGS Response Cname: Administrator

Cùng mẫu

31 0.109375 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local MSRPC MSRPC: c/o Bind: UUID{00000143-0000-0000-C000-000000000046} DCOM-IRemUnknown2 Call=0x1 Assoc Grp=0x0 Xmit=0x16D0 Recv=0x16D0 32 0.109375 {MSRPC:14, TCP:12, IPv4:5} test125.test.local test124.test.local MSRPC MSRPC: c/o Bind Ack: Call=0x1 Assoc Grp=0x333E Xmit=0x16D0 Recv=0x16D0 33 0.109375 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local MSRPC MSRPC: c/o Alter Cont: UUID{00000143-0000-0000-C000-000000000046} DCOM-IRemUnknown2 Call=0x1 34 0.109375 {MSRPC:14, TCP:12, IPv4:5} test125.test.local test124.test.local MSRPC MSRPC: c/o Alter Cont Resp: Call=0x1 Assoc Grp=0x333E Xmit=0x16D0 Recv=0x16D0 35 0.109375 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local DCOM DCOM 36 0.109375 {MSRPC:14, TCP:12, IPv4:5} test125.test.local test124.test.local DCOM DCOM 37 0.109375 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local MSRPC MSRPC: c/o Alter Cont: UUID{D4781CD6-E5D3-44DF-AD94-930EFE48A887} WMI-IWbemLoginClientID Call=0x2 38 0.109375 {MSRPC:14, TCP:12, IPv4:5} test125.test.local test124.test.local MSRPC MSRPC: c/o Alter Cont Resp: Call=0x2 Assoc Grp=0x333E Xmit=0x16D0 Recv=0x16D0

Page 60: Quản lý các mạng Windows dùng Script

39 0.109375 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local DCOM DCOM 40 0.109375 {MSRPC:14, TCP:12, IPv4:5} test125.test.local test124.test.local DCOM DCOM 41 0.109375 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local MSRPC MSRPC: c/o Alter Cont: UUID{F309AD18-D86A-11D0-A075-00C04FB68820} WMI-IWbemLevel1Login Call=0x3 42 0.109375 {MSRPC:14, TCP:12, IPv4:5} test125.test.local test124.test.local MSRPC MSRPC: c/o Alter Cont Resp: Call=0x3 Assoc Grp=0x333E Xmit=0x16D0 Recv=0x16D0 43 0.109375 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local DCOM DCOM 44 0.109375 {MSRPC:14, TCP:12, IPv4:5} test125.test.local test124.test.local DCOM DCOM 45 0.109375 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local DCOM COM 46 0.109375 {MSRPC:14, TCP:12, IPv4:5} test125.test.local test124.test.local DCOM DCOM 47 0.109375 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local MSRPC MSRPC: c/o Alter Cont: UUID{9556DC99-828C-11CF-A37E-00AA003240C7} WMI-IWbemServices Call=0x5 48 0.109375 {MSRPC:14, TCP:12, IPv4:5} test125.test.local test124.test.local MSRPC MSRPC: c/o Alter Cont Resp: Call=0x5 Assoc Grp=0x333E Xmit=0x16D0 Recv=0x16D0 49 0.109375 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local DCOM DCOM 50 0.109375 {MSRPC:14, TCP:12, IPv4:5} test125.test.local test124.test.local DCOM DCOM 51 0.109375 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local DCOM DCOM 52 0.109375 {MSRPC:14, TCP:12, IPv4:5} test125.test.local test124.test.local DCOM DCOM 53 0.109375 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local MSRPC MSRPC: c/o Alter Cont: UUID{1C1C45EE-4395-11D2-B60B-00104B703EFD} WMI-IWbemFetchSmartEnum Call=0x7 54 0.109375 {MSRPC:14, TCP:12, IPv4:5} test125.test.local test124.test.local MSRPC MSRPC: c/o Alter Cont Resp: Call=0x7 Assoc Grp=0x333E Xmit=0x16D0 Recv=0x16D0 55 0.109375 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local DCOM DCOM 56 0.109375 {MSRPC:14, TCP:12, IPv4:5} test125.test.local test124.test.local DCOM DCOM 57 0.109375 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local MSRPC MSRPC: c/o Alter Cont: UUID{423EC01E-2E35-11D2-B604-00104B703EFD} WMI-IWbemWCOSmartEnum Call=0x8 58 0.109375 {MSRPC:14, TCP:12, IPv4:5} test125.test.local test124.test.local MSRPC MSRPC: c/o Alter Cont Resp: Call=0x8 Assoc Grp=0x333E Xmit=0x16D0 Recv=0x16D0 59 0.109375 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local DCOM DCOM

Toàn bộ cụm RPC/DCOM, giống các dấu hiệu khác.

60 0.187500 {TCP:6, IPv4:5} test124.test.local test125.test.local TCP TCP: Flags=....A..., SrcPort=1063, DstPort=DCE endpoint resolution(135), Len=0, Seq=539163382, Ack=981335462, Win=65339 (scale factor 0) = 65339 61 0.187500 {MSRPC:14, TCP:12, IPv4:5} test125.test.local test124.test.local DCOM DCOM 62 0.187500 {TCP:12, IPv4:5} test125.test.local test124.test.local TCP TCP: [Continuation to #61]Flags=....A..., SrcPort=1117, DstPort=1066, Len=1460, Seq=539975906 - 539977366, Ack=1180776977, Win=65061 (scale factor 0) = 65061 63 0.187500 {TCP:12, IPv4:5} test124.test.local test125.test.local TCP TCP: Flags=....A..., SrcPort=1066, DstPort=1117, Len=0, Seq=1180776977, Ack=539977366, Win=65535 (scale factor 0) = 65535

Page 61: Quản lý các mạng Windows dùng Script

64 0.187500 {TCP:12, IPv4:5} test125.test.local test124.test.local TCP TCP: [Continuation to #61]Flags=....A..., SrcPort=1117, DstPort=1066, Len=1460, Seq=539977366 - 539978826, Ack=1180776977, Win=65061 (scale factor 0) = 65061 65 0.187500 {TCP:12, IPv4:5} test124.test.local test125.test.local TCP TCP: Flags=....A..., SrcPort=1066, DstPort=1117, Len=0, Seq=1180776977, Ack=539978826, Win=65535 (scale factor 0) = 65535 66 0.187500 {TCP:12, IPv4:5} test125.test.local test124.test.local TCP TCP: [Continuation to #61]Flags=...PA..., SrcPort=1117, DstPort=1066, Len=1449, Seq=539978826 - 539980275, Ack=1180776977, Win=65061 (scale factor 0) = 65061 67 0.187500 {MSRPC:14, TCP:12, IPv4:5} test125.test.local test124.test.local MSRPC MSRPC: c/o Continued Response: WMI-IWbemWCOSmartEnum Call=0x8 Context=0x5 Hint=0x198C Cancels=0x0 . . . 148 0.187500 {MSRPC:14, TCP:12, IPv4:5} test125.test.local test124.test.local MSRPC MSRPC: c/o Continued Response: WMI-IWbemServices Call=0x9 Context=0x3 Hint=0x1F84 Cancels=0x0 149 0.187500 {TCP:12, IPv4:5} test125.test.local test124.test.local TCP TCP: [Continuation to #148]Flags=....A..., SrcPort=1117, DstPort=1066, Len=1460, Seq=540058365 - 540059825, Ack=1180777222, Win=64816 (scale factor 0) = 64816 150 0.187500 {TCP:12, IPv4:5} test124.test.local test125.test.local TCP TCP: Flags=....A..., SrcPort=1066, DstPort=1117, Len=0, Seq=1180777222, Ack=540059825, Win=65535 (scale factor 0) = 65535 151 0.187500 {TCP:12, IPv4:5} test125.test.local test124.test.local TCP TCP: [Continuation to #148]Flags=....A..., SrcPort=1117, DstPort=1066, Len=1460, Seq=540059825 - 540061285, Ack=1180777222, Win=64816 (scale factor 0) = 64816 152 0.187500 {TCP:12, IPv4:5} test125.test.local test124.test.local TCP TCP: [Continuation to #148]Flags=...PA..., SrcPort=1117, DstPort=1066, Len=1449, Seq=540061285 - 540062734, Ack=1180777222, Win=64816 (scale factor 0) = 64816 153 0.187500 {TCP:12, IPv4:5} test124.test.local test125.test.local TCP TCP: Flags=....A..., SrcPort=1066, DstPort=1117, Len=0, Seq=1180777222, Ack=540062734, Win=65535 (scale factor 0) = 65535 154 0.187500 {MSRPC:14, TCP:12, IPv4:5} test125.test.local test124.test.local MSRPC MSRPC: c/o Continued Response: WMI-IWbemServices Call=0x9 Context=0x3 Hint=0x904 Cancels=0x0 155 0.187500 {TCP:12, IPv4:5} test125.test.local test124.test.local TCP TCP: [Continuation to #154]Flags=...PA..., SrcPort=1117, DstPort=1066, Len=929, Seq=540064194 - 540065123, Ack=1180777222, Win=64816 (scale factor 0) = 64816 156 0.187500 {TCP:12, IPv4:5} test124.test.local test125.test.local TCP TCP: Flags=....A..., SrcPort=1066, DstPort=1117, Len=0, Seq=1180777222, Ack=540065123, Win=65535 (scale factor 0) = 65535 157 0.187500 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local DCOM DCOM RPC together with TCP. You can see the WMI interface calls happening. RPC cùng với TCP. Bạn có thể nhìn thấy các cuộc gọi giao diện WMI đang diễn ra. 158 0.218750 {ARP:15} 172.16.11.144 172.16.11.144 ARP ARP: Request, 172.16.11.144 asks for 172.16.11.144

Kịch bản trên đã thay đổi thành công địa chỉ IP của máy tính mục tiêu (test125) từ 172.16.11.125 thành 172.16.11.144, vậy tại sao máy tính mục tiêu sử dụng ARP để thử và chuyển địa chỉ IP của nó vào thành địa chỉ MAC? Điều này là một ví dụ ARP không có lý do, điều đã xảy ra khi một nút nào đó khởi tạo yêu cầu ARP cho địa chỉ IP của nó. Vậy tại sao máy tính mục tiêu thực hiện điều này? Để bảo đảm địa chỉ IP mới không bị sử dụng bởi bất kỳ nút mạng khác nào trong mạng. Máy tính mục tiêu đưa ra một vài yêu cầu ARP và nếu không có đáp ứng ARP nào được nhận thì nó sẽ đưa ra quyết định rằng địa chỉ mới của nó là duy nhất đối với mạng và địa chỉ đó có thể được giữ lại. Tuy nhiên nếu một nút khác đưa ra một đáp ứng ARP cho yêu cầu này thì đây sẽ là nút đầu tiên thừa nhận có một địa chỉ xung đột trên mạng và nó vô hiệu hóa địa chỉ IP của nó (gán thành 0.0.0.0).

Page 62: Quản lý các mạng Windows dùng Script

Ở đây, mọi thứ dường như được giải quyết – bạn có thể thấy điều này bởi sự thật rằng thời gian bên trong các gói đang tăng đáng kể. Những gì đó xảy ra tiếp theo là nút mã nguồn (test124) cố gắng phúc đáp TCP với máy tính mục tiêu nhưng không gặp ở vị trí nào:

159 0.296875 {TCP:8, IPv4:5} test124.test.local test125.test.local TCP TCP: Flags=....A..., SrcPort=1064, DstPort=DCE endpoint resolution(135), Len=0, Seq=1367846254, Ack=3625280836, Win=65535 (scale factor 0) = 65535 160 0.437500 {ARP:15} 172.16.11.144 172.16.11.144 ARP ARP: Request, 172.16.11.144 asks for 172.16.11.144 161 0.515625 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local DCOM DCOM 162 1.062500 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local DCOM DCOM 163 1.437500 {ARP:15} 172.16.11.144 172.16.11.144 ARP ARP: Request, 172.16.11.144 asks for 172.16.11.144 164 2.265625 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local DCOM DCOM 165 2.453125 {ARP:15} 172.16.11.144 172.16.11.144 ARP ARP: Request, 172.16.11.144 asks for 172.16.11.144 166 3.437500 {ARP:15} 172.16.11.144 172.16.11.144 ARP ARP: Request, 172.16.11.144 asks for 172.16.11.144 167 4.437500 {ARP:15} 172.16.11.144 172.16.11.144 ARP ARP: Request, 172.16.11.144 asks for 172.16.11.144 168 4.671875 {MSRPC:14, TCP:12, IPv4:5} test124.test.local test125.test.local DCOM DCOM

Hãy xem xét gói 159 ở trên (Hình 8):

Page 63: Quản lý các mạng Windows dùng Script

Hình 8: Các vấn đề kết nối TCP

Lưu ý từ hình này rằng máy tính nguồn (test124) vẫn cho rằng máy đích có địa chỉ IP là 172.16.11.125, và nó vẫn cố gắng gửi tín hiệu ACK đến test125 để duy trì kết nối TCP được thành lập trước đó.

Hãy xem khung 161 (Hình 9):

Page 64: Quản lý các mạng Windows dùng Script

Hình 9: Các vấn đề RPC/DCOM

Lưu ý rằng việc kết nối RPC được thành lập trước đó bằng máy tính nguồn (test124) với máy tính đích (test125), đang cố gắng triệu gọi DCOM để gọi EnableStatic Method của lớp Win32_NetworkAdapterConfiguration. (Để có thể xem được vấn đề này, bạn hãy nhìn vào phần cửa sổ Hex Details, nơi có thể xem tải trọng hex của gói RPC được hiển thị dưới dạng văn bản Unicode). Tuy nhiên trong việc cố gắng triệu gọi DCOM, máy tính nguồn vẫn nghĩ địa chỉ đích của máy tính mục tiêu là 172.16.11.125 (xem phần Frame Details trong hình vẽ).

Phần còn lại của ChangeIPAddress.vbs cũng rất thú vị để phân tích tuy nhiên chúng ta đã nhận ra được lý do tại sao kịch bản điều khiển xa không chạy đúng cách. Rõ ràng nó làm việc nếu chúng ta sử dụng cách giải quyết On Error Resume Next mà chúng ta đã đề cập đến trong bài viết trước.

Quản trị mạng Windows bằng Script - Phần 9: Tìm hiểu kịch bản điều khiển xa

Page 65: Quản lý các mạng Windows dùng Script

Lúc này bạn cần phải quay lại ôn và nghiên cứu một cách chi tiết các kỹ thuật của kịch bản điều khiển xa trước khi chúng ta tiến xa hơn trong vấn đề này. Một cách cũng tốt cho bạn đó là nhảy vào và thử mọi thứ, tuy nhiên cách làm này đôi khi lại đưa bạn gặp phải bức tường. Để tránh gặp phải bức tường này chúng ta phải tìm hiểu về những nền tảng của chúng.

Hai loại kịch bản điều khiển xa

Có hai loại kịch bản điều khiển xa. Loại thứ nhất là khi chúng ta chạy một kịch bản trên máy tính A và máy tính mục tiêu là B để thực hiện một số hành động trên nó. Trong thử nghiệm bằng sử dụng kịch bản ChangeIPAddress.vbs, chúng tôi đã thay đổi dòng:

strComputer = "."

thành:

strComputer = "xp2"

Nếu chúng tôi sử dụng dòng đầu trên ở trên và chạy kịch bản trên máy tính A thì sẽ thay đổi được địa chỉ IP của máy tính này. Còn nếu chúng ta sử dụng dòng thứ hai ở trên và chạy kịch bản trên máy tính A thì sẽ thay đổi được địa chỉ IP của máy tính B.

Kiểu thứ hai của kịch bản điều khiển xa và nó làm việc giống như vậy. Tôi là một quản trị viên, đã đăng nhập vào máy tính A và có một kịch bản muốn sử dụng để thực hiện một số công việc trên máy tính B. Tuy nhiên thay vì cố gắng chạy kịch bản trên máy tính A và mục tiêu là máy tính B, tôi muốn chạy kịch bản trực tiếp trên máy tính B. Chính vì vậy tôi đã đưa kịch bản từ máy tính A sang máy tính mục tiêu B và sau đó chạy nó ở đây. Tôi có thể thực hiện điều đó như thế nào? Nếu có một môi trường Active Directory sau đó tôi có thể thử và chạy kịch bản như kịch bản đăng nhập trên máy tính điều khiển xa. Chúng ta hãy xem thực hiện như thế nào trong bài tiếp theo, nhưng bây giờ hãy chú ý rằng có hai loại kịch bản điều khiển xa.

Chạy kịch bản trên máy tính nội bộ và nhắm đến máy tính điều khiển xa. Chạy kịch bản trực tiếp trên máy tính điều khiển xa.

Hãy diễn tả sự khác nhau giữa hai cách mô tả kịch bản điều khiển xa:

Kiểu thứ nhất liên quan đến việc kết nối đến máy tính điều khiển xa và sau đó chạy kịch bản. Kiểu thứ hay liên quan đến việc triển khai kịch bản cho máy tính điều khiển xa, sau đó chạy kịch bản.

Tìm hiểu về kết nối kịch bản điều khiển xa

Bây giờ chúng ta hãy tập trung vào kiểu đầu tiên của kịch bản điều khiển xa. Nó có nghĩa gì khi chạy một kịch bản trên máy tính cục bộ của bạn để kết nối đến một máy tính điều khiển xa và chạy ngược lại nó? Nó có 3 ý nghĩa:

Kết nối mạng Nhận dạng người dùng Cho phép thích hợp

1. Kết nối mạng

Với kịch bản để thực hiện điều gì đó trên máy tính điều khiển xa, trước tiên nó phải thành lập được kết nối mạng với máy tính điều khiển xa. Những vấn đề gì có thể ngăn cản kết nối mạng của bạn?

Page 66: Quản lý các mạng Windows dùng Script

Đầu tiên, nó có thể là vấn đề tên, nếu kịch bản của bạn không thể giải quyết được hostname của máy tính hoặc FQDN vào địa chỉ IP của nó thì kịch bản có thể bị lỗi.

Thứ hai, nó có thể là vấn đề tường lửa. Chúng ta đã nhìn thấy trong bài viết trước, để có được kịch bản WMI của chúng ta có thể chạy cho một máy tính điều khiển xa thì chúng ta phải mở ngoại lệ quản trị từ xa Remote Administration trong tường lửa Windows trên máy tính điều khiển xa. Bây giờ nếu bạn mở Windows Firewall applet từ Control Panel và chọn tab Exceptions thì sẽ không thấy hộp kiểm Remote Administration được gán nhãn mà bạn có thể chọn để mở ngoại lệ này. Lý do của điều này là Control Panel applet này có ý nghĩa chính dành cho người dùng gia đình sử dụng để cấu hình tường lửa của họ. Trong môi trường doanh nghiệp, nơi Active Directory được sử dụng, cách quản lý Windows Firewall được ưa thích là sử dụng Group Policy. Chúng ta đã thấy trong bài viết trước rằng thiết lập Group Policy mà chúng ta cần cấu hình như dưới đây:

Computer Configuration\Administrative Templates\Network\NetworkConnections\Windows Firewall\Domain Profile\Windows Firewall: Dho phép ngoại lệ quản trị từ xa trở về.

Khi bạn nhắm đến chính sách này đối với một máy tính điều khiển xa thì nó sẽ mở hai cổng TCP trên máy tính đó: cổng 445 và 135.

• Cổng TCP 445 là cổng dành cho lưu lượng đi vào Server Message Block (SMB), nếu cổng này bị khóa trên tường lửa của máy tính điều khiển xa thì bạn không chỉ không thể kết nối tới nó bằng WMI mà cũng không thể kết nối đến nó bằng các công cụ quản trị MMC chuẩn như Computer Management. Khi cổng bị khóa và bạn đang thử chạy các kịch bản đối với máy tính từ xa thì có thể gặp một số lỗi khó hiểu như “System error 53 has occurred. The network path was not found” – Lỗi hệ thống 53 xuất hiện. Đường dẫn mạng không được tìm thấy…

• Cổng TCP 135 là cổng dành cho lưu lượng vào Distributed COM (DCOM). Đặc biệt hơn, cổng 135 là cổng lắng nghe cho DCOM Service Control Manager (SCM), cung cấp các dịch vụ RPC cho việc thuyết minh các đối tượng COM.

Độ dài hay ngắn của nó là cả hai cổng TCP 135 và 445 cần phải mở trên tường lửa của máy tính từ xa nếu các truy vấn WMI chạy từ máy tính cục bộ đến sử dụng thành công RCP để kết nối dịch vụ WMI trên máy tính điều khiển xa và đến thuyết minh thành công các đối tượng DCOM trên máy tính từ xa.

2. Nhận dạng người dùng

Khi bạn chạy kịch bản cho một máy tính điều khiển xa và có thể thiết lập kết nối mạng với máy tính từ xa, sau đó kịch bản có thể thực hiện các hành động trên máy tính từ xa đó. Nhưng các hành động mà nó có thể thực hiện lại phụ thuộc vào sự nhận dạng với kịch bản nào đang chạy trên máy tính điều khiển. Ví dụ tôi đăng nhập vào máy tính A bằng sử dụng một tài khoản người dùng tên miền thông thường. Sau đó tôi chạy kịch bản ChangeIPAddress.vbs và nhắm nó vào máy tính điều khiển xa B. Kịch bản sử dụng RPC để kết nối đến dịch vụ WMI trên máy tính B và nó thay đổi địa chỉ IP của máy tính B. Nhưng bất thành. Lý do tại sao? Ai đang cố gắng thực hiện hành động này trên máy tính điều khiển xa? Trên máy tính cục bộ (máy tính A) bạn là người dùng và khi chạy kịch bản bằng mặc định nó là hiện thân cho nhận dạng của bạn, nghĩa là kịch bản sẽ thực hiện các hành động của nó bằng sự nhận dạng của bạn (tài khoản người dùng của bạn). Vì vậy kịch bản sẽ thay đổi địa chỉ IP của máy tính điều khiển xa, nó có hiệu quả đối với bạn, một người dùng trong miền, người đang thực hiện điều này. Mặt khác nó sẽ hỏng khi việc thay đổi yêu cầu đến sự ủy nhiệm quản trị viên cục bộ.

Vì vậy, khi bạn đang ngồi tại máy tính A, đã đăng nhập vào người dùng của miền và bạn vẫn muốn sử dụng

Page 67: Quản lý các mạng Windows dùng Script

kịch bản của mình để thay đổi địa chỉ IP của máy tính B. Bạn có thể thực hiện chúng như sau:

Kịch bản ChangeIPAddress.vbs của bạn có thể thay đổi như sau:

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

với

strUser = "Administrator" strPassword = “Pa$$w0rd” Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2", strUser, strPassword)

Vấn đề ở đây là không an toàn – mật khẩu của tài khoản quản trị viên cho máy tính từ xa có trong văn bản của kịch bản và có thể bị quan sát.

Vậy làm thế nào để có thể loại bỏ được hai dòng đầu tiên này và giấu các giá trị strUser và strPassword cho kịch bản như các đối số khi kịch bản được chạy? Tốt hơn vẫn là việc mã hóa cứng các giá trị này trong kịch bản, nhưng nếu ai đó có chương trình đang chạy (như Network Monitor 3.0) thì họ có thể lấy được các thông tin quan trọng và khi đó bạn đã thỏa hiệp máy tính từ xa của mình.

Sẽ như thế nào nếu bạn sử dụng một lệnh nâng cao như runas /user:Administrator cmd.exe và sau đó chạy kịch bản từ cửa sổ lệnh nâng cao mà không cần chỉ định các thông tin quan trọng khác? Đó có thể là giải pháp tốt nhất cho kịch bản từ xa, nơi bạn muốn bảo đảm kịch bản có sự nhận dạng thích hợp (thường quản trị nội bộ trên máy tính mục tiêu) dù cho nó khá phức tạp. Rõ ràng, bạn có thể đơn giản việc đăng nhập vào máy trạm làm việc như tài khoản quản trị miền và đơn giản mở một lệnh và chạy kịch bản.

3. Cho phép thích hợp

Bạn đang chạy kịch bản trên máy tính A và kịch bản được giả định để thực hiện một số hành động trên máy tính B. Kịch bản đã thành lập kết nối mạng với dịch vụ WMI trên máy tính B và đang cố gắng thực hiện các hành động của nó bằng sử dụng đúng nhận dạng (thường là các thông tin quản trị viên cục bộ) trên máy tính B. Những gì có thể làm cho kịch bản này bị hỏng tại đây? Không đủ sự cho phép! Nếu kịch bản đang cố gắng thực hiện một số hành động được điều khiển bởi ACL (như việc thay đổi một đối tượng file hoặc tạo một đối tượng trong Active Directory hoặc kích hoạt một đối tượng DCOM) và bạn không có sự cho phép thích hợp để thực hiện hành động đó thì kịch bản sẽ bị lỗi. Không may thay đó thường là phần khó nhất của kịch bản điều khiển xa khi có các cho phép NTFS, DCOM và nhiều kiểu cho phép khác trên nền Windows. Bạn có thể có các cho phép đúng nhưng không có quyền đúng, nghĩa là các quyền người dùng để thực hiện một số hành động. Ví dụ, nói rằng bạn muốn sử dụng kịch bản để xóa sự kiện đăng nhập trên máy tính điều khiển xa nhưng sự nhận dạng của bạn thiếu quyền bảo mật SeSecurityPrivilege trên máy tính từ xa đó thì khi đó kịch bản của bạn sẽ bị lỗi.

Có rất nhiều cái để học về kịch bản điều khiển xa. Chúng tôi sẽ tiếp tục giới thiệu với các bạn trong bài tiếp theo.

Quản lý mạng Windows bằng Script - Phần 10: Các thủ thuật của kịch bản điều khiển xa

Page 68: Quản lý các mạng Windows dùng Script

Trong các bài viết trước, chúng ta đã được giới thiệu về một số khái niệm và các vấn đề xung quanh kịch bản điều khiển xa trên nền Windows. Trong phần này chúng tôi sẽ tiếp tục giới thiệu cho các bạn hai thủ thuật liên quan đến kịch bản điều khiển xa này qua sử dụng kịch bản WMI được viết bằng VBScript.

Thủ thuật 1: Tạo Cscript.exe, cấu hình kịch bản mặc định trên các máy tính từ xa

Đây là thủ thuật đầu tiên và nó thực sự đơn giản nhưng cũng khá thông minh do đó chúng ta cần phải có một số kiến thức cơ bản để dễ dàng tiếp cận. Bảo đảm rằng bạn biết một số cách để khởi chạy kịch bản trên các máy tính Windows. Ví dụ, nếu bạn có kịch bản ChangeIPAddress.vbs trên một máy tính thì có thể khởi chạy nó bằng cách:

- Kích đúp vào file .vbs hoặc shortcut trỏ đến file. 

- Kích Start, sau đó kích Run, nhập vào ChangeIPAddress.vbs và kích OK. 

- Mở một cửa sổ lệnh và điều hướng đến thư mục có kịch bản, nhập vào ChangeIPAddress.vbs sau đó nhấn ENTER.

Điều gì sẽ xảy ra nếu bạn thực hiện những thứ này, câu trả lời đó phụ thuộc vào những thiết lập mặc định nào được đặt cho Windows Script Host (WSH) trên máy tính của bạn. Windows Script Host (WSH) là một ngôn ngữ kịch bản độc lập dùng cho các scripting engine, có nghĩa là WSH sử dụng scripting engine là VBScript để chạy các kịch bản VBScript, vì vậy WSH hành động như “môi trường” bên trong mà kịch bản của bạn chạy. Tuy nhiên WSH thực sự có hai cấu hình kịch bản mặc định: 

- Wscript.exe, cung cấp một hộp thoại trên Windows cho việc thiết lập các thuộc tính kịch bản và hiển thị đầu ra kịch bản. 

- Cscript.exe, cho phép cấu hình các thuộc tính kịch bản và hiển thị đầu ra kịch bản từ cửa sổ lệnh.

Hãy xem sự khác nhau giữa chúng trong trường hợp bạn không biết hoặc quên. Chúng tôi sẽ sử dụng kịch bản ChangeIPAddress.vbs từ phần 2 của loạt bài này để minh chứng. Hãy mở cửa sổ lệnh trên máy tính Windows Vista và sử dụng kịch bản này để thay đổi địa chỉ IP của máy tính thành 172.16.11.173. Bây giờ việc đầu tiên cần chú ý đó là thay đổi các thiết lập cấu hình mạng cần thiết những tiêu chuẩn quản trị cục bộ trên máy, để thực hiện điều này chúng ta cần kích chuột phải vào shortcut của cửa sổ lệnh dưới Accessories và chọn Run As Administrator. Khi thực hiện điều đó thì cửa sổ User Account Control (UAC) xuất hiện, kích Continue để tiếp tục (nếu tài khoản người dùng đầu tiên là một thành viên trong nhóm quản trị cục bộ trên máy) hoặc nhập vào các thông tin quan trọng của tài khoản quản trị cục bộ (nếu tài khoản chỉ là một thành viên của nhóm người dùng cục bộ trên máy).

Mở cửa sổ lệnh mức quản trị và đánh lệnh để thay đổi địa chỉ của máy tính (Hình 1).

Page 69: Quản lý các mạng Windows dùng Script

Hình 1: Thay đổi địa chỉ IP dùng kịch bản

Điều gì sẽ xảy ra khi chúng ta nhấn ENTER, khi nhấn xong một vài giây sau, hộp thoại dưới đây sẽ xuất hiện (Hình 1)

Hình 2: Đầu ra của kịch bản xuất hiện như một hộp thoại

Thông báo này đến từ đâu? Bạn hãy nhớ lại rằng kịch bản của chúng ta Change IPAddress.vbs gồm có các dòng dưới đây ở cuối của kịch bản:

'Display result or error code

If errEnableStatic=0 Then     Wscript.Echo "Adapter's IP address has been successfully changed to " & strAddressElse     Wscript.Echo "Changing the adapter's address was not successful. Error code " & errEnableStaticEnd If

Vậy những gì đang xảy ra là lệnh Wscript.Echo đang hiển thị đầu ra (nghĩa là hiển thị một hộp thoại) thay vì hiển thị đầu ra bên trong cửa sổ lệnh. Lý do là vì mặc định Wscript.exe có cấu hình kịch bản mặc định và cấu hình này được thiết lập cho những gì nó hiển thị đầu ra bằng cửa sổ giống như vậy.

Chúng ta có thể dừng các hành vi này và lấy đầu ra kịch bản để hiển thị bên trong cửa sổ lệnh được không? Có một cách có thể giải quyết được nhiệm vụ này đó là triệu gọi Cscript.exe được cấu hình kịch bản dòng lệnh khi chạy kịch bản. Bạn có thể thực hiện được điều này như hình 3 dưới đây:

Page 70: Quản lý các mạng Windows dùng Script

Hình 3: Sử dụng cscript.exe xuất đầu ra kịch bản bên trong cửa sổ lệnh

Tuy nhiên cách này có thể làm phiền bạn vì phải đánh cscript trước khi đánh tên kịch bản giống như vậy, vì vậy bạn có thể thiết lập Cscript.exe như một cấu hình kịch bản mặc định cho tất cả triệu gọi WSH bằng thực hiện này (Hình 4):

Hình 4: Tạo cscript.exe cho cấu hình mặc định

Bây giờ chúng ta có thể chạy kịch bản và hiển thị đầu ra của nó từ bên trong cửa sổ lệnh mà không cần phải đánh cscript trước (Hình 5):

Page 71: Quản lý các mạng Windows dùng Script

Hình 5: Khi Cscript.exe là cấu hình kịch bản mặc định thì đầu ra của kịch bản được hiển thị bên trong cửa sổ lệnh

Chúng ta có một nhóm kịch bản giống ChangeIPAddress.vbs mà muốn chạy từ xa bằng cách triển khai chúng đến các máy đích như kịch bản đăng nhập hoặc khởi động kịch bản bằng Group Policy. Bên cạnh đó một số kịch bản có các câu lệnh Wscript.Echo trong chúng tạo đầu ra kịch bản. Điều gì sẽ xảy ra khi một trong các kịch bản đó được triển khai cho máy tính điều khiển xa và chạy trên máy? Một loạt các cửa sổ sẽ xuất hiện trên màn hình desktop của người dùng như kịch bản chạy trên máy, và người dùng sẽ phải kích OK, OK và OK,… cho tới khi các cửa sổ bật ra này biến mất hết và kịch bản kết thúc công việc của nó. Vậy có cách nào để khắc phục hiện tượng này?

Chúng ta có thể khắc phục hiện tượng này bằng hai cách. Đầu tiên, bạn có thể soạn thảo tất cả các kịch bản xóa hoặc chú thích câu lệnh Wscript.Echo để kịch bản không tạo ra bất cứ đầu ra nào. Đó là một chút trở ngại, đặc biệt nếu bạn có một số lượng lớn kịch bản. Vì vậy phương pháp thứ hai là gì? Đây là một mẹo nhỏ mà chúng tôi muốn chia sẻ với bạn:

Trong môi trường Active Directory trong Group Policy đang được sử dụng để quản lý các máy tính desktop, bạn có thể thay đổi cấu hình kịch bản từ Wscript.exe thành Cscript.exe trên các máy tính trong một OU bằng các bước dưới đây:

1. Sử dụng Notepad để tạo một file văn bản có tên là ChangeToCscript.bat với hai dòng dưới đây trong nó:     @echo off     cscript //h:cscript //s

2. Mở GPO được liên kết đến OU và điều hướng đến Computer Configuration\Windows Settings\Scripts\Startup.

3. Kích đúp vào thiết lập chính sách khởi động Startup để mở trang thuộc tính của nó. 

4. Kích nút Show Files và copy/paste file ChangeToCscript.bat từ Windows Explorer vào thư mục con của SYSVOL, nơi các kịch bản khởi động được đặt.

5. Kích nút Add trên trang thuộc tính cho thiết lập chính sách khởi động.

6. Kích nút Browse và chọn ChangeToCscript.bat.

Page 72: Quản lý các mạng Windows dùng Script

7. Đóng tất cả các trang thuộc tính.

8. Việc bổ sung thêm kịch bản khởi động này sẽ làm cho kịch bản mặc định trên các máy tính mục tiêu được chuyển từ Wscript.exe thành Cscript.exe trong lần khởi động lại tiếp theo của các máy tính đó, và điều này sẽ làm việc mà không cần quan tâm đến người dùng mục tiêu là người dùng chuẩn hay quản trị viên cục bộ.

Lưu ý: ChangeToCscript.bat phải được chạy như một kịch bản khởi động và không là kịch bản đăng nhập. Nếu bạn chạy nó như một kịch bản đăng nhập thì nó sẽ chỉ làm việc khi người dùng mục tiêu là quản trị viên trên máy tính.

Bạn có thể làm gì với chỉ một file có hai dòng? Bây giờ bạn có thể triển khai các kịch bản mà bạn muốn đối với các máy tính mục tiêu và không phải lo lắng về người dùng gặp phải rất nhiều cửa sổ pop-up xuất hiện trên màn hình của họ.

Thủ thuật 2: Thực hiện “runAs” mà không cần các thông tin chỉ định

Thủ thuật thứ hai được đệ trình với chúng tôi bởi một trong các độc giả sau khi đã đọc các phần trước loạt bài này. Chúng tôi được phép trích dẫn trực tiếp từ email giải thích của anh ấy:

FYI là cách tôi thực hiện ‘runAs’ mà không cần phải nhập vào các thông tin quan trọng khác, là sử dụng tài khoản quản trị viên cục bộ cho WMI, sau đó lưu mật khẩu quản trị trong một file văn bản trên một mạng chia sẻ được bảo vệ bởi sự cho phép NTFS. Ví dụ, nếu ‘tech1’, ‘tech4’ và ‘tech5’ là các tài khoản miền thông thường (không phải quản trị miền), nhưng các người dùng này được thẩm định để chạy kịch bản WMI, sau đó tôi cho phép truy cập NTFS các tài khoản này thành file văn bản, file văn bản này gồm có mật khẩu quản trị cục bộ. Sau đó có kịch bản nhập passwword và kết nối bằng sử dụng Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2", strComputer & “\Administrator”,

strImportedPassword).

Ở trên là không đúng 100%. Tôi sử dụng.

Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator") objSWbemLocator.Security_.Privileges.AddAsString("SeSecurityPrivilege") Set objWMIService = objSWbemLocator.ConnectServer(strComputer, "root\cimv2", strComputer & "\administrator", strPWD, "", "", &H80) Set objReg = objSWbemLocator.ConnectServer(strComputer, "root\default", strComputer & "\administrator", strPWD, "", "", &H80)

Set oReg = objReg.Get("StdRegProv")

…để hoàn thành thứ tương tự.

Việc kết nối với tài khoản quản trị cục bộ lại có hiệu quả thú vị khác; nó không để lại bản sao profile tài khoản quản trị miền của bạn trên máy tính trong Documents and Settings. Khi sử dụng tài khoản miền của mình, tôi đã có một số người dùng hỏi “Tại sao bạn được kết nối vào máy tính của tôi” và việc phân vân rằng đang xảy ra việc rình mò gì đó. Bằng cách sử dụng tài khoản quản trị cục bộ, họ không nhận ra bất cứ ai đã kết nối (họ được khóa không cho xem các bản ghi bảo mật).

Với bản ghi, trong thực tế chúng ta có một cặp mật khẩu quản trị cục bộ khác nhau sử dụng ở đây; vì vậy kịch bản nhập vào một danh sách và thử từng cái một cho tới khi thành công hoặc hết các tùy chọn.

Page 73: Quản lý các mạng Windows dùng Script

Quản lý mạng Windows bằng Script - Phần 11: Các thủ thuật kịch bản khác

Trong phần trước của loạt bài này chúng ta đã biết hai thủ thuật cho kịch bản điều khiển xa. Trong phần trước chúng ta đã xem thêm hai mẹo kịch bản nữa. Mẹo đầu tiên, thủ thuật kịch bản điều khiển xa từ một độc giả, mẹo thứ hai, một ví dụ thế giới thực được dùng để thể hiện cách sử dụng the Windows Management Instrumentation Command-line (WMIC).

Thủ thuật 1: Thủ thuật “runas” nhưng với sự mã hóa

Thủ thuật kịch bản đầu tiên được đệ trình bởi độc giả Steven Beard đến từ Anh. Steve đưa ra một cách hoàn toàn khác để gọi lệnh “runas” từ bên trong kịch bản và điều này có thể hữu dụng trong các môi trường hoạt động kinh doanh như thế nào. Hãy lắng nghe những gì mà Steve đã nói:

Tôi đã sử dụng vb script trong nhiều năm qua để quản trị miền Windows của tôi nhưng chưa bao giờ hiểu hết về WMI mà chỉ là những gì tôi thực sự cần thiết. Mặc dù phần cuối cùng của các bạn quan tâm đến hàm runas là rất tốt, nhưng tôi sử dụng nó theo nhiều cách khác nhau, bạn có thể xem dưới đây:

Set WshShell = CreateObject("Wscript.Shell") Set WshEnv = WshShell.Environment("PRocess") WshShell.Run "runas.exe /user:" & "domain\user" & " " & Chr(34) & "cscript c:\PCQuery.vbs" & Chr(34) Wscript.Sleep 800 WshShell.AppActivate WshEnv("SystemRoot") & "\system32\runas.exe" Wscript.Sleep 200 WshShell.SendKeys "PASSWORD" & "~" Wscript.Sleep 500 Set WshShell = Nothing

Set WshEn = Nothing

Một cách cơ bản, tôi giấu tất cả các kịch bản cần đến quyền quản trị trong kịch bản ở trên bằng sử dụng runas, sau đó đợi và sử dụng sendkeys để gửi mật khẩu.

Đây là vấn đề tương tự kịch bản được chuyển đến bạn bằng một độc giả khác. Các mật khẩu gửi không được mã hóa xuyên mạng, đó là lý do tại sao tôi viết email này.

Tôi sử dụng script encoder (cơ bản chạy kịch bản thông qua bộ mã hóa và các bảng băm bằng nhiều thuật toán mã hóa), sau đó kết thúc với một file .vbe thay vì .vbs.

Tôi đảm bảo nó vẫn có thể bị crack nhưng vẫn tốt hơn là không mã hóa.

Thủ thuật 2: Truy vấn cho quản trị viên cục bộ bằng WMIC

Thủ thuật thứ hai này sẽ được dựa trên vấn đề cuộc sống thực. Một độc giả đã liên hệ với chúng tôi hỏi một câu hỏi đơn giản: làm thế nào bạn có thể liệt kê các tài khoản quản trị viên cục bộ trên máy tính điều khiển xa? Kịch bản là độc giả có nhiều máy trạm Windows XP, các máy là phần khởi đầu của một nhóm, và người dùng có quyền quản trị cục bộ trên các máy tính đó (nghĩa là các tài khoản cục bộ của họ là thành viên của nhóm quản trị cục bộ trên các máy tính này). Cuối cùng mạng cũng đã được di trú đến một miền Active Directory và người dùng được trao các tài khoản mới với tư cách là thành viên nhóm toàn cục Domain Users. Sau đó, một ngày quản trị viên được thông báo rằng người dùng dường như có nhiều đặc quyền hơn những gì mà anh ta đã gán và anh ta đã phát hiện ra rằng các tài khoản quản trị cục bộ cũ đã không được phát hiện từ máy trạm của anh ta, anh ta đã đăng nhập bằng một tài khoản quản trị cục bộ đó khi tài khoản domain user

Page 74: Quản lý các mạng Windows dùng Script

không cho anh ta có được đủ quyền điều khiển trên máy trạm. Quản trị viên nhận ra điều này có thể là một vấn đề nghiêm trọng khi (a) nó can thiệp vào chính sách bảo mật của công ty và (b) cho phép người dùng đăng nhập vào các máy trạm của họ như các quản trị viên, nghĩa là họ có thể xử lý đơn giản trên máy trạm của họ khi quản trị cục bộ có thể thực hiện gần như bất cứ cái gì trên các máy của họ, tuy nhiên điều này có thể dẫn đến chi phí hỗ trợ cao hơn.

Bây giờ để làm cho nó phức tạp hơn chút ít, nhóm quản trị cục bộ Administrators đính kèm trên máy trạm được đặt lại tên thành một tên nào đó và tài khoản người dùng Administrator cục bộ đính kèm cũng được đặt lại tên. Kiểm tra máy trạm thứ hai đã phát hiện ra rằng nhóm cục bộ quản trị viên đính kèm và tài khoản người dùng cục bộ cũng đều được đặt lại tên trên máy tính này, tuy nhiên chúng được đặt lại tên khác với máy trạm đầu tiên! Thực sự là một sự phức tạp gây đau đầu! Việc giải quyết điều này giống như nó đòi hỏi phải đăng nhập vào các máy trạm và đào bới tìm kiếm tất cả người dùng và các nhóm cục bộ trên mỗi máy tính để xác định tài khoản người dùng cục bộ nào là quản trị cục bộ trên máy đó, hoặc tìm các khác để xác định thông tin này. Có thể là một kịch bản?

Bạn có thể giải quyết bằng kịch bản nhưng thay vì làm điều đó, bạn hãy thử thực hiện một cái gì đó khác và sử dụng Windows Management Instrumentation Command-line (WMIC) xem sao. WMIC cơ bản là một công cụ (một trình thông dịch lệnh) cho phép truy vấn thông tin WMI trực tiếp từ dòng lệnh thay vì phải thực hiện nó bên trong một kịch bản. WMIC có thể được sử dụng theo hai cách: tương tác (đưa ra một lệnh tại một thời điểm nào đó ở cửa sổ lệnh) hoặc trong các file.

Sử dụng WMIC tương tác

Ví dụ, hãy cho rằng nhóm quản trị cục bộ đính kèm và tài khoản người dùng cục bộ không được đặt lại tên trên hệ thống. Nếu đây là một trường hợp thì bạn có thể sử dụng WMIC tương tác để hiển thị danh sách các thành viên của nhóm quản trị cục bộ bằng cách mở cửa sổ lệnh và đánh vào đó lệnh sau:

C:\Documents and Settings\myself>wmic path win32_groupuser where (groupcomponent="win32_group.name=\"administrators\",domain=\"%computername%\"") GroupComponent??????????????????? ????????PartComponent win32_group.domain="XP191",name="administrators"? \\XP191\root\cimv2:Win32_UserAccount.Domain="XP191",Name="Administrator" win32_group.domain="XP191",name="administrators"? \\XP191\root\cimv2:Win32_UserAccount.Domain="XP191",Name="sjones"???? win32_group.domain="XP191",name="administrators"? \\XP191\root\cimv2:Win32_UserAccount.Domain="XP191",Name="gsmith"??????? win32_group.domain="XP191",name="administrators"? \\XP191\root\

cimv2:Win32_Group.Domain="TEST",Name="Domain Admins"

Xem cột thứ hai, chúng ta có thể thấy nhóm quản trị cục bộ trên máy tính này có 3 tài khoản người dùng cùng với nó: quản trị viên, sjones và gsmith. Thêm vào đó, nhóm quản trị miền toàn cục là một thành viên của nhóm quản trị cục bộ trên hệ thống này.

Bây giờ nhóm quản trị cục bộ đính kèm trên hệ thống được đổi tên thành gì? Chạy lệnh trên bạn sẽ có kết quả dưới đây:

C:\Documents and Settings\myself>wmic path win32_groupuser where (groupcomponent="win32_group.name=\"administrators\",domain=\"%computername%\"")No Instance(s) Available.

Tại sao lệnh bị hỏng? Rõ ràng bởi vì tên của nhóm tồn tại đã truy vấn bởi mã cứng trong lệnh. Nhưng nếu nhóm quản trị cục bộ đính kèm được đặt lại tên thì bạn có thể xác định tên mới của nó như thế nào? Câu trả

Page 75: Quản lý các mạng Windows dùng Script

lời đơn giản là nhóm này có thể được đặt tên là gì thì nó vẫn giống nhóm cũ ở bề ngoài. Hay nó theo cách khác, nó là bộ nhận dạnh bảo mật (SID) không thay đổi và vẫn là S-1-5-32-544 (bạn có thể xem thêm tại đây để có thêm danh sách về các SID).

Vậy chúng ta có thể xác định tên của nhóm là gì nếu biết SID của nó? Chúng ta có thể sử dụng lại WMIC một lần nữa, giống như dưới đây:

C:\Documents and Settings\myself>wmic group where (sid = "S-1-5-32-544" and localaccount = true) get nameName             

JustAnotherGroup 

Vậy nhóm quản trị đính kèm trên hệ thống này được đặt lại tên thành JustAnotherGroup!

Dù thế nào đi chăng nữa bây giờ chúng ta cũng biết được tên của nhóm này, chúng ta có thể sử dụng WMIC để truy vấn các thành viên của nó:

C:\Documents and Settings\myself>wmic path win32_groupuser where (groupcomponent="win32_group.name=\"justanothergroup\",domain=\"%computername%\"") GroupComponent PartComponent win32_group.domain="XP191",name="justanothergroup" \\XP191\root\cimv2:Win32_UserAccount.Domain="XP191",Name="JustAnotherUser" win32_group.domain="XP191",name="justanothergroup" \\XP191\root\cimv2:Win32_UserAccount.Domain="XP191",Name="sjones" win32_group.domain="XP191",name="justanothergroup" \\XP191\root\cimv2:Win32_UserAccount.Domain="XP191",Name="gsmith" win32_group.domain="XP191",name="justanothergroup" \\XP191\root\

cimv2:Win32_Group.Domain="TEST",Name="Domain Admins"

Và chúng ta có thể xem từ đầu ra lệnh có 3 quản trị cục bộ trên máy tính này: sjones, gsmith và JustAnotherUser. Rõ ràng nhóm toàn cục quản trị miền là một thành viên của JustAnotherGroup.

Sử dụng WMIC trong các file Batch

Ngược lại nếu chúng ta không muốn đăng nhập vào máy trạm và chạy các lệnh WMIC trên, thì chúng ta phải làm như thế nào? WMIC có thể được chạy trên các máy tính điều khiển xa bằng cách sử dụng khóa chuyển đổi /node:””, khóa được cung cấp để bạn có thể kích hoạt Remote Administration trên các máy tính mục tiêu (bạn có thể thực hiện bằng cách sử dụng Group Policy như đã được giải thích trong phần 6). Vậy thừa nhận rằng bạn đã thực hiện điều đó, hãy mở cửa sổ lệnh trên máy chủ trung tâm của chúng ta (bộ điều khiển miền) và đưa ra hai lệnh tương tự WMIC, nhưng lúc này máy trạm điều khiển xa có tên là XP191. Đầu tiên chúng ta lấy tên của nhóm quản trị cục bộ đính kèm trên máy tính điều khiển xa.

C:\Documents and Settings\Administrator>wmic /node:"xp191" group where (sid = "S-1-5-32-544" and localaccount = true) get nameName

JustAnotherGroup

Bây giờ chúng ta sử dụng kết quả này để lấy danh sách các thành viên của nhóm:

C:\Documents and Settings\Administrator>wmic /node:"xp191" path win32_groupuser where

Page 76: Quản lý các mạng Windows dùng Script

(groupcomponent = "win32_group.name=\"justanothergroup\",domain=\"xp191\"") GroupComponent?????????????????????????????PartComponent win32_group.domain="xp191",name="justanothergroup"? \\XP191\root\cimv2:Win32_UserAccount.Domain="XP191",Name="JustAnotherAccount" win32_group.domain="xp191",name="justanothergroup"? \\XP191\root\cimv2:Win32_UserAccount.Domain="XP191",Name="sjones" win32_group.domain="xp191",name="justanothergroup"? \\XP191\root\cimv2:Win32_UserAccount.Domain="XP191",Name="gsmith" win32_group.domain="xp191",name="justanothergroup"? \\XP191\root\cimv2:Win32_Group.Domain="TEST",Name="Domain Admins"

Kết quả giốnh như những gì chúng ta mong đợi. Từ điểm này, bạn hoàn toàn dễ dàng viết một file đơn giản để truy vấn tất cả các máy trạm trên mạng và lưu kết quả trong một file văn bản để có thể phân tích về sau.

Kết luận

WMIC quả thực có nhiều thú vị, tuy nhiên đôi khi cũng khó hiểu. Chúng ta sẽ nghiên cứu về sử dụng nó trong các phần tiếp theo.

Quản lý mạng Windows bằng Script - Phần 12: Các thuộc tính của lớp WMI

Quay trở lại phần ba của loạt bài này, chúng ta đã phát triển kịch bản đơn giản có tên displayTimeZone.vbs để hiển thị  thiết lập vùng thời gian hiện hành trên máy tính của bạn:

Option ExplicitOn Error Resume NextDim strComputerDim strWMINamespaceDim strWMIQueryDim objWMIServiceDim colItemsDim 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

Khi tôi chạy kịch bản này, nó cho kết quả như sau:

C:\scripts>DisplayTimeZone.vbsMicrosoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

(GMT-06:00) Central Time (US & Canada)

Page 77: Quản lý các mạng Windows dùng Script

Làm thế nào tôi biết được đó là thuộc tính chính của lớp Win32_TimeZone gồm có thông tin mà tôi muốn hiển thị? Bằng cách đọc các chỉ dẫn về nó tại đây mà tôi có thể biết điều đó. Trong thực tế, trang MSDN này cho chúng ta biết được rằng thuộc tính Description cơ bản trả về objItem.Description và các kết quả tương tự.

Trang MSDN này còn cho chúng ta biết thêm gì nữa về lớp Win32_TimeZone? Điều gì sẽ xảy ra nếu tôi muốn tìm ra tháng nào thực hiện việc đó ảnh hưởng trên máy tính? Nếu đọc qua trang này thì bạn sẽ có được thông tin liên quan đế thuộc tính này (DaylightMonth).

DaylightMonth Data type: uint32Access type: Read-only

Month when the transition from standard time to daylight saving time occurs on an operating system.

Value Meaning 10x1 January 20x2 February 30x3 March 40x4 April 50x5 May 60x6 June 70x7 July 80x8 August 90x9 September 100xA October 110xB November 12

0xC December

Để sử dụng thông tin này, đơn giản tôi chỉ thay đổi dòng WScript.Echo objItem.Caption thành WScript.Echo objItem.DaylightMonth và đây là những gì tôi nhận được khi chạy kịch bản này:

C:\scripts>DisplayTimeZone.vbsMicrosoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

3

Liệt kê các thuộc tính của một lớp

Bây giờ chúng ta có thể tiếp tục quá trình bằng cách thay đổi thuộc tính <property> trong WScript.Echo objItem.<property>  và vì vậy từ từ làm việc thông qua hiển thị từng cái một trong các thuộc tính của lớp Win32_TimeZone, nhưng đây có phải là cách dễ dàng hơn? Chúng ta có thể hiển thị được các thuộc tính của lớp này trong một kịch bản mà không cần đặt tên chúng trong kịch bản? Điều này thực hiện được nhưng trước khi thực hiện hãy thử và liệt kê số các thuộc tính của lớp này. Đây là cách chúng ta thực hiện:

Page 78: Quản lý các mạng Windows dùng Script

Option ExplicitOn Error Resume NextDim strComputerDim strWMINamespaceDim strWMIQueryDim objWMIServiceDim colItemsDim objItem

strComputer = "."strWMINamespace = "\root\CIMV2"strWMIQuery = ":Win32_TimeZone"

Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace & strWMIQuery)WScript.Echo "Number of properties of " & strWMIQuery & " class is " &

objWMIService.Properties_.count

Đây là kết quả chạy kịch bản mới này, kịch bản mà chúng ta sẽ gọi nó là DisplayClassProperties.vbs:

C:\scripts>DisplayClassProperties.vbsMicrosoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

Number of properties of :Win32_TimeZone class is 24

Xem một bảng kiểm kê các thuộc tính tại Win32_TimeZone MSDN sẽ cho chúng ta thấy con số 24 là hoàn toàn chính xác, điều đó có nghĩa là lớp Win32_TimeZone có 24 thuộc tính trong tổng số.

Kịch bản mới này làm việc như thế nào? Đầu tiên bạn lưu ý rằng thay vì kết nối đến không gian tên mặc định ("\root\CIMV2") trên máy tính cục bộ (“.”) chúng ta kết nối trực tiếp đến lớp Win32_TimeZone trên máy tính. Hay nói theo cách khác, dòng:

Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace &

strWMIQuery)

có thể được thay thế bởi

Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2:Win32_TimeZone")

và nó sẽ thực hiện các công việc một cách tương tự. Một điều khác mà bạn sẽ chú ý là một thứ trong dòng cuối cùng của kịch bản:

objWMIService.Properties_.count

Chúng ta biết về các thuộc tính (như <object>.<property>) và các phương pháp (<object>.<method>) từ phần đầu tiên của loạt bài này, nhưng objWMIService.Properties_.count có hai chu kỳ trong nó. Điều gì sẽ xảy ra ở đây? Chúng ta hãy quay lại dòng này một lần nữa:

Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace &

strWMIQuery)

những gì chúng ta đã nhìn thấy tương đương với

Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2:Win32_TimeZone")

Page 79: Quản lý các mạng Windows dùng Script

Biệt danh trong lệnh WMI này là winmgmts:\\.\root\CIMV2:Win32_TimeZone và nó định nghĩa đường dẫn đến lớp WMI mà chúng ta quan tâm trong việc tăng truy cập, khi bạn sử dụng hàm GetObject trên biệt danh này thì nó sẽ trả về một đối tượng SwbemObject, đối tượng này sau đó được gán cho biến objWMIService bằng lệnh Set. (Chính xác hơn, hàm GetObject trả lại một tham chiếu cho đối tượng SwbemObject đã được cung cấp bởi thành phần COM).

Nói cách khác, khi lệnh

Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2:Win32_TimeZone")

được thực thi, thì chúng ta sẽ có một đối tượng SwbemObject được trả về. Các đối tượng có các thuộc tính, vì vậy những thuộc tính gì mà đối tượng SwmebObject có được? Một thuộc tính được gọi là Properties_ và sử dụng kí hiệu chuẩn <object><properties> điều này có nghĩa là Properties_ property của một đối tượng SwebmObject sẽ được định nghĩa bởi SWbemObject.Properties_ ( đường gạch dưới từ là phần tên của thuộc tính). Bạn có thể đọc thêm về SWbemObject.Properties_ property của đối tượng SwebmObject trên trang này, và nó sẽ cho bạn thấy rằng thuộc tính này là “một bộ sưu tập các thuộc tính của lớp hiện tại” hoặc theo cách nói khác, SWbemObject.Properties_ property là một bộ sưu tập. Bạn cũng nên nhớ rằng một bộ sưu tập là một loại đối tương gồm có nhiều thành phần (thành phần đó có thể là các đối tượng khác hoặc các thuộc tính nhưng không phải là các phương pháp).

Quả thực SWbemObject.Properties_ là một bộ sưu tập (một kiểu đối tượng) và khi đối tượng có các thuộc tính thì bạn có thể sử dụng các thuộc tính này. Một thuộc tính mà một bộ sưu tập có là .count, nó có thể trả về số các thuộc tính của đối tượng, nghĩa là <collection>.<count> trả về số các thành phần trong bộ sưu tập. Điều này nghĩa là SWbemObject.Properties_.count là một thuộc tính .count của SWbemObject.Properties_ object, vì vậy xuất hiện hai chu kỳ thay vì một chu kỳ thông thường trong cú pháp <object>.<property>. Ít nhất, đó là cách hiểu vấn đề này, nhưng bạn nên nhớ rằng chúng tôi không phải là những nhà phát triển – mà cũng chỉ là một người đam mê giống như bạn, những người đang tìm hiểu kịch bản để phục vụ công việc của mình!

Hiển thị các thuộc tính của lớp

Bây giờ chúng ta có thể liệt kê các thuộc tính của lớp Win32_TimeZone, có thể trả về tên của các thuộc tính như thế nào? Bằng cách nối thêm các dòng dưới đây vào phần cuối của kịch bản DisplayClassProperties.vbs:

For Each objItem in objWMIService.Properties_    Wscript.Echo "Property: " & objItem.name

Next

Đây là những gì chúng ta có khi chạy kịch bản:

C:\scripts>DisplayClassProperties.vbsMicrosoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

Number of properties of :Win32_TimeZone class is 24Property: BiasProperty: CaptionProperty: DaylightBiasProperty: DaylightDayProperty: DaylightDayOfWeekProperty: DaylightHourProperty: DaylightMillisecondProperty: DaylightMinuteProperty: DaylightMonth

Page 80: Quản lý các mạng Windows dùng Script

Property: DaylightNameProperty: DaylightSecondProperty: DaylightYearProperty: DescriptionProperty: SettingIDProperty: StandardBiasProperty: StandardDayProperty: StandardDayOfWeekProperty: StandardHourProperty: StandardMillisecondProperty: StandardMinuteProperty: StandardMonthProperty: StandardNameProperty: StandardSecond

Property: StandardYear

Kiểm tra trang MSDN trước, trang đã mô tả về lớp Win32_TimeZone, chúng ta có thể thấy ở trên có tên của các thuộc tính lớp.

Kết luận

Sức mạnh của phương pháp này là nó cho phép chúng ta liệt kê tên các thuộc tính của lớp WMI, vì vậy chúng ta có thể học thêm về chúng (nhớ rằng trong phần 3 của loạt bài này chúng ta đã thấy cách liệt kê các lớp WMI của một không gian tên và cùng với danh sách đó chúng ta có thể khám phá và thấy được những gì chúng ta có thể quản lý thông qua sử dụng WMI).

Ví dụ, nếu chúng ta muốn liệt kê danh sách các thuộc tính của lớp Win32_BootConfiguration WMI bằng sử dụng kịch bản DisplayClassProperties.vbs, tất cả những gì cần thực hiện là thay đổi dòng:

strWMIQuery = ":Win32_TimeZone"

thành dòng như dưới đây:

strWMIQuery = ":Win32_BootConfiguration"

Khi chúng ta thực hiện thay đổi này và chạy lại kịch bản thì sẽ có được kết quả:

C:\scripts>DisplayClassProperties.vbsMicrosoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

Number of properties of :Win32_BootConfiguration class is 9Property: BootDirectoryProperty: Caption      Property: ConfigurationPath    Property: Description  Property: LastDrive    Property: Name  Value:Property: ScratchDirectory     Property: SettingID   

Property: TempDirectory

Chúng tôi khuyên bạn nên sử dụng phần bài viết này cùng với phần ba để khai thác lớp WMI và các thuộc tính khác của chúng, ngoài ra chúng ta có thể xem chi tiết hơn về sức mạnh của việc sử dụng WMI để quản lý máy tính Windows trong các bài sau của loạt bài này, mời các bạn đón đọc.

Page 81: Quản lý các mạng Windows dùng Script

Quản lý mạng Windows bằng Script - Phần 13: Kịch bản trả về tất cả các giá trị

Trong phần trước của loạt bài này chúng ta đã đến với kịch bản có tên gọi là DisplayClassProperties.vbs, đây là kịch bản hiển thị tên các thuộc tính của lớp WMI. Đây là những gì của nội dung kịch bản, bằng sử dụng Win32_BootConfiguration như một lớp, chúng ta đang kết nối vào biệt danh WMI:

Option ExplicitOn Error Resume NextDim strComputerDim strWMINamespaceDim strWMIQueryDim objWMIServiceDim colItemsDim objItem strComputer = "."strWMINamespace = "\root\CIMV2"strWMIQuery = ":Win32_BootConfiguration" Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace & strWMIQuery)WScript.Echo "Number of properties of " & strWMIQuery & " class is " & objWMIService.Properties_.count For Each objItem in objWMIService.Properties_    Wscript.Echo "Property: " & objItem.nameNext

Khi chạy kịch bản này (sử dụng các thông tin quản trị cục bộ) trên máy tính Windows XP (với Cscript.exe được cấu hình từ trước như một kịch bản Windows mặc định), kết quả cho được như sau:

C:\scripts>DisplayClassProperties.vbsMicrosoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved. Number of properties of :Win32_BootConfiguration class is 9Property: BootDirectoryProperty: CaptionProperty: ConfigurationPathProperty: DescriptionProperty: LastDriveProperty: NameProperty: ScratchDirectoryProperty: SettingID

Property: TempDirectory

Như đã đề cập đến trong phần cuối, kịch bản này có thể dễ dàng được tùy chỉnh để hiển thị tên thuộc tính của bất kỳ lớp WMI nào. Ví dụ, nếu muốn hiển thị tất cả tên thuộc tính trong lớp Win32_DiskPartition, chúng ta chỉ cần thay đổi dòng:

strWMIQuery = ":Win32_BootConfiguration"

thành:

strWMIQuery = ":Win32_DiskPartition"

Page 82: Quản lý các mạng Windows dùng Script

Khi chạy lại kịch bản thì kết quả thu được sẽ là:

C:\scripts>DisplayClassProperties.vbsMicrosoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved. Number of properties of :Win32_DiskPartition class is 34Property: AccessProperty: AvailabilityProperty: BlockSizeProperty: BootableProperty: BootPartitionProperty: CaptionProperty: ConfigManagerErrorCodeProperty: ConfigManagerUserConfigProperty: CreationClassNameProperty: DescriptionProperty: DeviceIDProperty: DiskIndexProperty: ErrorClearedProperty: ErrorDescriptionProperty: ErrorMethodologyProperty: HiddenSectorsProperty: IndexProperty: InstallDateProperty: LastErrorCodeProperty: NameProperty: NumberOfBlocksProperty: PNPDeviceIDProperty: PowerManagementCapabilitiesProperty: PowerManagementSupportedProperty: PrimaryPartitionProperty: PurposeProperty: RewritePartitionProperty: SizeProperty: StartingOffsetProperty: StatusProperty: StatusInfoProperty: SystemCreationClassNameProperty: SystemNameProperty: Type

Hiển thị các giá trị của mỗi thuộc tính

Ở đây chúng ta quay lại để sử dụng Win32_BootConfiguration như một lớp, nếu thay đổi để kịch bản sẽ liệt kê không chỉ tên của tất cả các thuộc tính mà còn cả giá trị của chúng thì bạn chỉ cần thay đổi dòng:

Wscript.Echo "Property: " & objItem.name

thành:

Wscript.Echo "Property: " & objItem.name & vbTab & "Value: " & objItem.value

Kết quả khi chạy:

C:\scripts>DisplayClassProperties.vbsMicrosoft (R) Windows Script Host Version 5.6Copyright (C) Microsoft Corporation 1996-2001. All rights reserved. Number of properties of :Win32_BootConfiguration class is 9Property: BootDirectory Value:

Page 83: Quản lý các mạng Windows dùng Script

Property: Caption       Value:Property: ConfigurationPath     Value:Property: Description   Value:Property: LastDrive     Value:Property: Name  Value:Property: ScratchDirectory      Value:Property: SettingID     Value:Property: TempDirectory Value:

Kết quả các giá trị đều là trống. Tại sao lại như vậy?

Đây là những gì đang tiếp tục, hãy xem dòng này:

Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace & strWMIQuery)

Việc đưa vào các giá trị của mỗi biến chúng ta có thể ghi lại dòng này như sau:

Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2:Win32_BootConfiguration")

Lưu ý rằng chúng ta đang kết nối đến một lớp WMI cụ thể (Win32_BootConfiguration) trong biệt danh WMI để có thể trả về một bộ gồm có các thuộc tính của lớp này. Sau đó chúng ta muốn hiển thị tên và giá trị của mỗi thuộc tính. Nhưng các giá trị được trả về NULL (trống rỗng) là bởi vì chưa kết nối được với nstance cụ thể của lớp này. WMI Glossary nói rằng một instance là “một thể hiện của thế giới thực đã quản lý đối tượng kèm với một lớp cụ thể” và “các instance gồm có giá trị thực” và giá trị thực này là những gì chúng ta muốn. Vậy có thể kết nối đến một instance của một lớp như thế nào?

Để kết nối tới instance của một lớp, bạn cần phải chỉ định instance riêng biệt bằng cách sử dụng key property của lớp. Chúng ta có thể xem key property là một thuộc tính cung cấp bộ nhận dạng cần thiết cho một instance của lớp và các key property được đánh dấu bằng Key qualifier trong tài liệu MSDN. Hãy xem trang MSDN về cấu hình lớp Win32_BootConfiguration để có thể biết thêm về key property cho lớp này. Hình 1 hiển thị một phần của trang này, chỉ ra cho bạn cách phân biệt key property của lớp:

Page 84: Quản lý các mạng Windows dùng Script

Hình 1: Key property cho lớp Win32_BootConfiguring

Từ trang MSDN này, chúng ta có thể thấy được rằng key property cho lớp Win32_BootConfiguration là Name. Điều này nghĩa là chúng ta cần phải chỉ định một giá trị cho thuộc tính này trong chuỗi biệt danh WMI nếu chúng ta muốn kết nối đến một instance cụ thể của lớp để lấy các giá trị của mỗi thuộc tính lớp. Hay nói cách khác, tất cả những gì cần phải thực hiện là thay đổi dòng:

strWMIQuery = ":Win32_BootConfiguration"

thành:

strWMIQuery = ":Win32_BootConfiguration.Name='SOMETHING'"

Tại “SOMETHING” là giá trị thuộc tính tên của một instance cụ thể trong lớp.

Chúng ta có thể tìm thấy giá trị key property của một instance cụ thể của lớp như thế nào? Có một cách là sử dụng Windows Management Instrumentation Tester (wbemtest.exe). Bắt đầu bằng đánh wbemtest tại cửa sổ lệnh để bạn có thể mở được cửa sổ như dưới đây:

Page 85: Quản lý các mạng Windows dùng Script

Hình 2: Windows Management Instrumentation Tester

Kích nút Connect và kết nối đến không gian tên root\cimv2:

Hình 3: Kết nối đến lớp Win32_BootConfiguration

Page 86: Quản lý các mạng Windows dùng Script

Kích Connect để quay về cửa sổ chính, nơi có tất cả các nút hiển thị ở đây:

Hình 4: Đã kết nối đến lớp

Kích nút Enum Instances và đánh tên lớp để có thể hiển thị được tất cả các instance của lớp:

Hình 5: Hiển thị các instance của lớp

Cuối cùng, kích OK để hiển thị tất cả instance của lớp như đã được liệt kê bởi key property của chúng (Name):

Page 87: Quản lý các mạng Windows dùng Script

Hình 6: Các instance của Win32_BootConfiguration

Sau khi tất cả đã được loại ra chỉ còn lại có một instance của lớp này trên máy tính và thuộc tính Name của instance này có giá trị là "BootConfiguration"! điều này có nghĩa là để hiển thị các giá trị của các thuộc tính của instance của lớp Win32_BootConfiguration trên máy tính của chúng ta thì tất cả những gì cần thiết là thay đổi dòng này:

strWMIQuery = ":Win32_BootConfiguration"

thành:

strWMIQuery = ":Win32_BootConfiguration.Name='BootConfiguration'"

Cách khác, kịch bản DisplayClassProperties.vbs được duyệt lại bây giờ như sau:

Option ExplicitOn Error Resume NextDim strComputerDim strWMINamespaceDim strWMIQueryDim objWMIServiceDim colItemsDim objItem strComputer = "."strWMINamespace = "\root\CIMV2"strWMIQuery = ":Win32_BootConfiguration.Name='BootConfiguration'" Set objWMIService = GetObject("winmgmts:\\" & strComputer & strWMINamespace & strWMIQuery)WScript.Echo "Number of properties of " & strWMIQuery & " class is " & objWMIService.Properties_.count For Each objItem in objWMIService.Properties_   Wscript.Echo "Property: " & objItem.name & vbTab & "Value: " & objItem.valueNext

Khi chạy kịch bản này, nó sẽ không chỉ hiển thị tên các thuộc tính mà còn cả giá trị của chúng nữa:

C:\scripts>DisplayClassProperties.vbsMicrosoft (R) Windows Script Host Version 5.6

Page 88: Quản lý các mạng Windows dùng Script

Copyright (C) Microsoft Corporation 1996-2001. All rights reserved. Number of properties of :Win32_BootConfiguration.Name='BootConfiguration' classis 9Property: BootDirectory Value: \WINDOWSProperty: Caption       Value: \Device\Harddisk0\Partition1Property: ConfigurationPath     Value: \WINDOWSProperty: Description   Value: \Device\Harddisk0\Partition1Property: LastDrive     Value: C:Property: Name  Value: BootConfigurationProperty: ScratchDirectory      Value: C:\WINDOWS\system32\config\systemprofile\Local Settings\TempProperty: SettingID     Value:Property: TempDirectory Value: C:\WINDOWS\system32\config\systemprofile\Local Settings\

Temp

Đặt thông tin này vào bảng để dễ đọc hơn:

BootDirectory \WINDOWS

Caption \Device\Harddisk0\Partition1

ConfigurationPath \WINDOWS

Description \Device\Harddisk0\Partition1

LastDrive C:

Name BootConfiguration

ScratchDirectory C:\WINDOWS\system32\config\systemprofile\Local Settings\Temp

SettingID Value:

TempDirectory C:\WINDOWS\system32\config\systemprofile\Local Settings\Temp

Kết luận

Chúng ta có thể thấy rằng kịch bản “trả về tất cả các giá trị” đơn giản này đã cho những thông tin hữu dụng về máy tính. Đây là một bài tập mà bạn có thể tự thực hiện: thay vì kết nối đến một instance của lớp Win32_BootConfiguration (chỉ có một instance của lớp này), bạn hãy cố gắng kết nối đến một instance của lớp Win32_DiskPartition (lớp có một vài instance nếu máy tính của bạn có nhiều partition). Để thực hiện điều đó, trước tiên bạn cần sử dụng wbemtest để hiển thị các instance của lớp này (tìm hiểu thêm về key property khác với các instance này) và sau đó thay đổi kịch bản DisplayClassProperties.vbs để nó có thể hiển thị các thuộc tính và các giá trị của instance cụ thể của lớp này (nghĩa là phân vùng đĩa bạn đã chỉ định).

Page 89: Quản lý các mạng Windows dùng Script

% Hết %