PowerShell và mọi điều bạn cần biết về tiện ích này

PowerShell là gì?

Microsoft PowerShell là một tiện ích dòng lệnh và ngôn ngữ kịch bản, là công cụ mạnh mẽ dành cho các quản trị viên, giúp bạn có thể tự động hóa hàng loạt nhiệm vụ cho máy tính và mạng. PowerShell chứa các thành phần của Command Prompt và được xây dựng trên framework .NET. Nếu bạn đang tìm hiểu về quản trị mạng, thì bạn cần biết rằng PowerShell chính là công cụ được các quản trị viên công nghệ thông tin chọn để quản lý các mạng lớn.

Học cách sử dụng PowerShell sẽ giúp đơn giản hóa nhiều công việc tẻ nhạt hàng ngày. Bạn cũng có thể thực hiện các thay đổi toàn hệ thống thông qua mạng mà không phải điều chỉnh riêng lẻ cho từng máy chủ. PowerShell đang trở thành một phần thiết yếu trong việc vận hành môi trường đám mây lai.

PowerShell có rất nhiều cách sử dụng khác nhau giúp làm việc tối ưu hơn và giữ cho mạng hoạt động hiệu quả. Những cách sử dụng cơ bản nhất bao gồm: lên lịch cập nhật hàng ngày trên các hệ thống, tạo báo cáo cho những tiến trình hiện tại, dịch vụ theo chu kỳ và nhiều thứ khác. Đúng là nhiều tác vụ trong số này có thể được thực hiện thông qua GUI, tuy nhiên quan điểm của PowerShell là thực hiện chúng nhanh hơn.

Nếu bạn có một nhiệm vụ bảo trì thường xuyên mất vài phút để thiết lập, bạn có thể tạo script cho các chức năng tương tự trong một lệnh duy nhất, đặt tên trên PowerShell. Như vậy, lần tiếp theo, bạn chỉ cần mở tập lệnh đó và nó sẽ chạy trong nền. Nắm vững logic script của PowerShell, hiểu cách các object, var (biến) hoạt động và triển khai nó một cách thông minh trên mạng của bạn sẽ khiến bạn tự hỏi tại sao lại không sử dụng PowerShell sớm hơn.

Hướng dẫn này sẽ mang đến những kiến ​​thức cơ bản về PowerShell, giúp ích cho những bạn mới học CNTT, đặc biệt nếu bạn đã quen thuộc với Command Prompt của Windows. Bài viết sẽ giới thiệu cách sử dụng các công cụ và lệnh cơ bản, cách thao tác với các tệp và thư mục, hiểu các đối tượng, sử dụng các biến và quản lý các máy chủ từ xa.

Lịch sử vắn tắt của tiện ích dòng lệnh Windows

Sau khi Windows NT ra đời, CMD.EXE trở thành tiện ích dòng lệnh cho Windows. Mặc dù CMD.EXE thừa hưởng một số thành phần của người tiền nhiệm DOS (COMMAN.COM), nhưng nó vẫn dựa trên một ngôn ngữ kịch bản khá “sơ khai”: sử dụng các file Windows Command (.CMD và .BAT). Sự bổ sung của Windows Scripting Host và các ngôn ngữ VBScript, JScript đã nâng cao đáng kể tính năng kịch bản cho trình tiện ích.

Những công nghệ này là sự kết hợp khá cân bằng giữa tiện ích dòng lệnh nâng cao và môi trường kịch bản. Thực ra vấn đề có thể thao tác được với bao nhiêu file CMD.EXE, .CMD và Windows Scripting Host không phải là mối quan tâm thực sự. Thứ khiến người ta phàn nàn và bận tâm nhất là hoàn thành một số nhiệm vụ dường như đơn giản.

Sử dụng “khung làm việc” của các công cụ dòng lệnh và kịch bản, bất kỳ script ở mức tổng hợp vừa phải cũng đòi hỏi phải có sự kết hợp của cả các lệnh batch, Windows Scripting Host và các thực thi độc lập. Mỗi script đều sử dụng các quy ước khác nhau cho quá trình thực thi và yêu cầu, phân tích cú pháp, trả về dữ liệu.

