10 thủ thuật với PowerShell trong Windows Server 2008 - Phần 1

Quản Trị Mạng - Trên thực tế, có khá nhiều tác vụ của Windows Server 2008 chúng ta có thể thực hiện nhanh hơn rất nhiều bằng PowerShell so với ứng dụng hoặc công cụ hỗ trợ có giao diện đồ họa. Trong bài viết dưới đây, chúng tôi sẽ giới thiệu với các bạn một số thao tác cơ bản và được sử dụng thường xuyên nhất với PowerShell.

1. Thay đổi mật khẩu quản trị với PowerShell

Giả sử rằng bạn đang đăng nhập bằng tài khoản Administrator domain trên máy tính Windows 7 Desktop trên hệ thống domain. Yêu cầu đặt ra ở đây là phải thay đổi mật khẩu trên server remote tại Chicago có tên là CHI-WIN7-22. Sau khi 1 tài khoản được sử dụng nhiều lần thì cơ hội “bẻ khóa” mật khẩu lại càng cao. Đó là lý do tại sao chúng ta nên thay đổi mật khẩu của tài khoản sau 1 khoảng thời gian sử dụng.

Trước tiên, chúng ta cần phải tạo mới 1 đối tượng ADSI đối với tài khoản Administrator local trên server. Để thực hiện, các bạn hãy gõ lệnh sau tại màn hình PowerShell:

[ADSI]$Admin=”WinNT://CHI-WIN7-22/Administrator”

Về bản chất, câu lệnh trên sẽ thực hiện việc “lấy lại” tài khoản admin trên máy CHI-WIN7-22 và gán với đối tượng ADSI có tên là $Admin. Nếu muốn kết nối tới máy tính khác thì các bạn chỉ việc thay đổi CHI-WIN7-22 thành tên tương ứng của máy tính đó. Còn nếu muốn biết mật khẩu đó đã sử dụng được bao lâu để có thể thay đổi, chúng ta sẽ sử dụng lệnh:

$Admin.PasswordAge

Câu lệnh trên sẽ hiển thị khoảng thời gian đã trôi qua kể từ lần thay đổi gần đây nhất, và vì giá trị trả về được tính bằng giây, nên chúng ta sẽ chia cho 86.400 để chuyển thành ngày:

$Admin.PasswordAge.Value/86400

Nếu các bạn để ý kỹ sẽ thấy rằng chúng tôi có sử dụng thuộc tính Value ở đây. Đó là vì phần thông tin PasswordAge được lưu trữ dưới dạng collection, di vậy chúng ta cần phải biết giá trị của collection đó để tra lại con số chính xác nhằm thực hiện phép tính chia. Cuối cùng, thay đổi mật khẩu bằng cách dùng hàm SetPassword, đi kèm với đó là mật khẩu mới – argument. Ví dụ, nếu muốn đặt password mới là S3cre+WOrd thì phải gõ lệnh như sau:

$Admin.SetPassword(“S3cre+WOrd”)

Tuy nhiên, các bạn cần lưu ý rằng sau khi nhấn Enter thì hệ thống sẽ không hiển thị bất cứ thông báo nào, mà sự thay đổi này sẽ ngay lập tức có hiệu lực. Bởi vì chúng ta đã sử dụng phương pháp – method, chứ không phải là lệnh – cmdlet. Không giống như cmdlet, SetPassword không hỗ trợ -whatif hoặc -confirm.

sử dụng $Admin.PasswordAge

2. Tắt hoặc khởi động lại server

Để thực hiện việc này, chúng ta sẽ sử dụng 1 cặp lệnh cmdlet dựa trên WMI, đó là Restart-Computer Stop-Computer. Mực dù không đi quá sâu vào việc phân tích từng lệnh trên, nhưng chúng ta vẫn phải đề cập tới, vì những lệnh cmdlet đó có chấp nhận các thông tin thay thế – có ích rất lớn trong việc chỉ định tài khoản người dùng đã đăng nhập sẵn, qua đó chúng ta có thể thực hiện được các lệnh tương ứng của tài khoản đó.

Bên cạnh đó, các bạn còn có thể tận dụng được lợi thế của -whatif và -confirm, có nghĩa là nếu muốn thực hiện lệnh tắt hoặc khởi động lại hệ thống, chúng ta hoàn toàn có thể thực hiện được theo cách riêng. Và nếu áp dụng vào thực tế, nhất là trong trường hợp cần phải tắt nhiều máy tính cùng lúc, đây sẽ là giải pháp hiệu quả nhất. Cấu trúc cơ bản của lệnh này là:

Restart-Computer -ComputerName <string[ ]>

