ฉันจะส่งพารามิเตอร์หลายรายการไปยังฟังก์ชันใน PowerShell ได้อย่างไร


438

หากฉันมีฟังก์ชั่นที่ยอมรับพารามิเตอร์สตริงมากกว่าหนึ่งพารามิเตอร์พารามิเตอร์แรกดูเหมือนว่าจะได้รับข้อมูลทั้งหมดที่กำหนดไว้และพารามิเตอร์ที่เหลือจะถูกส่งผ่านเป็นว่างเปล่า

สคริปต์ทดสอบอย่างรวดเร็ว:

Function Test([string]$arg1, [string]$arg2)
{
    Write-Host "`$arg1 value: $arg1"
    Write-Host "`$arg2 value: $arg2"
}

Test("ABC", "DEF")

ผลลัพธ์ที่สร้างขึ้นคือ

$arg1 value: ABC DEF
$arg2 value: 

ผลลัพธ์ที่ถูกต้องควรเป็น:

$arg1 value: ABC
$arg2 value: DEF

ดูเหมือนว่าจะสอดคล้องกันระหว่าง v1 และ v2 ในหลาย ๆ เครื่องดังนั้นเห็นได้ชัดว่าฉันกำลังทำอะไรผิด ใครสามารถชี้ให้เห็นว่าอะไรกันแน่?


3
คุณเพียงแค่เรียกสิ่งนี้:Test "ABC" "DEF"
Ranadip Dutta

คำตอบ:


576

พารามิเตอร์ในการโทรไปยังฟังก์ชั่นใน PowerShell (ทุกรุ่น) มีพื้นที่แยกออกจากกันไม่ได้คั่นด้วยเครื่องหมายจุลภาค นอกจากนี้วงเล็บยังไม่จำเป็นทั้งหมดและจะทำให้เกิดข้อผิดพลาดในการแยกวิเคราะห์ใน PowerShell 2.0 (หรือใหม่กว่า) หากSet-StrictModeมีการใช้งาน อาร์กิวเมนต์วงเล็บถูกใช้ในวิธีการ. NET เท่านั้น

function foo($a, $b, $c) {
   "a: $a; b: $b; c: $c"
}

ps> foo 1 2 3
a: 1; b: 2; c: 3

20
สิ่งที่สำคัญที่สุดที่ในที่สุดก็ช่วย 'ติด' สิ่งนี้ในใจของฉันคือประโยคสุดท้าย: "อาร์กิวเมนต์ที่ใช้วงเล็บในวิธีการ. NET เท่านั้น"
แอชลีย์

1
ฉันชอบใช้ paranthesis และคั่นด้วยเครื่องหมายจุลภาค .. เป็นไปได้ไหมที่จะทำเช่นนี้ใน PowerShell?
sam yi

8
@ samyi ไม่การส่ง a (1,2,3)ไปยังฟังก์ชันจะถือว่าเป็นอาร์เรย์อย่างมีประสิทธิภาพ อาร์กิวเมนต์เดียว หากคุณต้องการใช้อาร์กิวเมนต์ลักษณะของเมธอด OO ให้ใช้โมดูล:$m = new-module -ascustomobject { function Add($x,$y) { $x + $y } }; $m.Add(1,1)
x0n

4
Powershellเป็นภาษาของเชลล์และเป็นเรื่องปกติที่เชลล์ภาษาจะใช้ช่องว่างเป็นตัวคั่นโทเค็น ฉันจะไม่พูดPowershellคือความแตกต่างกันที่นี่ก็เป็นที่เหมาะสมสอดคล้องกับเปลือกหอยเริ่มต้นของระบบอื่น ๆ เช่นcmd, sh, bashฯลฯ
เบนเดอร์ยิ่งใหญ่ที่สุด

270

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

ฉันจะเพิ่มนี่เป็นความคิดเห็น แต่ฉันต้องการที่จะรวมภาพประกอบ - ฉันฉีกมันออกจากแผนภูมิอ้างอิงอย่างรวดเร็วของฉันในฟังก์ชั่น PowerShell สิ่งนี้ถือว่าฟังก์ชันของ f คือf($a, $b, $c):