Những biến yếu hỗ trợ trong CMD.EXE, các giao diện không nhất quán và khả năng truy cập giới hạn thiết lập Windows, kết hợp với một điểm yếu khác khiến kịch bản dòng lệnh trở nên khó khăn hơn trong triển khai và sử dụng. Chắc bạn sẽ thắc mắc ngay ‘một điểm yếu khác’ ở đây là gì? Xin thưa rằng đó là văn bản thuần tuý (text). Ở những công nghệ này, mọi thứ đều có dạng text. Dữ liệu đầu ra (output) của một lệnh hay kịch bản là text và phải được phân tích cú pháp cũng như định dạng lại để hoạt động như dữ liệu đầu vào (input) cho lệnh tiếp theo. Đây chính là điểm xuất phát cơ bản mà PowerShell lấy ra từ tất cả các trình tiện ích truyền thống.

Giới thiệu công cụ, lệnh và mô-đun của PowerShell

Ba khái niệm được giới thiệu trong phần này chỉ là những kiến thức rất cơ bản để hiểu các khái niệm chính tạo thành nền tảng của PowerShell. Bạn sẽ cần dành thêm thời gian để tìm hiểu và nắm vững được những khái niệm nâng cao hơn khi tiếp cận với các lệnh của PowerShell.

Công cụ PowerShell

PowerShell được cài đặt theo mặc định trong Windows 10, Windows 7, Windows Server 2008 R2 và các phiên bản Windows mới hơn. Những bản PowerShell mới được bổ sung thêm nhiều tính năng mới và "cmdlets" (thuật ngữ của Microsoft cho các lệnh PowerShell - phát âm là "command-lets") và được cài đặt bằng phiên bản tương ứng của Windows Management Framework (WMF).

Hiện tại WMF 5.1 là phiên bản mới nhất được khuyến nghị sử dụng. Trong một số trường hợp, một số tính năng mới phụ thuộc vào hệ điều hành bên cạnh phiên bản WMF. Chẳng hạn, Windows 8 và Windows Server 2012 hỗ trợ cmdlet Test-NetConnection, cho phép bạn kiểm tra kết nối với một cổng TCP/IP cụ thể, nhưng cmdlet này không khả dụng trong Windows 7 ngay cả khi chạy phiên bản WMF mới nhất.

Trên hầu hết các hệ thống Windows, người dùng sẽ có sẵn hai môi trường PowerShell, bảng điều khiển PowerShell và PowerShell ISE (Môi trường tập lệnh tích hợp). Bảng điều khiển PowerShell xuất hiện giống như dòng lệnh truyền thống, nhưng với toàn bộ tính năng đầy đủ của PowerShell đằng sau nó. Tên biến, vòng lặp, tự động hoàn thành lệnh và piping có sẵn từ bảng điều khiển PowerShell.

Để sử dụng sâu hơn (như xây dựng tập lệnh), PowerShell ISE cung cấp tính năng tự động hoàn thành câu lệnh, highlight code và khả năng hoàn tất code Intellisense của Microsoft để hỗ trợ bạn tạo và kiểm tra code PowerShell. PowerShell ISE cũng cho phép bạn làm việc với nhiều tập lệnh PowerShell đồng thời sử dụng điều hướng theo tab.

cmdlets trong PowerShell

Nền tảng của các lệnh PowerShell chính là cmdlet. Microsoft đã thực hiện vài chiến lược thiết kế khi tạo ra cmdlet trong PowerShell.

Đầu tiên là khả năng dễ dàng suy ra tên của cmdlet hoặc ít nhất là làm cho chúng dễ khám phá hơn. Các lệnh PowerShell hay cmdlet cũng được thiết kế để dễ sử dụng hơn, cú pháp được tiêu chuẩn hóa, giúp tạo các tập lệnh dễ dàng hơn từ giao diện dòng lệnh.

cmdlet dùng định dạng Verb-Noun (động từ - danh từ) như trong Get-Service, Stop-Service, hay Import-Csv. Phần động từ trong tên của cmdlet sẽ chỉ ra hành động được thực hiện trên danh từ. Thông thường, các cmdlet được sử dụng để lấy thông tin sẽ có động từ Get (lấy) trong tên, ví dụ như Get-Process hay Get-Content. Lệnh sử dụng để chỉnh sửa cái gì đó thường bắt đầu với động từ Set, để thêm thực thể mới vào đâu đó thì thường bắt đầu với Add hoặc New.