với -ComputerName <string[ ]> là mảng dữ liệu dạng chuỗi, được gán với tên của 1 hoặc nhiều máy tính bất kỳ. Stop-Computer sử dụng cú pháp tương tự, ví dụ nếu muốn khởi động lại 2 máy tính có tên là CHI-DC02CHI-FP01 thì chúng ta gõ lệnh:

Restart-Computer “CHI-DC02”, “CHI-FP01”

cú pháp Restart-Computer -ComputerName <string[ ]>
Tham số -whatif được dùng để hiển thị những gì sẽ xảy ra khi thực hiện lệnh

Bây giờ, chúng ta sẽ chuyển sang 1 ví dụ khác phức tạp hơn, giả sử rằng chúng ta có 1 danh sách nhiều máy tính trong 1 file có tên là servers.txt, sử dụng lệnh cmdlet Get-Content để lấy nội dung bên trong file text đó:

dùng lệnh Get-Content

Do vậy, nếu bạn phải thực hiện trên nhiều máy tính thì hãy nhập tên của những máy tính đó vào 1 file text. Và mỗi lần cần khởi động lại, chúng ta chỉ cần áp dụng lệnh cmdlet Get-Content. Ví dụ như dưới đây:

dùng lệnh Get-Content trên nhiều máy tính

Tiếp theo, hệ thống sẽ đẩy phần danh sách này tới mệnh đề where để kiểm tra. Bên trong mệnh đề where này, chúng ta sẽ tiến hành thực hiện lệnh test-connection – mục đích chính là để ping tới từng máy tính riêng biệt. Tham số -quiet sẽ trả về giá trị true hoặc false, trong khi -count 2 có nghĩa là mỗi máy tính chỉ được ping 2 lần. Đối với mỗi máy được ping 2 lần, hệ thống sẽ tự động duyệt chúng.

Tiếp theo, chúng ta sẽ phải sử dụng foreach. Cụ thể, đối với mỗi tên máy tính vượt qua được lần kiểm tra trên, hệ thống sẽ hiển thị thông báo với màu xanh lá cây có nội dung là: “Restarting”. Tham số $_ đại diện cho từng đối tượng đang ở trong hệ thống, và sau đó lệnh cmdlet Restart-Computer sẽ được gọi ra để khởi động lại tất cả các máy tính đã được ping. Bên cạnh đó, chúng ta còn có thể sử dụng thêm tham số -force để ngăn chặn bất kỳ tài khoản nào muốn đăng nhập.

Và cuối cùng, tiếp tục dùng -whatif để hiển thị toàn bộ hoạt động, tiến trình hoặc diễn biến đang xảy ra trong hệ thống.

3. Khởi động lại dịch vụ

Tại đây, Restart-Service sẽ là lệnh cmdlet được dùng để khởi động lại dịch vụ – service trong hệ thống. Mặc dù lệnh cmdlet không có cơ chế hỗ trợ việc kết nối tới máy tính được remote, PowerShell Remoting có thể được kích hoạt để sử dụng qua cơ chế remote.

Để thực hiện, chúng ta chỉ việc gõ lệnh: Restart-Service “service”, trong đó “service” là tên của dịch vụ cần khởi động lại. Mặt khác, nếu muốn áp dụng việc này trên 1 hoặc nhiều máy tính remote, các bạn hãy dùng lệnh cmdlet Invoke-CommandPowerShell Remoting.

Ví dụ, trong ảnh chụp màn hình của PowerShell bên dưới, có 2 trường hợp chúng tôi đã thực hiện cú pháp Restart-Service để khởi động lại dịch vụ có tên là wuauserv (của Windows Update). Đầu tiên, Restart-Service được thực thi trực tiếp trên hệ thống, nhưng sau đó lệnh này lại tiếp tục được thực hiện trên 1 server cơ sở dữ liệu có tên là CHI-DB01 với sự trợ giúp của Invoke-Command.

thực thi lệnh Restart-Service

Ở chế độ mặc định thì Restart-Service sẽ không lưu bất kỳ đối tượng nào vào hệ thống trừ khi các bạn dùng lệnh -passthru. Do vậy, những thông tin chúng ta nhìn thấy ở phía dưới (Status, Name... ) là kết quả sau khi dùng -passthru. Còn nếu dịch vụ hoạt động trên nhiều máy tính khác nhau, và muốn khởi động lại dịch vụ đó thì chúng ta chỉ cần gán thêm tên của những máy tính đó vào danh sách, ngăn cách bởi dấu phẩy.

Một cách khác để thực hiện việc này là dùng WMI. Trước tiên, chúng ta sẽ tạo mới 1 đối tượng WMI:

dùng WMI