ข้อผิดพลาดทางไวยากรณ์ของการเรียกใช้ฟังก์ชัน

ดังนั้นหนึ่งสามารถเรียกใช้ฟังก์ชั่นที่มีพารามิเตอร์ตำแหน่งคั่นด้วยช่องว่างหรือพารามิเตอร์ชื่อสั่งซื้ออิสระ ข้อผิดพลาดอื่น ๆ เผยให้เห็นว่าคุณจะต้องรับรู้ถึงจุลภาควงเล็บและพื้นที่สีขาว

สำหรับการอ่านเพิ่มเติมโปรดดูบทความของฉันลงโพรงกระต่าย: ศึกษาใน PowerShell ท่อ, ฟังก์ชั่นและพารามิเตอร์ บทความนี้มีลิงค์ไปยังแผนภูมิอ้างอิง / กำแพงอย่างรวดเร็วเช่นกัน


4
คำอธิบายที่มีไวยากรณ์ verbose เพิ่มเติมเรียกแต่ละพารามิเตอร์และกำหนดค่าให้มันประสานจริง ๆ ขอบคุณ!
ConstantineK

7
ขอบคุณมันทำให้ฉันไม่เข้าใจสิ่งที่ฉันทำผิด ในที่สุดเมื่อฉันทำถูกต้องฉันก็หิวเพราะคำอธิบายของพฤติกรรมนี้
BSAFH

1
ขอบคุณที่โพสต์สิ่งนี้เป็นคำตอบ การรู้ว่าทำไมสิ่งผิดปกติมีความสำคัญเท่ากับความผิด
Gavin Ward

4
นี่เป็นคำตอบที่ดีกว่ามาก มันควรจะเพิ่มขึ้น
Mark Bertenshaw

53

มีคำตอบที่ดีอยู่ที่นี่ แต่ฉันต้องการชี้ให้เห็นอีกสองสิ่ง พารามิเตอร์ฟังก์ชั่นเป็นสถานที่ที่ PowerShell ส่องสว่าง ตัวอย่างเช่นคุณสามารถมีพารามิเตอร์ที่ระบุชื่อหรือตำแหน่งในฟังก์ชันขั้นสูงเช่น:

function Get-Something
{
    Param
    (
         [Parameter(Mandatory=$true, Position=0)]
         [string] $Name,
         [Parameter(Mandatory=$true, Position=1)]
         [int] $Id
    )
}

จากนั้นคุณสามารถเรียกมันได้โดยระบุชื่อพารามิเตอร์หรือคุณสามารถใช้พารามิเตอร์ตำแหน่งเนื่องจากคุณกำหนดไว้อย่างชัดเจน ดังนั้นสิ่งเหล่านี้จะได้ผล:

Get-Something -Id 34 -Name "Blah"
Get-Something "Blah" 34

ตัวอย่างแรกใช้งานได้แม้ว่าจะNameมีให้เป็นครั้งที่สองเพราะเราใช้ชื่อพารามิเตอร์อย่างชัดเจน ตัวอย่างที่สองใช้งานได้ตามตำแหน่งแม้ว่าNameจะต้องเป็นอันดับแรก เมื่อเป็นไปได้ฉันพยายามกำหนดตำแหน่งเพื่อให้ทั้งสองตัวเลือกพร้อมใช้งาน

PowerShell ยังมีความสามารถในการกำหนดชุดพารามิเตอร์ มันใช้วิธีนี้แทนวิธีการมากไปและอีกครั้งมีประโยชน์มาก:

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
    )
}

ตอนนี้ฟังก์ชั่นจะใช้ชื่อหรือรหัส แต่ไม่ใช่ทั้งสองอย่าง คุณสามารถใช้พวกเขาตามตำแหน่งหรือตามชื่อ เนื่องจากเป็นประเภทที่แตกต่างกัน PowerShell จะคิดออก ดังนั้นสิ่งเหล่านี้จะได้ผล:

Get-Something "some name"
Get-Something 23
Get-Something -Name "some name"
Get-Something -Id 23