Thứ 2, các tham số thường được sử dụng trong PowerShell cũng được đặt tên một cách chuẩn hóa. Ví dụ, tham số -ComputerName cho phép cmdlet được thực hiện trên một hoặc nhiều máy tính từ xa. -Credential được sử dụng để cung cấp một đối tượng xác thực, chứa thông tin đăng nhập của người dùng, để chạy lệnh với tư cách là một người dùng cụ thể.

Module trong PowerShell

Bạn có thể sử dụng alias (bí danh) cho cả cmdlet và tham số để tiết kiệm số lần nhấn phím, rút ngắn độ dài tổng thể của câu lệnh (rất hữu ích khi bạn kết hợp nhiều lệnh với nhau). Dù các alias này không phải lúc nào cũng sử dụng quy ước đặt tên tiêu chuẩn, nhưng chúng vẫn phản ánh các tiện ích dòng lệnh truyền thống.

Trong PowerShell, các alias như DIR, CD, DEL và CLS tương ứng với cmdlet Get-ChildItem, Set-Location, Remove-Item và Clear-Host tương ứng. Alias tham số có thể hoạt động theo hai cách: chúng có thể sử dụng một alias được cmdlet xác định trước hoặc chúng có thể được đặt alias bằng cách nhập đủ các ký tự để tạo ra kết quả khớp duy nhất giữa các tham số được hỗ trợ của cmdlet.

Quản lý file và thư mục

Hầu hết quản trị viên hệ thống đều phải thao tác với file, thư mục trong quá trình làm việc của mình, đó có thể là di chuyển thư mục đến một vị trí khác trên máy chủ, lưu trữ file nhật ký hoặc tìm kiếm file lớn. Trong trường hợp các thao tác giống nhau bị lặp lại trên nhiều file thì dùng PowerShell để tự động hóa chúng sẽ là giải pháp tiết kiệm thời gian hiệu quả.

Để tìm file và thư mục thì một trong những công cụ dòng lệnh đầu tiên mà quản trị viên sẽ học trong máy tính ngày xưa là lệnh dir. Dir sẽ liệt kê file và thư mục có trong thư mục được chỉ định.

PowerShell có một lệnh tương tự ở dạng Cmdlet Get-ChildItem. Get-ChildItem cho phép bạn nhanh chóng xây dựng danh sách file trong thư mục theo cách để bạn có thể thao tác trên file này thông qua một lệnh pipe hoặc gán đầu ra cho một biến.

Get-ChildItem có thể được sử dụng đơn giản bằng cách cung cấp một đường dẫn, thông qua pipeline, sử dụng tham số -Path hoặc ngay sau tên cmdlet. Để điều chỉnh phản hồi do Get-ChildItem trả về, cần phải xem xét một số tham số được tạo sẵn bởi cmdlet.

Tham số -Filter là một cách bạn có thể tìm kiếm file. Mặc định, Get-ChildItem chỉ trả về các phần tử con trực tiếp của thư mục đích. Chức năng này có thể được mở rộng bằng cách sử dụng thêm -Recurse, tìm kiếm đệ quy các thư mục chứa trong thư mục hiện tại.

Trong PowerShell 4.0 Get-ChildItem thêm khả năng giới hạn kết quả cho file hoặc thư mục bằng cách sử dụng switch –File hoặc –Directory. Các phiên bản trước của PowerShell phải chuyển kết quả đến Where-Object, lọc trên thuộc tính PSIsContainer để thực hiện quyết định này. Ví dụ về cả hai kỹ thuật được sử dụng để trả về các thư mục chứa trong C:Users được hiển thị ở đây:

Get-ChildItem C:Users -Directory Get-ChildItem C:Users | Where-Object {$_.PSIsContainer –eq $true}

Để phát hiện ra file ẩn hoặc file hệ thống, phải sử dụng -Force. Get-ChildItem trong PowerShell 4.0 trở lên cũng có thể được sử dụng để chỉ trả lại những file bị ẩn, chỉ đọc hoặc file hệ thống bằng cách sử dụng -Hidden, -ReadOnly–System tương ứng. Chức năng tương tự có thể đạt được trong các phiên bản trước bằng cách lọc thuộc tính Chế độ bằng Where-Object:

Get-ChildItem C:Users | Where-Object {$_.Mode -like '*R*'}

Kiểm tra xem file có tồn tại không

