Lập trình · Ngôn ngữ lập trình
Hướng dẫn học PowerShell cơ bản cho người mới
Trả lời nhanh
PowerShell là shell và ngôn ngữ kịch bản đa nền tảng của Microsoft dùng để tự động hóa. Các lệnh của nó, gọi là cmdlet, truyền đối tượng .NET qua pipeline thay vì văn bản thuần, nên bạn có thể lọc, sắp xếp và xuất dữ liệu mà không cần phân tích cú pháp. Trang này bao gồm cài PowerShell 7, chạy script, cmdlet, biến, toán tử, điều khiển luồng, hàm, collection và xử lý lỗi.
Mở Kiểm tra regexPowerShell là gì và dùng để làm gì
PowerShell là shell và ngôn ngữ kịch bản đa nền tảng của Microsoft, xây dựng trên .NET. Khác với các shell truyền thống chỉ chuyển văn bản thuần giữa các lệnh, PowerShell truyền các đối tượng .NET có thuộc tính và phương thức, nên bạn có thể lọc và sắp xếp dữ liệu mà không phải phân tích văn bản.
Quản trị viên hệ thống và kỹ sư DevOps dùng PowerShell để tự động hóa Windows, quản lý Active Directory, Microsoft 365 và Azure, cũng như viết script build và triển khai. Có hai phiên bản: Windows PowerShell 5.1, được tích hợp sẵn trong Windows, và PowerShell 7 trở lên (tên lệnh pwsh), là mã nguồn mở và chạy trên Windows, Linux và macOS. Hướng dẫn này nhắm tới PowerShell 7.
Cài PowerShell và chạy Hello, world
Trên Windows, cài PowerShell 7 bằng winget install --id Microsoft.PowerShell --source winget; trên macOS và Linux, dùng Homebrew hoặc trình quản lý gói được nêu trong hướng dẫn cài đặt của Microsoft. Script là các tệp văn bản có đuôi .ps1.
# hello.ps1
Write-Output "Hello, world!"pwsh ./hello.ps1
# Hello, world!Trên Windows, chính sách thực thi (execution policy) có thể chặn script. Set-ExecutionPolicy -Scope CurrentUser RemoteSigned cho phép script cục bộ của bạn chạy nhưng vẫn yêu cầu script tải về phải được ký. Visual Studio Code cùng tiện ích mở rộng PowerShell là trình soạn thảo được khuyên dùng.
Cmdlet và pipeline
Các lệnh được gọi là cmdlet và đặt tên theo mẫu Verb-Noun (động từ-danh từ), như Get-Process, Set-Location hay New-Item. Ba cmdlet giúp bạn khám phá mọi thứ còn lại: Get-Command, Get-Help và Get-Member.
Get-Command -Noun Process # list commands that work with processes
Get-Help Get-ChildItem -Examples # show usage examples
# five processes using the most memory
Get-Process |
Sort-Object -Property WorkingSet64 -Descending |
Select-Object -First 5 -Property Name, Id, WorkingSet64
# files larger than 1 MB in the current folder
Get-ChildItem -File | Where-Object { $_.Length -gt 1MB } |
ForEach-Object { "{0} {1:N0} KB" -f $_.Name, ($_.Length / 1KB) }
Get-Date | Get-Member -MemberType Property # inspect an objectBên trong một script block, $_ (hoặc $PSItem) là đối tượng hiện tại trong pipeline. Vì đối tượng giữ nguyên kiểu, Sort-Object sắp xếp số theo giá trị số và ngày theo thứ tự thời gian mà không cần làm thêm gì.
Biến và kiểu dữ liệu
Biến bắt đầu bằng $. Chúng chứa bất kỳ đối tượng .NET nào, và bạn có thể thêm ràng buộc kiểu trong ngoặc vuông. Chuỗi trong dấu nháy kép sẽ khai triển biến và biểu thức $( ); chuỗi trong dấu nháy đơn được giữ nguyên.
$name = "Ada"
[int]$count = 3
$price = 19.99 # System.Double
$isAdmin = $false
$today = Get-Date
"Hello, $name" # Hello, Ada
"Next: $($count + 1)" # Next: 4
'No $expansion here' # No $expansion here
$price.GetType().Name # Double
$today.ToString("yyyy-MM-dd") # for example 2026-10-31
[int]"42" + 1 # 43 (explicit conversion)| Kiểu | Ví dụ | Ghi chú |
|---|---|---|
[int] | 42 | số nguyên 32 bit |
[double] | 3.14 | số thực dấu phẩy động; dùng [decimal] cho tiền |
[string] | "text" | mặc định so sánh không phân biệt hoa thường |
[bool] | $true, $false | biến tự động, không phải từ khóa |
[datetime] | Get-Date | đối tượng DateTime đầy đủ của .NET |
[array], [hashtable] | @(1, 2), @{ a = 1 } | các collection, sẽ nói ở phần dưới |
Toán tử và điều khiển luồng
Toán tử so sánh là các từ chứ không phải ký hiệu: -eq, -ne, -gt, -lt, -ge, -le, -like (ký tự đại diện), -match (biểu thức chính quy) và -contains. So sánh chuỗi không phân biệt hoa thường trừ khi bạn dùng các dạng có c như -ceq.
$temp = 22
if ($temp -gt 30) {
"hot"
} elseif ($temp -ge 15) {
"mild" # mild
} else {
"cold"
}
switch ("report.csv") {
{ $_ -like "*.csv" } { "CSV file" } # CSV file
{ $_ -like "*.txt" } { "text file" }
default { "other" }
}
foreach ($n in 1..3) { "n = $n" } # n = 1, n = 2, n = 3
for ($i = 0; $i -lt 2; $i++) { "i = $i" } # i = 0, i = 1
$k = 3
while ($k -gt 0) { $k-- }
"Hello" -eq "hello" # TrueHàm và tham số
Hàm dùng khối param() để khai báo tham số có kiểu và có tên. Thêm [CmdletBinding()] giúp hàm có các tham số chung giống cmdlet dựng sẵn, như -Verbose. Mọi đầu ra không được bắt lại đều trở thành giá trị trả về của hàm.
function Get-Greeting {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$Name,
[string]$Greeting = "Hello"
)
Write-Verbose "Building greeting for $Name"
"$Greeting, $Name!"
}
Get-Greeting -Name "Ann" # Hello, Ann!
Get-Greeting -Name "Bo" -Greeting "Hi" # Hi, Bo!
Get-Greeting "Cy" -Verbose # also prints the verbose messageGọi hàm giống như cmdlet, các đối số cách nhau bằng dấu cách: Get-Greeting -Name Ann. Viết Get-Greeting("Ann", "Hi") sẽ truyền một đối số duy nhất là mảng, điều thường gây bất ngờ cho người đến từ ngôn ngữ khác.
Mảng, hashtable và đối tượng tùy chỉnh
Mảng được tạo bằng @( ) hoặc danh sách ngăn cách bằng dấu phẩy. Hashtable, viết là @{ }, lưu các cặp khóa-giá trị. [pscustomobject] biến hashtable thành đối tượng dùng tốt với Sort-Object, Format-Table và Export-Csv.
$langs = @("PowerShell", "Python")
$langs += "Go" # creates a new, longer array
$langs.Count # 3
$langs[0] # PowerShell
$langs -contains "Go" # True
$ports = @{ http = 80; https = 443 }
$ports["ssh"] = 22
$ports.https # 443
$ports.Keys.Count # 3
$user = [pscustomobject]@{ Name = "Ann"; Age = 31 }
$user.Name # Ann
$people = @(
[pscustomobject]@{ Name = "Bo"; Age = 25 }
$user
)
$people | Sort-Object Age | Format-TableThêm phần tử vào mảng bằng += sẽ sao chép toàn bộ mảng mỗi lần. Với vòng lặp lớn, hãy gom đầu ra của vòng lặp trực tiếp ($result = foreach (...) { ... }) hoặc dùng [System.Collections.Generic.List[object]].
Xử lý lỗi
PowerShell có lỗi kết thúc (terminating), làm dừng thực thi, và lỗi không kết thúc (non-terminating), chỉ in thông báo rồi chạy tiếp. try/catch/finally chỉ bắt lỗi kết thúc, vì vậy hãy thêm -ErrorAction Stop vào cmdlet khi bạn muốn bắt lỗi của nó.
try {
$content = Get-Content -Path "missing.txt" -ErrorAction Stop
}
catch [System.Management.Automation.ItemNotFoundException] {
Write-Warning "File not found: $($_.Exception.Message)"
}
catch {
Write-Error "Unexpected error: $_"
}
finally {
"cleanup done"
}
$ErrorActionPreference = "Stop" # make all errors terminating in this script
throw "Something went wrong" # raise your own terminating errorBên trong catch, $_ là bản ghi lỗi. Đặt $ErrorActionPreference = "Stop" ở đầu script là cách thường dùng để dừng ngay khi có lỗi.
Một script hoàn chỉnh nhỏ: báo cáo dung lượng đĩa
Script này liệt kê các tệp lớn nhất trong một thư mục, nhóm chúng theo phần mở rộng và xuất báo cáo CSV. Nó kết hợp tham số, pipeline, thuộc tính tính toán và xử lý lỗi.
# report.ps1
param(
[string]$Path = ".",
[int]$Top = 5
)
$ErrorActionPreference = "Stop"
$files = Get-ChildItem -Path $Path -File -Recurse
"Largest $Top files:"
$files | Sort-Object Length -Descending | Select-Object -First $Top |
Format-Table Name, @{ Name = "SizeKB"; Expression = { [math]::Round($_.Length / 1KB, 1) } }
$byExt = $files | Group-Object Extension | ForEach-Object {
[pscustomobject]@{
Extension = if ($_.Name) { $_.Name } else { "(none)" }
Files = $_.Count
TotalMB = [math]::Round(($_.Group | Measure-Object Length -Sum).Sum / 1MB, 2)
}
} | Sort-Object TotalMB -Descending
$byExt | Format-Table
$byExt | Export-Csv -Path "usage.csv" -NoTypeInformation
"Report saved to usage.csv"pwsh ./report.ps1 -Path ~/Documents -Top 3Học tiếp ở đâu
- PowerShell 101 và tài liệu PowerShell trên Microsoft Learn.
Get-Help about_*ngay trong shell, ví dụGet-Help about_Operators; hãy chạyUpdate-Helptrước.- PowerShell Gallery, kho module chính thức, dùng cùng
Install-Module. - PSScriptAnalyzer, một công cụ linter kiểm tra script theo các thực hành được khuyến nghị.
Câu hỏi thường gặp
PowerShell và Windows PowerShell khác nhau thế nào?
Windows PowerShell 5.1 là phiên bản cũ hơn, tích hợp sẵn trong Windows và dựa trên .NET Framework. PowerShell 7 trở lên là phiên bản đa nền tảng, mã nguồn mở, dựa trên .NET hiện đại, khởi động bằng lệnh pwsh.
PowerShell có giống Command Prompt không?
Không. Command Prompt (cmd.exe) chạy các lệnh batch và truyền văn bản. PowerShell là ngôn ngữ kịch bản đầy đủ truyền đối tượng, dù vẫn chạy được hầu hết các chương trình dòng lệnh.
PowerShell có chạy được trên Linux và macOS không?
Có. PowerShell 7 trở lên chạy trên Windows, Linux và macOS, mặc dù một số module dành riêng cho Windows chỉ có trên Windows.
Vì sao tôi không chạy được script .ps1 của mình?
Chính sách thực thi trên Windows có thể đang chặn nó. Hãy chạy Set-ExecutionPolicy -Scope CurrentUser RemoteSigned, và khởi động script kèm đường dẫn, chẳng hạn ./script.ps1.
$_ nghĩa là gì trong PowerShell?
$_ (cũng là $PSItem) là đối tượng hiện tại trong pipeline, dùng bên trong script block của các cmdlet như Where-Object và ForEach-Object, và là lỗi hiện tại bên trong catch.