Trong đó gwmi là alias của Get-WmiObject.

Cụ thể, trước tiên hệ thống sẽ đẩy các đối tượng tới Get-Member (với alias gm):

sử dụng Get-Member

Nếu để ý kỹ, các bạn sẽ thấy rằng không hề có phương án nào để khởi động lại dịch vụ. Điều đó có nghĩa là chúng ta sẽ phải dùng lệnh StopService để dừng, sau đó khởi động bằng StartService.

Dưới đây là cách dừng dịch vụ sử dụng StopService của đối tượng. Nếu bạn nhận được giá trị ReturnValue là 0 thì có nghĩa là dịch vụ đó đã được dừng. Còn trong trường hợp bạn nhận giá trị khác, thì hãy tìm giá trị đó trên MSDN:

dùng lệnh StopService

Để khởi động dịch vụ, chúng ta dùng lệnh StartService:

dùng lệnh StartService

Để kiểm tra, các bạn gõ lệnh get-service tương ứng trên máy tính. Lệnh này cho phép người dùng kết nối tới máy tính remote:

kết nối tới máy remote bằng lệnh get-service

4. Tắt 1 process bất kỳ

Đây cũng là việc thường xuyên phải thực hiện nhất trên nhiều server, và để làm việc này chúng ta sẽ phải dùng lệnh cmdlet Stop-Process. Tương tự như trên, nếu muốn áp dụng trên hệ thống remote thì các bạn sẽ cần tới Stop-Process đi kèm với PowerShell Remoting.

Trên thực tế, chúng ta có 2 cách để thực hiện việc này bằng lệnh cmdlet Stop-Process.

Cách đầu tiên khá đơn giản, các bạn chỉ cần chạy lệnh Stop-Process, và theo sau đó là tên hoặc ID tương ứng của tiến trình. Ví dụ với ảnh chụp màn hình bên dưới, tên tiến trình cần tắt ở đây là Calc (chính là Windows Calculator):

dùng lệnh Stop-Process

Tiếp theo, chúng ta sẽ chuyển sang trường hợp ứng dụng trên máy tính remote. Ví dụ ở đây là tiến trình notepad trên máy remote có tên là chi-fp01.

áp dụng với tiến trình notepad trên máy remote

Sau đó, chúng ta phải kiểm tra xem ứng dụng đó có đang hoạt động hay không bằng cách dùng tham số ps – alias của Get-Process:

kiểm tra notepad

Và khi đã có được tiến trình remote để xử lý, chúng ta sẽ áp dụng một số bước tương tự như trong phần khởi động lại dịch vụ bên trên, các bạn sử dụng lệnh Invoke-CommandPowerShell Remoting để thực hiện cú pháp Stop-Process trên server remote chi-fp01.

sử dụng lệnh Invoke-Command

5. Tạo báo cáo Disk Utilization

Những người quản trị hệ thống thường xuyên phải theo dõi tình trạng hoạt động cũng như dung lượng còn trống trên ổ đĩa của server. Trên thực tế, chúng ta có thể dễ dàng thực hiện việc này bằng cách dùng WMI hoặc class Win32_LogicalDisk.

Với WMI, các bạn hoàn toàn có thể thực hiện các câu lệnh truy vấn trực tiếp trên máy local hoặc remote, 1 hoặc nhiều máy tính khác nhau. Bên cạnh đó là khả năng lưu dữ liệu thành file CVS hoặc trực tiếp thành cơ sở dữ liệu, trang HTML hoặc đơn giản nhất là hiển thị trên màn hình.

Ví dụ về câu lệnh WMI đơn giản trên máy local:

Get-WmiObject win32_logicaldisk -filter “drivetype=3” | Out-File c:\Reports\Disks.txt

Cụ thể, chúng tôi sử dụng lệnh cmdlet GetWmiObject để hiển thị thông tin trả về từ class Win32_LogicalDisk. Sau đó là -filter để lọc những thông tin có liên quan tới drivetype=3 – tương ứng với các phân vùng hệ thống cố định như ổ C. Điều này cũng có nghĩa là các thiết bị khác như ổ Flash USB, ổ đĩa map trên hệ thống sẽ không được liệt kê ở đây, và những thông tin này sẽ được lưu trong file Disks.txt.

Trong ảnh chụp màn hình dưới đây, chúng ta chỉ định rằng kết quả hiển thị sẽ bao gồm một số thông tin như Device ID, Size, Space...:

áp dụng Win32_LogicalDisk

Cụ thể, chúng ta sẽ tạo mới 1 hàm function ở đây có tên là Get-DiskUtil. Tùy từng trường hợp cụ thể trong thực tế mà các bạn có thể đặt function này trong file script, sau đó tải tới profile, hoặc load từ nhiều script khác để sử dụng kết hợp.