Thông thường khi làm việc với file, tất cả những gì chúng ta cần biết là file có tồn tại hay đường dẫn thư mục có hợp lệ hay không. PowerShell cung cấp một cmdlet để làm việc này dưới dạng Test-Path, nó trả về giá trị true hoặc false.

Test-Path được dùng như một bước phòng ngừa trước khi cố gắng sao chép hoặc xóa file cụ thể.

Sao chép, di chuyển và xóa file

Copy-Item: Sao chép một hoặc nhiều file hoặc thư mục từ một vị trí, được xác định bởi tham số -Path, đến vị trí được chỉ định bởi tùy chọn -Destination.

Move-Item: Di chuyển file hoặc thư mục.

Khi cấu trúc thư mục đang được sao chép hoặc di chuyển, -Recurse nên được sử dụng để cmdlet thực hiện hành động trên thư mục và nội dung của nó. Trong một số trường hợp, cần dùng thêm -Force, chẳng hạn như khi file chỉ đọc bị ghi đè bởi thao tác sao chép.

Remove-Item: Xóa file, thư mục.

Switch -Force phải được sử dụng khi gặp file hoặc chỉ đọc và -Recurse nên được sử dụng khi xóa một thư mục và nội dung của nó.

Sử dụng PowerShell -WhatIf và -Confirm

Trước khi thực hiện thao tác xóa cái gì nghiêm trọng, hàng loạt, hãy sử dụng -WhatIf. -WhatIf cho phép bạn xem điều gì sẽ xảy ra nếu chạy tập lệnh hoặc lệnh, nó có tác động tiêu cực tiềm ẩn nào khi xóa dữ liệu kinh doanh quan trọng không. Cũng cần lưu ý rằng -WhatIf không giới hạn ở các hoạt động tệp, nó được sử dụng rộng rãi trong PowerShell.

Đối với các tập lệnh mà bạn định chạy theo cách thủ công hoặc tệ hơn, có lệnh phụ thuộc chạy theo cách thủ công, hãy xem xét sử dụng -Confirm. Điều này cho phép bạn yêu cầu sự tương tác của người dùng trước khi hoạt động thực sự diễn ra.

Kịch bản PowerShell = Các file Batch trên Steroids

Bản thân PowerShell được viết trong ngôn ngữ .NET và dựa chủ yếu trên .NET Framework. Bởi vậy mà PowerShell được thiết kế như một trình tiện ích hướng đối tượng và ngôn ngữ kịch bản. Tất cả trong PowerShell đều được xem như một đối tượng với đầy đủ tính năng của .NET Framework. Một lệnh đưa ra tập hợp các đối tượng có thể được sử dụng bằng cách dùng thuộc tính và phương thức của kiểu đối tượng đó. Khi bạn muốn đưa dữ liệu đầu ra của một lệnh vào ống dẫn cho một lệnh khác, PowerShell thực tế sẽ cho đối tượng qua, không phải chỉ là dữ liệu đầu ra dạng text của dòng lệnh đầu tiên. Điều này tạo cho lệnh tiếp theo khả năng truy cập đầy đủ tất cả thuộc tính và phương thức của đối tượng trong pipeline.

Việc coi tất cả mọi thứ như là một đối tượng và khả năng chấp thuận đối tượng giữa các lệnh là một thay đổi lớn về mặt lý thuyết cho các tiện ích dòng lệnh. Điều đó nói lên rằng, PowerShell vẫn hoạt động giống như một trình tiện ích shell truyền thống. Lệnh, kịch bản, thực thi có thể được gõ và chạy từ dòng lệnh và kết quả được hiển thị ở dạng text. Các file windows .CMD và .BAT, VBScripts, JScripts và các thực thi hoạt động bên trong CMD.EXE, tất cả vẫn chạy trong PowerShell. Tuy nhiên, vì chúng không hướng đối tượng nên không có quyền truy cập đầy đủ tới những đối tượng được tạo và dùng trong PowerShell. Các kịch bản và thực thi di sản này vẫn sẽ coi mọi thứ dưới dạng text, nhưng bạn có thể kết hợp PowerShell với một số công nghệ khác. Đây là điểm rất quan trọng nếu bạn muốn bắt đầu sử dụng PowerShell bằng một tập tổng hợp các script đã tồn tại mà không thể chuyển đổi hết chúng trong một lần.

Giải thích các tham số PowerShell