คุณยังสามารถกำหนดพารามิเตอร์เพิ่มเติมให้กับชุดพารามิเตอร์ต่างๆ (นั่นเป็นตัวอย่างพื้นฐานที่ค่อนข้างชัดเจน) ภายในฟังก์ชันคุณสามารถกำหนดชุดพารามิเตอร์ที่ใช้กับคุณสมบัติ $ PsCmdlet.ParameterSetName ตัวอย่างเช่น:

if($PsCmdlet.ParameterSetName -eq "Name")
{
    Write-Host "Doing something with name here"
}

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

function Get-Something
{
    Param
    (
         [Parameter(Mandatory=$true, Position=0)]
         [ValidatePattern('^Some.*')]
         [string] $Name,
         [Parameter(Mandatory=$true, Position=1)]
         [ValidateRange(10,100)]
         [int] $Id
    )
}

ในตัวอย่างแรก ValidatePattern ยอมรับการแสดงออกปกติที่มั่นใจว่าพารามิเตอร์ที่ให้มาตรงกับสิ่งที่คุณคาดหวัง หากไม่เป็นเช่นนั้นจะมีการโยนข้อยกเว้นตามสัญชาตญาณเพื่อบอกคุณว่ามีอะไรผิดปกติ ดังนั้นในตัวอย่างนั้น 'Something' จะทำงานได้ดี แต่ 'Summer' จะไม่ผ่านการตรวจสอบ

ValidateRange ทำให้แน่ใจว่าค่าพารามิเตอร์อยู่ในช่วงที่คุณคาดหวังสำหรับจำนวนเต็ม ดังนั้น 10 หรือ 99 ก็ใช้ได้ แต่ 101 จะมีข้อยกเว้น

อีกชุดหนึ่งที่มีประโยชน์คือ ValidateSet ซึ่งช่วยให้คุณสามารถกำหนดอาร์เรย์ของค่าที่ยอมรับได้อย่างชัดเจน หากป้อนอย่างอื่นข้อยกเว้นจะถูกโยนทิ้ง มีคนอื่นเช่นกัน แต่อาจเป็นประโยชน์มากที่สุดคือ ValidateScript สิ่งนี้ใช้บล็อกสคริปต์ที่ต้องประเมินเป็น $ true ดังนั้นท้องฟ้าจึงมีข้อ จำกัด ตัวอย่างเช่น:

function Get-Something
{
    Param
    (
         [Parameter(Mandatory=$true, Position=0)]
         [ValidateScript({ Test-Path $_ -PathType 'Leaf' })]
         [ValidateScript({ (Get-Item $_ | select -Expand Extension) -eq ".csv" })]
         [string] $Path
    )
}

ในตัวอย่างนี้เราไม่เพียง แต่มั่นใจว่า $ Path มีอยู่ แต่มันเป็นไฟล์ (ตรงข้ามกับไดเรกทอรี) และมีนามสกุลเป็น. csv ($ _ อ้างอิงถึงพารามิเตอร์เมื่ออยู่ใน scriptblock ของคุณ) คุณยังสามารถผ่านบล็อกสคริปต์แบบหลายบรรทัดที่ใหญ่กว่านี้ได้หากจำเป็นต้องใช้ระดับนั้นหรือใช้สคริปต์แบบหลายบล็อกเหมือนที่ฉันทำที่นี่ มันมีประโยชน์อย่างมากและทำให้ฟังก์ชั่นที่ดีสะอาดและข้อยกเว้นที่ใช้งานง่าย


3
+1 สำหรับสาธิตMy_Function -NamedParamater "ParamValue"สไตล์การเรียกใช้ฟังก์ชัน นี่เป็นรูปแบบที่โค้ดสคริปต์ PS ควรปฏิบัติตามเพื่อให้อ่านง่ายขึ้น
Mister_Tom

46

คุณเรียกใช้ฟังก์ชัน PowerShell โดยไม่มีวงเล็บและไม่ใช้เครื่องหมายจุลภาคเป็นตัวคั่น ลองใช้:

test "ABC" "DEF"

ใน PowerShell เครื่องหมายจุลภาค (,) เป็นตัวดำเนินการอาร์เรย์เช่น

