วิธีจัดการอาร์กิวเมนต์บรรทัดคำสั่งใน PowerShell


494

วิธี "ดีที่สุด" ในการจัดการอาร์กิวเมนต์บรรทัดคำสั่งคืออะไร

ดูเหมือนว่ามีคำตอบหลายอย่างเกี่ยวกับวิธีที่ "ดีที่สุด" และด้วยเหตุนี้ฉันจึงติดอยู่กับวิธีการจัดการบางสิ่งที่ง่ายเหมือน:

script.ps1 /n name /d domain

และ

script.ps1 /d domain /n name.

มีปลั๊กอินที่สามารถจัดการกับสิ่งนี้ได้ดีขึ้นหรือไม่? ฉันรู้ว่าฉันกำลังสร้างวงล้อใหม่ที่นี่

เห็นได้ชัดว่าสิ่งที่ฉันมีอยู่ไม่สวยและไม่ใช่ "ดีที่สุด" แต่มันใช้งานได้ ... และมันก็เป็น UGLY

for ( $i = 0; $i -lt $args.count; $i++ ) {
    if ($args[ $i ] -eq "/n"){ $strName=$args[ $i+1 ]}
    if ($args[ $i ] -eq "-n"){ $strName=$args[ $i+1 ]}
    if ($args[ $i ] -eq "/d"){ $strDomain=$args[ $i+1 ]}
    if ($args[ $i ] -eq "-d"){ $strDomain=$args[ $i+1 ]}
}
Write-Host $strName
Write-Host $strDomain

คำตอบ:


917

คุณกำลังคิดค้นล้อใหม่ สคริปต์ PowerShell ปกติมีพารามิเตอร์ที่ขึ้นต้นด้วย-เช่นscript.ps1 -server http://devserver

จากนั้นคุณจัดการพวกเขาในparamส่วนในจุดเริ่มต้นของไฟล์

คุณยังสามารถกำหนดค่าเริ่มต้นให้กับ params ของคุณอ่านค่าจากคอนโซลหากไม่มีหรือหยุดการทำงานของสคริปต์:

 param (
    [string]$server = "http://defaultserver",
    [Parameter(Mandatory=$true)][string]$username,
    [string]$password = $( Read-Host "Input password, please" )
 )

ภายในสคริปต์คุณสามารถทำได้ง่ายๆ

write-output $server

เนื่องจากพารามิเตอร์ทั้งหมดกลายเป็นตัวแปรที่มีอยู่ในขอบเขตสคริปต์

ในตัวอย่างนี้การ$serverรับค่าเริ่มต้นหากสคริปต์ถูกเรียกโดยไม่มีสคริปต์จะหยุดถ้าคุณไม่ใช้-usernameพารามิเตอร์และขออินพุตเทอร์มินัลหาก-passwordไม่ได้ระบุไว้

อัปเดต: คุณอาจต้องการส่งผ่าน "แฟล็ก" (พารามิเตอร์บูลีนจริง / เท็จ) ไปยังสคริปต์ PowerShell ตัวอย่างเช่นสคริปต์ของคุณอาจยอมรับ "แรง" ซึ่งสคริปต์จะทำงานในโหมดระมัดระวังมากกว่านี้เมื่อไม่ใช้แรง

คำหลักสำหรับ[switch]ประเภทพารามิเตอร์คือ:

 param (
    [string]$server = "http://defaultserver",
    [string]$password = $( Read-Host "Input password, please" ),
    [switch]$force = $false
 )

ภายในสคริปต์จากนั้นคุณจะทำงานกับมันดังนี้:

if ($force) {
  //deletes a file or does something "bad"
}

ตอนนี้เมื่อเรียกสคริปต์คุณต้องตั้งค่าพารามิเตอร์สวิตช์ / แฟล็กดังนี้:

.\yourscript.ps1 -server "http://otherserver" -force

หากคุณต้องการระบุอย่างชัดเจนว่าไม่มีการตั้งค่าสถานะมีไวยากรณ์พิเศษสำหรับสิ่งนั้น

.\yourscript.ps1 -server "http://otherserver" -force:$false

ลิงค์ไปยังเอกสารประกอบของ Microsoft ที่เกี่ยวข้อง (สำหรับ PowerShell 5.0; รุ่น tho 3.0 และ 4.0 มีอยู่ที่ลิงค์):


58
อันที่จริงข้อดีอย่างหนึ่งของ PowerShell ก็คือมันมีพารามิเตอร์มาตรฐานในการแยกวิเคราะห์โครงสร้างพื้นฐานที่ใช้งานง่าย
Keith Hill

14
@naivists จาก PowerShell 2.0 แทนการมีไวยากรณ์สำหรับพารามิเตอร์บังคับ:[string]$username = $(throw "-username is required.") [Parameter(Mandatory=$true)][string]$usernameนี่คือข้อมูลเพิ่มเติมเกี่ยวกับความแตกต่างระหว่างเทคนิคเหล่านี้: blogs.technet.com/b/heyscriptingguy/archive/2011/05/22/…
v.karbovnichy

7
ระวังข้อผิดพลาดเมื่อไม่ได้หาเรื่อง PowerShell เพิ่งจะคว้าข้อความพิเศษใด ๆ จากบรรทัดคำสั่ง:. \ yourscript.ps1 -server " serv " -password "mypass" typo สิ่งนี้จะกำหนด 'typo' ให้เป็นชื่อผู้ใช้อย่างน่าอัศจรรย์
sheamus

4
การใช้บล็อก param ดูเหมือนว่าจะมีผลกระทบอื่น ๆ โดยไม่ได้ตั้งใจ: stackoverflow.com/questions/40940819/…
Logan

1
@shamam: นั่นไม่ใช่ข้อผิดพลาด! Powershell จะประมวลผลและกำหนดอาร์กิวเมนต์ตามลำดับที่ได้รับเว้นแต่จะถูกแทนที่ด้วยการใช้ชื่อพารามิเตอร์ที่เหมาะสมเช่นหากรายการบล็อกพารามิเตอร์ของคุณ: $ user $ pass $ เซิร์ฟเวอร์และคุณดำเนินการ yourscript.ps1 abc กำหนดเป็นผู้ใช้ $, b เป็น $ pass และ c ลงในเซิร์ฟเวอร์ $ เว้นแต่คุณจะมอบหมายให้พวกเขาโดยเฉพาะ! ดังนั้นถ้าคุณพูดว่า: yourscript.ps1 -pass abc, $ pass จะถูกตั้งค่าเป็น, และพารามิเตอร์ที่เหลือ (ไม่มีชื่อ) จะถูกใช้เพื่อเติมลงในรายการที่หายไปตามลำดับที่ระบุไว้ในบล็อกพารามิเตอร์ดังนั้น $ user = b, $ server = c
เฟอร์นันโดมาดรูกา
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.