Cmdlet có thể chấp nhận các tham số để thay đổi hành vi của chúng. Khi chạy Cmdlet hoặc hàm, bạn có thể cung cấp các giá trị tham số để chỉ định cái gì, khi nào, ở đâu và cách mỗi lệnh PowerShell chạy.

Ví dụ, Get-Process sẽ nhận và liệt kê tất cả các tiến trình đang hoạt động trong hệ điều hành của bạn:

Get-Process liệt kê tất cả các tiến trình đang hoạt động
Get-Process liệt kê tất cả các tiến trình đang hoạt động

Nhưng nếu bạn chỉ muốn có được một tiến trình cụ thể thì sao? Bạn có thể làm như vậy bằng cách sử dụng các tham số. Ví dụ, để có được tất cả các tiến trình Slack, bạn có thể sử dụng tham số Name với Cmdlet Get-Process:

Get-Process -Name Slack

Sau đó, bạn sẽ chỉ thấy những tiến trình có tên "slack":

Sử dụng Get-Process với tham số
Sử dụng Get-Process với tham số

Mẹo: Một số tham số là "vị trí" có nghĩa là tên của chúng là tùy chọn. Trong trường hợp này, Get-Process -Name SlackGet-Process Slack đều thực hiện nhiệm vụ tương tự.

Mỗi Cmdlet sẽ chấp nhận các loại tham số khác nhau. Sử dụng lệnh Get-Help để xem các tham số được chấp nhận của Cmdlet trong phần SYNTAX.

Get-Help Get-Process

Bạn sẽ thấy danh sách tất cả các cách có thể để bạn có thể chạy Cmdlet đã cho:

Tham số cú pháp lệnh cmdlet
Tham số cú pháp lệnh cmdlet

Trong trường hợp này, Cmdlet Get-Process chấp nhận các tham số như Name, Id, ComputerName, Module, FileVersionInfo và các tham số phổ biến khác. Các ký hiệu ở đây có nghĩa là:

Ký hiệu

Tên

Ý nghĩa

Trống

Tham số không chấp nhận đầu vào

-

Dấu gạch nối

Cho biết tên tham số

<>

Dấu ngoặc nhọn

Trình giữ chỗ cho văn bản

[]

Dấu ngoặc đơn

Tham số có thể chấp nhận một hoặc nhiều giá trị

{}

Dấu ngoặc nhọn

Tham số chấp nhận một tập hợp các giá trị

Tham số chấp nhận một tập hợp các giá trị sẽ cho biết loại dữ liệu chúng yêu cầu, chẳng hạn như chuỗi, số nguyên, boolean hoặc DateTime. Ví dụ, lệnh sau:

Get-Process [[-Name] <string[]>]

... có nghĩa là tham số Name chấp nhận một hoặc nhiều giá trị chuỗi, trong khi lệnh này:

Get-Process -Id <int[]>

... có nghĩa là tham số Id chấp nhận một hoặc nhiều giá trị nguyên.

Ví dụ Get-Process trước đó đã sử dụng tham số Name để thu hẹp kết quả. Tuy nhiên, nếu bạn muốn thu hẹp nó xuống một tiến trình cụ thể hơn nữa, bạn có thể sử dụng tham số ID, tham số này yêu cầu một số nguyên như đã nêu trong cú pháp của nó.

Get-Process -Id 3016

Sau đó, bạn sẽ chỉ thấy một tiến trình trong danh sách:

Sử dụng tham số Id trên Cmdlet
Sử dụng tham số Id trên Cmdlet

Tạo pipeline

PowerShell xử lý tất cả dữ liệu dưới dạng đối tượng. Để xây dựng một script, các đối tượng này chạy qua một loạt Cmdlet hoặc những hàm được kết nối bằng ký hiệu pipe (|). Việc chọn các Cmdlet phù hợp và kết nối chúng theo trình tự hợp lý bằng cách sử dụng pipeline là điều quan trọng để có một script hiệu quả.

Giả sử bạn đang tạo một script để sắp xếp và hiển thị 5 file chiếm nhiều dung lượng lưu trữ nhất trong một thư mục. Có nhiều cách mạnh mẽ hơn để tạo script sắp xếp file, nhưng cách viết đơn giản sau đây rất dễ hiểu:

Script Sort-LargeFiles PS1
Script Sort-LargeFiles PS1

Để thực hiện việc này trong PowerShell, hãy sử dụng một pipeline trông giống như thế này:

Get-ChildItem -Path "C:\Directory" -File | Sort-Object Length -Descending `
 | Select-Object -First 5 | Format-Table Name, Length -AutoSize

Lưu pipeline dưới dạng script PS1

Bây giờ, chúng ta đã có một pipeline đang hoạt động, bạn có thể lưu nó dưới dạng file script PS1 để không cần phải nhập nó mỗi lần sử dụng.

Cách đơn giản nhất để tạo file PS1 là dán script của bạn vào Notepad và lưu file có phần mở rộng .ps1.

Tạo script bằng Notepad
Tạo script bằng Notepad

Sau khi tạo file PS1, bạn có thể sử dụng file đó trong PowerShell bằng cách chạy ./ScriptName.ps1:

Sử dụng script PS1
Sử dụng script PS1

Mẹo: Nếu bạn gặp lỗi về quyền, cách giải quyết nhanh nhất là chạy PowerShell với quyền admin khi chạy script của bạn.

Chúc mừng! Bây giờ bạn có thể tạo script PowerShell PS1.

Ví dụ về một PowerShell Script

Đọc và hiểu cái tuyệt vời của công nghệ mới là một chuyện, còn xem xét và sử dụng nó lại là chuyện khác! Ở phần còn lại của bài này, chúng ta sẽ cùng phát triển một script PowerShell để minh chứng cho những khả năng cũng như cách sử dụng của nó.

DIR là một trong những lệnh phổ biến nhất ở CMD.EXE. Lệnh này đưa ra tất cả file và thư mục con chứa trong một thư mục mẹ (như Hình 1). Cùng với tên của từng đối tượng, thông tin đưa ra còn có ngày giờ update mới nhất và kích thước của từng file. DIR còn hiển thị kích thước tổng hợp của tất cả các file trong thư mục, cũng như tổng số file và tổng thư mục con.


Hình 1

Chạy DIR trong PowerShell cũng đưa ra một danh sách thư mục như Hình 2, nhưng hơi khác một chút. PowerShell không có lệnh DIR mà thay vào đó là Get-ChildItem, cũng thực hiện chức năng tương tự. Trong PowerShell, DIR là một bí danh cho Get-ChildItem. Tôi không có ý định đi sâu vào những bí danh trong bài này. Bạn có thể tưởng tượng DIR trong PowerShell như là một tên viết tắt cho Get-ChildItem.

DIR trong PowerShell cung cấp nhiều thông tin giống như đã nói ở trên: một danh sách file và folder, ngày tháng thời gian update lần cuối và kích thước từng file. Tuy nhiên nó thiếu phần thông tin tóm tắt mà DIR trong CMD.EXE cung cấp: tổng kích thước của tất cả các file trong thư mục, tổng số file và tổng số thư mục con.


Hình 2

Với kịch bản ví dụ, bạn sẽ cần tạo một script PowerShell mô phỏng lệnh CMD.EXE DIR. Bên dưới tôi sẽ giải thích các phần cốt yếu nhất trong một script.

DIR.PS1: Tiêu đề (Header)

Một script PowerShell bao gồm các lệnh PowerShell trong một file văn bản thuần tuý với đuôi mở rộng .PS1. Thay thế DIR, bạn sẽ dùng một file text gọi là DIR.PS1.

Để chạy script, gõ lệnh như sau ở màn hình của PowerShell:

.DIR.PS1 X:Folder

Trong đó X là ký tự phân vùng ổ (như C, D, E) và Folder là tên thư mục.

Nếu muốn biết một số thông tin về phân vùng ổ, bạn sẽ phải dùng Windows Management Instrumentation (WMI). Chi tiết về WMI nằm ngoài phạm vi của bài này nên chúng ta sẽ không đề cập tới ở đây. Nhưng đoạn mã PowerShell bên dưới cũng khá dễ hiểu để không cần dùng đến trợ giúp của WMI. Bạn có thể tạo một biến “$filter” để dùng với lệnh Get-WmiObject. Biến lọc này (tức filter) nói với lệnh Get-WmiObject rằng bạn chỉ muốn có thông tin về một ổ đĩa cụ thể. Kết quả của lệnh Get-WmiObject được lưu trữ ở một biến gọi là $volInfo. Nhớ rằng, trong PowerShell mọi thứ đều là đối tượng; $volInfo bây giờ cũng là một đối tượng kết quả trả ra từ Get-WmiObject.

$filter = "DeviceID = '" + $drive + ":'"
$volInfo = Get-WmiObject -Class Win32_LogicalDisk -Filter $filter

Bây giờ bạn đã có thể truy cập tất cả các đối tượng và phương thức gắn với đối tượng. Dãy số của phân vùng ổ có thể truy cập qua thuộc tính VolumeSerialNumber. Thông tin trả về là một dãy số dạng xâu 8 ký tự. Nhưng thường thì bạn muốn định dạng nó theo kiểu bốn số tách riêng một, cách nhau bởi một dấu nối ngang. có thể thực hiện tương tự như ở dòng bên dưới. Dấu nối ở cuối dòng thứ nhất là ký tự nối tiếp dòng trong PowerShell. Về cơ bản, nó chỉ nói cho PowerShell biết rằng dòng không bị ngắt quãng mà bao gồm cả dòng tiếp theo. Khi viết mã không cần phân tách dòng, nhưng để giảm bề rộng và để cho đoạn mã dễ đọc, bạn nên thực hiện điều này.

$serial = $volInfo.VolumeSerialNumber.SubString(0, 4) + "-" + `
$volInfo.VolumeSerialNumber.SubString(4, 4)