$a = "one", "two", "three"

มันตั้ง$aเป็นอาร์เรย์ที่มีสามค่า



11

หากคุณเป็นนักพัฒนา C # / Java / C ++ / Ruby / Python / Pick-A-Language-From-This-Century และคุณต้องการโทรหาฟังก์ชันของคุณด้วยเครื่องหมายจุลภาคเพราะนั่นคือสิ่งที่คุณทำมาตลอด แบบนี้:

$myModule = New-Module -ascustomobject { 
    function test($arg1, $arg2) { 
        echo "arg1 = $arg1, and arg2 = $arg2"
    }
}

ตอนนี้โทร:

$myModule.test("ABC", "DEF")

และคุณจะเห็น

arg1 = ABC, and arg2 = DEF

Java, C ++, Ruby และ Python ไม่ได้มาจากศตวรรษนี้ (เฉพาะ C #) สันนิษฐานว่าปฏิทินเกรกอเรียน (แม้ว่าบางคนมีวิวัฒนาการมากกว่าคนอื่น ๆ )
Peter Mortensen

หึ @PeterMortensen อาร์กิวเมนต์ของคุณคือฉันควรจะพูดว่า "เลือกภาษาจากศตวรรษนี้หรือคนสุดท้าย"? :-)
Ryan Shillington

10

หากคุณไม่ทราบ (หรือสนใจ) จำนวนอาร์กิวเมนต์ที่คุณจะส่งผ่านไปยังฟังก์ชันคุณสามารถใช้วิธีที่ง่ายมากเช่น

รหัส :

function FunctionName()
{
    Write-Host $args
}

ที่จะพิมพ์ข้อโต้แย้งทั้งหมด ตัวอย่างเช่น:

FunctionName a b c 1 2 3

เอาท์พุต

a b c 1 2 3

ฉันพบว่ามีประโยชน์อย่างยิ่งเมื่อสร้างฟังก์ชันที่ใช้คำสั่งภายนอกที่อาจมีพารามิเตอร์ที่แตกต่างกัน (และเป็นทางเลือก) แต่ต้องอาศัยคำสั่งดังกล่าวเพื่อให้ข้อเสนอแนะเกี่ยวกับข้อผิดพลาดทางไวยากรณ์ ฯลฯ

นี่เป็นอีกตัวอย่างในโลกแห่งความจริง (การสร้างฟังก์ชั่นให้กับคำสั่ง tracert ซึ่งฉันเกลียดการจำชื่อที่ถูกตัดทอน);

รหัส :

Function traceroute
{
    Start-Process -FilePath "$env:systemroot\system32\tracert.exe" -ArgumentList $args -NoNewWindow
}

7

ถ้าคุณลอง:

PS > Test("ABC", "GHI") ("DEF")

คุณได้รับ:

$arg1 value: ABC GHI
$arg2 value: DEF

ดังนั้นคุณจะเห็นว่าวงเล็บคั่นพารามิเตอร์


ถ้าคุณลอง:

PS > $var = "C"
PS > Test ("AB" + $var) "DEF"

คุณได้รับ:

$arg1 value: ABC
$arg2 value: DEF

ตอนนี้คุณสามารถหาประโยชน์ได้ทันทีจากวงเล็บ - ช่องว่างจะไม่กลายเป็นตัวคั่นสำหรับพารามิเตอร์ถัดไป - แทนที่จะมีฟังก์ชัน eval


4
Parens ไม่แยกพารามิเตอร์ พวกเขากำหนดอาร์เรย์
n0rd

1
Parens ไม่ได้กำหนดอาร์เรย์ แต่จะกำหนดกลุ่มซึ่ง PowerShell สามารถตีความเป็นอาร์เรย์ได้ อาร์เรย์ถูกกำหนดด้วยเครื่องหมาย at ( @) หน้า paren ชั้นนำเช่นอาร์เรย์ว่างนี้: @(); @(1, 2)หรืออาร์เรย์นี้กับตัวเลขสอง:
VertigoRay

5