tạo Get-DiskUtil

Function trên sẽ sử dụng tên máy tính làm tham số, và giá trị mặc định chính là tên của máy tính local.

truyền tham số

Tại đây, chúng ta tiếp tục dùng script Process để ngăn chặn tên của máy tính local không lọt vào function.

dùng process

Tiếp theo là GetWmiObject:

dùng GetWmiObject

Kết quả của quá trình này là việc tập trung vào lệnh cmdlet Select-Object (với alias tương ứng là Select). Tiếp theo đó, chúng tôi tận dụng Hashtable để tạo 1 đối tượng thuộc tính có tên là Computername – với chức năng chính là đổi tên SystemName của đối tượng hiện tại ($_) thành Computername, còn DeviceID sẽ được giữ nguyên:

cấu trúc Select-Object

Sau đó, chúng tôi tiếp tục tạo thêm 1 cặp đối tượng Hashtable, đầu tiên là thuộc tính Size, chia nhỏ theo từng phần riêng biệt 1GB, do vậy hãy đổi lại thành SizeGB. Tiếp theo là Freespace với công thức cơ bản tương tự như vậy:

tạo đối tượng thuộc tính

Để tiếp tục, chúng ta sẽ tạo mới 1 thuộc tính với tên là UsedGB – không tồn tại sẵn trong WMI, đơn giản đây là chỉ là sự khác biệt giữa Size FreeSpace, sau đó chia nhỏ theo 1GB:

tạo mới thuộc tính UsedGB

Và cuối cùng, chúng ta cần tạo 1 thuộc tính khác gọi là PerFree – hiểu nôm na là “percent free”, với chức năng chính là hiển thị dung lượng còn trống của ổ đĩa tính theo %:

tạo mới đối tượng PerFree

Dưới đây là ảnh chụp màn hình của hệ thống khi chúng ta nhập tên của máy tính, hiển thị theo định dạng bảng - Format-Table hoặc ft, sau đó kết quả hiển tị sẽ tự động được điều chỉnh theo kích thước bằng cách dùng -auto.

định dạng bảng

Bước tiếp theo, chúng ta sẽ cùng nhau chuyển sang phần chi tiết tạo báo cáo về tình trạng Disk Utilization đối với server. Việc đầu tiên cần thực hiện tại đây là lưu toàn bộ dữ liệu vào biến $data, qua đó người dùng sẽ không phải gõ lệnh theo cách thủ công nữa. Sau đó, hệ thống tiếp tục đẩy kết quả thu được tới đối tượng where, thực hiện lệnh ping để kiểm tra, gán tên máy tính tới function mới được tạo – Get-DiskUtil.

Và khi hệ thống hiển thị giao diện như hình dưới đây thì có nghĩa là việc lưu dữ liệu đã hoàn tất:

lưu dữ liệu

Thông tin dữ liệu đã được lưu trữ thành công trong $data. Nếu muốn, người dùng có thể xác định phần thông tin này trong $data và sắp xếp theo biến computername, bên cạnh đó còn có thể gửi chúng qua Out-Printer hoặc Out-File:

hiển thị thông tin

Tương tự như vậy, nếu muốn tải lượng thông tin đó tới SQL database hoặc Excel, chúng ta chỉ cần chuyển đổi định dạng – convert thành file CVS như sau:

lưu thành file *.cvs

Nếu các bạn import file CSV thì có thể lưu trữ được tình trạng tạm thời của các phân vùng, ổ đĩa khi câu lệnh được thực thi:

import file *.cvs

Ví dụ:

ví dụ

Và cuối cùng, chúng ta sẽ cùng nhau tham khảo cách tạo bản báo cáo định dạng HTML. Tương tự như trên, các bạn bắt đầu bằng việc lọc $data và gán với Sort Computername, sau đó chuyển phần thông tin này tới lệnh cmdlet ConvertTo-HTML, bên cạnh đó là việc đặt tên và đường dẫn tới file CSS. Phần CSS này thực sự rất cần thiết vì ConverToHTML không thực hiện bất cứ thao tác định dạng cũng như sắp xếp thông tin nào. Sau đó, khởi tạo file kết quả theo cấu trúc như bên dưới:

sử dụng hàm ConverToHTML

Sau đó, gõ lệnh start để bắt đầu:

dùng lệnh start

Và đây là kết quả của chúng ta:

báo cáo định dạng HTML

Chúc các bạn thành công!

Thứ Tư, 26/08/2020 13:39
3,65 👨 5.241
0 Bình luận
Sắp xếp theo