Bây giờ đã có đối tượng $volInfo, bạn có thể viết thông tin header DIR cho màn hình. Nếu ổ đĩa không có tên, đoạn text viết cho màn hình sẽ khác một chút so với ổ đĩa có tên. Một lệnh If-Else đơn giản được dùng để kiểm tra xem thuộc tính VolumeName có là xâu rỗng hay không. Lệnh Write-Host được dùng để viết từng dòng lệnh cho màn hình.

If ($volInfo.VolumeName -eq "") { Write-Host (" Volume in drive " + $drive + " has no label") } Else { Write-Host (" Volume in drive " + $drive + " is " + $volInfo.VolumeName) } Write-Host (" Volume Serial Number is " + $serial) Write-Host ("`n Directory of " + $args[0] + "`n")

Ký tự “ `n ” ở đầu và cuối lệnh Write-Host được dùng để chèn dòng mới vào trước và sau văn bản. Lệnh Write-Host thêm một dòng mới vào cuối mỗi dòng. Vì thế tác động của “ `n ” là tạo dòng trống trước và sau dòng văn bản.

Bạn có chú ý đến cụm “-eq” trong lệnh If? Đó là một toán tử so sánh bằng. Bảng bên dưới sẽ cho bạn biết tất cả các toán tử so sánh:

-eq, -ieqSo sánh bằng
-ne, -ineSo sánh không bằng
-gt, -igtSo sánh lớn hơn
-ge, -igeSo sánh lớn hơn hoặc bằng
-lt, -iltSo sánh nhỏ hơn
-le, -ileSo sánh nhỏ hơn hoặc bằng

Ký tự -i ở trước các toán tử so sánh là để chỉ toán tử đó không phân biệt chữ hoa, chữ thường.


Hình 3: Dữ liệu đầu ra (output) của script hiện bạn đang có

DIR.PS1: Danh sách file/thư mục

Bây giờ, bạn đã sẵn sàng hiển thị nội dung và đặc tính của thư mục này. Điều đầu tiên cần làm là gọi lệnh PowerShell Get-ChildItem để đưa ra tập hợp các file và đưa vào script như một tham số. Lệnh Get-ChildItem sẽ lấy ra tập hợp đối tượng file và folder, không chỉ tên mà còn dẫn ống các đối tượng này trực tiếp vào lệnh Sort-Object để sắp xếp chúng. Mặc định lệnh Sort-Object sẽ sắp xếp đối tượng dựa theo thuộc tính Name. Vì thế bạn không cần phải mô tả bất kỳ tham số khác nào. Tập hợp các đối tượng đã sắp xếp sau đó sẽ được lưu trữ trong một biến có tên $items.

$items = Get-ChildItem $args[0] | Sort-Object

Sau khi có được tập hợp đối tượng file và folder, bạn cần lặp vòng lại chúng và hiển thị những đặc trưng phù hợp. Lệnh dùng cho việc này là ForEach. Với từng file hay folder, đặc trưng được hiển thị ra sẽ là ngày giờ update cuối cùng, tên, chiều dài hay kích thước file. Thứ lạ trông như các xâu ký tự bên trong ngoặc tròn là mã định dạng xâu .NET. Chúng được dùng để căn lề trái/phải cho các trường và định dạng ngày tháng, thời gian, số. Việc hiểu các mã định dạng xâu này không quan trọng lắm, vì chúng không phải là thứ cốt yếu phản ánh bản chất của script này.