เนื่องจากนี่เป็นคำถามที่ดูบ่อยฉันต้องการพูดถึงว่าฟังก์ชัน PowerShell ควรใช้คำกริยาที่ได้รับการอนุมัติ ( Verb-Nounเป็นชื่อฟังก์ชัน) ส่วนคำกริยาของชื่อระบุการกระทำที่ cmdlet ดำเนินการ ส่วนที่เป็นรูปธรรมของชื่อจะระบุเอนทิตีที่ดำเนินการ กฎนี้ทำให้การใช้งาน cmdlet ของคุณง่ายขึ้นสำหรับผู้ใช้ PowerShell ขั้นสูง

นอกจากนี้คุณสามารถระบุสิ่งต่าง ๆ เช่นพารามิเตอร์บังคับและตำแหน่งของพารามิเตอร์:

function Test-Script
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true, Position=0)]
        [string]$arg1,

        [Parameter(Mandatory=$true, Position=1)]
        [string]$arg2
    )

    Write-Host "`$arg1 value: $arg1"
    Write-Host "`$arg2 value: $arg2"
}

ในการส่งพารามิเตอร์ไปยังฟังก์ชันคุณสามารถใช้ตำแหน่งได้ :

Test-Script "Hello" "World"

หรือคุณระบุชื่อพารามิเตอร์:

Test-Script -arg1 "Hello" -arg2 "World"

คุณไม่ใช้วงเล็บเหมือนที่คุณทำเมื่อคุณเรียกใช้ฟังก์ชันภายใน C #


ผมอยากจะแนะนำให้เสมอผ่านชื่อพารามิเตอร์เมื่อใช้มากกว่าหนึ่งพารามิเตอร์ตั้งแต่นี้เป็นมากขึ้นอ่าน


FYI ลิงก์คำกริยาที่ผ่านการอนุมัติแล้วไม่สามารถใช้งานได้อีกต่อไป แต่ตอนนี้สามารถพบได้ที่นี่ - docs.microsoft.com/en-us/powershell/developer/cmdlet/ …
Keith Langmead

@ KeithLangmead ขอบคุณ Keith ฉันได้อัปเดตคำตอบของฉันเช่นกัน
Martin Brandl

1
"คำกริยาคำนาม" ในคำกริยาและคำนามเป็นตัวพิมพ์ใหญ่หรือไม่ อาจเปลี่ยนคำตอบให้ชัดเจนยิ่งขึ้นเกี่ยวกับเรื่องนี้?
Peter Mortensen

@PeterMortensen ขอบคุณที่กล่าวถึง ฉันปรับปรุงคำตอบของฉัน
Martin Brandl

1
ดีพิจารณาคุณเปิดเผยGet-Nodecmdlet มันจะมีความชัดเจนสำหรับเราที่เรามีการเรียกGet-Nodeไม่ได้Retrieve-NodeหรือReceive-Nodeไม่ .....
มาร์ติน Brandl

4

ฉันไม่รู้ว่าคุณกำลังทำอะไรกับฟังก์ชั่นนี้ แต่ดูที่การใช้คำหลัก 'param' มันค่อนข้างมีประสิทธิภาพมากกว่าสำหรับการส่งพารามิเตอร์ไปยังฟังก์ชั่นและทำให้ผู้ใช้เป็นมิตรมากขึ้น ด้านล่างนี้เป็นลิงค์ไปยังบทความที่ซับซ้อนมากเกินไปจาก Microsoft เกี่ยวกับเรื่องนี้ มันไม่ซับซ้อนเท่าที่บทความทำให้เสียง

การใช้พารามิเตอร์

และนี่คือตัวอย่างจากคำถามในไซต์นี้:

ลองดูสิ


ขอบคุณสำหรับคำตอบ. อย่างไรก็ตามฉันมีปัญหาเมื่อเรียกใช้ฟังก์ชัน ไม่สำคัญว่าจะมีการประกาศฟังก์ชันด้วยพารามิเตอร์หรือไม่ก็ตาม
Nasir


2

ฉันระบุดังต่อไปนี้ก่อนหน้านี้:

ปัญหาที่พบบ่อยคือการใช้แบบฟอร์มเอกพจน์$argซึ่งไม่ถูกต้อง มันควรจะเป็นพหูพจน์$argsเสมอ

