Có một số câu trả lời tốt ở đây, nhưng tôi muốn chỉ ra một vài điều khác. Các tham số chức năng thực sự là nơi PowerShell tỏa sáng. Ví dụ: bạn có thể có các tham số được đặt tên hoặc vị trí trong các hàm nâng cao như vậy:
function Get-Something
{
Param
(
[Parameter(Mandatory=$true, Position=0)]
[string] $Name,
[Parameter(Mandatory=$true, Position=1)]
[int] $Id
)
}
Sau đó, bạn có thể gọi nó bằng cách chỉ định tên tham số hoặc bạn chỉ có thể sử dụng tham số vị trí, vì bạn đã xác định rõ ràng chúng. Vì vậy, một trong hai sẽ hoạt động:
Get-Something -Id 34 -Name "Blah"
Get-Something "Blah" 34
Ví dụ đầu tiên hoạt động ngay cả khi Name
được cung cấp thứ hai, bởi vì chúng tôi sử dụng rõ ràng tên tham số. Ví dụ thứ hai hoạt động dựa trên vị trí, vì vậy Name
sẽ cần phải là đầu tiên. Khi có thể, tôi luôn cố gắng xác định vị trí để cả hai tùy chọn đều khả dụng.
PowerShell cũng có khả năng xác định các bộ tham số. Nó sử dụng điều này thay cho phương thức nạp chồng, và một lần nữa khá hữu ích:
function Get-Something
{
[CmdletBinding(DefaultParameterSetName='Name')]
Param
(
[Parameter(Mandatory=$true, Position=0, ParameterSetName='Name')]
[string] $Name,
[Parameter(Mandatory=$true, Position=0, ParameterSetName='Id')]
[int] $Id
)
}
Bây giờ hàm sẽ lấy tên hoặc id, nhưng không phải cả hai. Bạn có thể sử dụng chúng theo vị trí, hoặc theo tên. Vì chúng là một loại khác nhau, PowerShell sẽ tìm ra nó. Vì vậy, tất cả những thứ này sẽ hoạt động:
Get-Something "some name"
Get-Something 23
Get-Something -Name "some name"
Get-Something -Id 23
Bạn cũng có thể gán các tham số bổ sung cho các bộ tham số khác nhau. (Đó là một ví dụ khá cơ bản rõ ràng.) Bên trong hàm, bạn có thể xác định tập tham số nào đã được sử dụng với thuộc tính $ PsCmdlet.ParameterSetName. Ví dụ:
if($PsCmdlet.ParameterSetName -eq "Name")
{
Write-Host "Doing something with name here"
}
Sau đó, trên một ghi chú bên liên quan, cũng có xác thực tham số trong PowerShell. Đây là một trong những tính năng PowerShell yêu thích của tôi và nó làm cho mã bên trong các chức năng của bạn rất sạch sẽ. Có rất nhiều xác nhận bạn có thể sử dụng. Một vài ví dụ là:
function Get-Something
{
Param
(
[Parameter(Mandatory=$true, Position=0)]
[ValidatePattern('^Some.*')]
[string] $Name,
[Parameter(Mandatory=$true, Position=1)]
[ValidateRange(10,100)]
[int] $Id
)
}
Trong ví dụ đầu tiên, ValidatePotype chấp nhận một biểu thức chính quy đảm bảo tham số được cung cấp khớp với những gì bạn mong đợi. Nếu không, một ngoại lệ trực quan sẽ được đưa ra, cho bạn biết chính xác những gì sai. Vì vậy, trong ví dụ đó, 'Cái gì đó' sẽ hoạt động tốt, nhưng 'Mùa hè' sẽ không vượt qua được xác nhận.
ValidateRange đảm bảo rằng giá trị tham số nằm trong phạm vi bạn mong đợi cho một số nguyên. Vì vậy, 10 hoặc 99 sẽ hoạt động, nhưng 101 sẽ ném một ngoại lệ.
Một cái hữu ích khác là ValidateSet, cho phép bạn xác định rõ ràng một mảng các giá trị được chấp nhận. Nếu một cái gì đó khác được nhập vào, một ngoại lệ sẽ được ném ra. Cũng có những cái khác, nhưng có lẽ cái hữu ích nhất là ValidateScript. Điều này cần một khối tập lệnh phải ước tính thành $ true, vì vậy bầu trời là giới hạn. Ví dụ:
function Get-Something
{
Param
(
[Parameter(Mandatory=$true, Position=0)]
[ValidateScript({ Test-Path $_ -PathType 'Leaf' })]
[ValidateScript({ (Get-Item $_ | select -Expand Extension) -eq ".csv" })]
[string] $Path
)
}
Trong ví dụ này, chúng tôi đảm bảo không chỉ có $ Path tồn tại mà còn là một tệp, (trái ngược với thư mục) và có phần mở rộng .csv. ($ _ đề cập đến tham số, khi bên trong tập lệnh script của bạn.) Bạn cũng có thể chuyển vào các khối tập lệnh nhiều dòng lớn hơn nhiều nếu mức đó là bắt buộc hoặc sử dụng nhiều tập lệnh như tôi đã làm ở đây. Nó cực kỳ hữu ích và làm cho các chức năng sạch đẹp và ngoại lệ trực quan.
Test "ABC" "DEF"