Lệnh If là nơi bạn xác định xem liệu có đối tượng nào là thư mục hay không. Nếu ký tự đầu tiên của thuộc tính Mode là “d”, đối tượng là một thư mục. Bạn cần kiểm tra lại vì mã viết cho thư mục thường khác với mã viết cho file.

Chú ý dòng $totalDirs++ bên trong lệnh If. Đây là bộ đếm chịu trách nhiệm theo dõi số thư mục. Tương tự, có một biến $totalFiles được dùng để theo dõi tổng kích thước của tất cả các file. Những giá trị này luôn được tính toán trong quá trình thực thi. Nhưng chúng chỉ được hiển thị khi quá trình lập danh sách file kết thúc.

ForEach ($i In $items)
{
$date = "{0, -20:MM/dd/yyyy hh:mm tt}" -f $i.LastWriteTime
$file = $i.Name
If ($i.Mode.SubString(0, 1) -eq "d")
{
$totalDirs++
$list = $date + " {0, -15}" -f "
" + " " + $file
}
Else
{
$totalFiles++
$size = "{0, 18:N0}" -f $i.Length
$list = $date + $size + " " + $file
}
$totalSize += $i.Length
Write-Host $list
}


Hình 4: Hiển thị dữ liệu xuất của script được update.

DIR.PS1: Hậu đề (Footer)

Chỉ còn một việc còn lại là viết lên màn hình tổng số file, thư mục, kích thước tổng cộng của tất cả các file và không gian trống trên phân vùng ổ này. Để thực hiện bạn sẽ cần sử dụng các biến bộ đếm ($totalFiles, $totalDirs, $totalSize) đã tạo ở phần trước. Bạn có thể biết được lượng không gian trống từ biến $volInfo đã tạo từ lúc bắt đầu viết script.

Write-Host ("{0, 16:N0}" -f $totalFiles + " File(s)" + `
"{0, 15:N0}" -f $totalSize + " bytes")
Write-Host ("{0, 16:N0}" -f $totalDirs + " Dir(s)" + `
"{0, 16:N0}" -f $volInfo.FreeSpace + " bytes free`n")


Hình 5: Hiển thị hoàn toàn dữ liệu đầu ra (output) của script.

Những dự báo và khả năng nâng cao có thể

Mặc dù script mà bạn tạo đưa ra dữ liệu đầu ra gần giống hệt của lệnh CMD.EXE DIR nhưng cũng có một số dự báo bạn cần biết đến và một số nâng cao có thể thực hiện được.

  • Bản script này không thực hiện bất kỳ kiểm tra lỗi nào.
  • Nếu một đường dẫn hợp lệ không được đưa vào script, script sẽ hỏng với một thông báo lỗi PowerShell.
  • Tổng số thư mục đưa ra trong script ít hơn 2 so với kết quả từ lệnh CMD.EXE DIR vì lệnh Get-ChildItem không tính hai thư mục “.” và “..” như ở CMD.EXE.
  • Script của bạn chỉ sắp xếp thứ tự theo tên file, tên thư mục và không cung cấp thêm bất kỳ cách sắp xếp theo thuộc tính nào khác.
  • Script của bạn không có khả năng hiển thị nội dung thư mục và tất cả thư mục con.

Kết luận

Mặc dù PowerShell là một trình tiện ích và ngôn ngữ scripting mạnh nhưng bạn chỉ cần bỏ ra ít thời gian là đã có thể nắm bắt và sử dụng nó, nhất là khi chưa quen thuộc với môi trường .NET Framework. Tôi hy vọng bài báo này cùng với script ví dụ sẽ hữu ích cho bất kỳ ai muốn hiểu về PowerShell. Nhưng script được tạo ví dụ trong bài khá đơn giản. Tin rằng nó có thể được xây dựng, phát triển hoàn thiện hơn để phục vụ tốt cho nhiều trình ứng dụng phức tạp hơn.

Thứ Năm, 22/02/2024 11:53
445 👨 108.677
0 Bình luận
Sắp xếp theo