ปัญหาไม่ใช่ว่า ในความเป็นจริง$argสามารถเป็นอย่างอื่นได้ ปัญหาคือการใช้เครื่องหมายจุลภาคและวงเล็บ

ฉันเรียกใช้รหัสต่อไปนี้ที่ทำงานและผลลัพธ์ดังนี้

รหัส:

Function Test([string]$var1, [string]$var2)
{
    Write-Host "`$var1 value: $var1"
    Write-Host "`$var2 value: $var2"
}

ทดสอบ "ABC" "DEF"

เอาท์พุท:

$var1 value: ABC
$var2 value: DEF

4
ขอบคุณเพื่อนของฉันอย่างไรก็ตามคุณเพิ่งผ่านไปไม่กี่ปี :-) คำตอบสามอันดับแรกที่ได้รับการแก้ไขนั้นเพียงพอแล้ว ฉันขอแนะนำให้มุ่งหน้าไปยังหัวข้อที่ยังไม่ได้ตอบและลองตอบคำถามเหล่านี้ได้ไหม?
Nasir

2
Function Test {
    Param([string]$arg1, [string]$arg2)

    Write-Host $arg1
    Write-Host $arg2
}

นี่คือการparamsประกาศที่เหมาะสม

ดูabout_Functions_Advanced_Parameters

และมันใช้งานได้จริง


1

คุณสามารถส่งผ่านพารามิเตอร์ในฟังก์ชั่นเช่นนี้ได้เช่นกัน:

function FunctionName()
{
    Param ([string]$ParamName);
    # Operations
}

3
นั่นจะเป็นการกำหนดพารามิเตอร์สำหรับฟังก์ชั่นคำถามดั้งเดิมเกี่ยวกับวิธีการระบุพารามิเตอร์เมื่อคุณเรียกใช้ฟังก์ชัน
Nasir

1

ฉันไม่เห็นมันกล่าวถึงที่นี่ แต่การกระจายข้อโต้แย้งของคุณเป็นทางเลือกที่มีประโยชน์และกลายเป็นประโยชน์อย่างยิ่งหากคุณกำลังสร้างข้อโต้แย้งไปยังคำสั่งแบบไดนามิก (ตรงข้ามกับการใช้Invoke-Expression) คุณสามารถแสดงด้วยอาร์เรย์สำหรับอาร์กิวเมนต์ตำแหน่งและแฮชเทเบิลสำหรับอาร์กิวเมนต์ที่มีชื่อ นี่คือตัวอย่างบางส่วน:

Splat With Array (อาร์กิวเมนต์ตำแหน่ง)

ทดสอบการเชื่อมต่อกับอาร์กิวเมนต์ตำแหน่ง

Test-Connection www.google.com localhost

ด้วย Array Splatting

$argumentArray = 'www.google.com', 'localhost'
Test-Connection @argumentArray

ทราบว่าเมื่อ splatting เราอ้างอิงตัวแปร splatted กับแทน@ $มันก็เหมือนกันเมื่อใช้ Hashtable เพื่อทำเครื่องหมายด้วย

Splat With Hashtable (อาร์กิวเมนต์ที่มีชื่อ)

ทดสอบการเชื่อมต่อกับอาร์กิวเมนต์ที่ระบุชื่อ

Test-Connection -ComputerName www.google.com -Source localhost

ด้วย Hashtable Splatting

$argumentHash = @{
  ComputerName = 'www.google.com'
  Source = 'localhost'
}
Test-Connection @argumentHash

Splat อาร์กิวเมนต์ตำแหน่งและตั้งชื่อพร้อมกัน

ทดสอบการเชื่อมต่อกับทั้งอาร์กิวเมนต์ตำแหน่งและชื่อ

Test-Connection www.google.com localhost -Count 1

การแบ่งอาร์เรย์และแฮชเทเบิ้ลเข้าด้วยกัน

$argumentHash = @{
  Count = 1
}
$argumentArray = 'www.google.com', 'localhost'
Test-Connection @argumentHash @argumentArray
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.