Powershell 函数使用Try-Catch停止处理

Powershell 函数使用Try-Catch停止处理,powershell,Powershell,为什么即使我正在使用try/catch和continue语句,该函数仍会停止处理 在下面的例子中,当达到“三”时,我尝试一个无效的Get项,希望能捕获ErrorAction停止语句,然后继续到“四”和“五” 结果应该是 one two four five 但是我只得到前两个值 one two 因为这是在管道中,所以continue退出管道并尝试移动到对象上方阵列中的下一个对象。而是使用一个将返回到管道中下一个对象的返回 继续在这种情况下工作: foreach($item in $Outsi

为什么即使我正在使用try/catch和continue语句,该函数仍会停止处理

在下面的例子中,当达到“三”时,我尝试一个无效的Get项,希望能捕获ErrorAction停止语句,然后继续到“四”和“五”

结果应该是

one
two
four
five
但是我只得到前两个值

one
two


因为这是在管道中,所以continue退出管道并尝试移动到对象上方阵列中的下一个对象。而是使用一个将返回到管道中下一个对象的返回

继续在这种情况下工作:

foreach($item in $OutsideArray){
    if($item -eq "three"){
        continue
    }
    $item
}
Return将在以下情况下起作用:

$InsideArray  = @("one","two","three","four","five")
$InsideArray | ForEach-Object {    
    if($_ -eq "three"){    
        try
        {
            Get-Item -Path "x:\foo" -ErrorAction Stop
        }
        catch [System.Exception]
        {
            Write-Error $_
            return
        }
    }     
    Write-Output $_
}
在下面的最后一个示例中,您将看到,当您点击管道中的continue时,它将转到$OutsideArray中的下一项。它永远不会命中的“外部端点”语句,因为管道会强制ForEach移动到下一个数字

foreach($item in $OutsideArray){
    "Outside Start :  $item"
    $InsideArray  = @("one","two","three","four","five")
    $InsideArray | ForEach-Object {
        if($_ -eq "three"){
            try
            {
                Get-Item -Path "x:\foo" -ErrorAction Stop
            }
            catch [System.Exception]
            {
                continue
            }
        } 
        "Inside : $_"
    }
    "Outside End :  $item"
}

整个想法只有在紧急情况下才能奏效

  • 写入输出
  • 尝试获取项目的整个if
在try-catch块内

## Q:\Test\2018\06\28\SO_51089096.ps1

function Get-Array {
    [CmdletBinding(
        SupportsShouldProcess=$false, ConfirmImpact='Medium'
    )]
    param(
        [string[]] $myArray
    )
    begin{
        Set-StrictMode -Version latest
        Write-Verbose ('[{0}] Processing begun ...' -f $MyInvocation.MyCommand)
        Write-Verbose ("Procesing {0} items" -f $myArray.Count)
    }
    process {
        $myArray | ForEach-Object {
            try {
                if($_ -eq "three"){
                    Get-Item -Path "x:\foo" -ErrorAction Stop
                }
                Write-Output $_
            } catch [System.Exception] {
                    Write-Error $_
            }
        }
    }
    end {
        Write-Verbose ('[{0}] Processing completed.' -f $MyInvocation.MyCommand)
    }
}

$MyInput = @("one","two","three","four","five")
$result = Get-Array -myArray $MyInput -verbose -InformationVariable $info
$result
# Expect: "one","two","four","five"
# Actual: "one","two"
样本输出:

> Q:\Test\2018\06\28\SO_51089096.ps1
AUSFÜHRLICH: [Get-Array] Processing begun ...
AUSFÜHRLICH: Procesing 5 items

不知道为什么,但我发现使用for循环的性能与预期一样

function Get-Array {

    [CmdletBinding(
        SupportsShouldProcess=$false, ConfirmImpact='Medium'
    )]
    param(

        [string[]] $myArray

    )

    begin{

        Set-StrictMode -Version latest

        Write-Verbose ('[{0}] Processing begun ...' -f $MyInvocation.MyCommand)

        Write-Verbose ("Procesing {0} items" -f $myArray.Count)

    }

    process{
`
        for($i=0;$i -lt $myArray.Count;$i++) {

            if($myArray[$i] -eq "three"){

               try
               {
                    Get-Item -Path "x:\foo" -ErrorAction Stop
               }
               catch [System.Exception]
               {
                    Write-Error $myArray[$i]
                    continue;
               }
            } 


            Write-Output $myArray[$i]
        }


    }

    end{

        Write-Verbose ('[{0}] Processing completed.' -f $MyInvocation.MyCommand)
    }

}


$input = @("one","two","three","four","five")



$result = Get-Array -myArray $input -verbose -InformationVariable $info
$result 

# Expect: "one","two","four","five"
# Actual: "one","two"

阅读
获取有关自动变量的帮助
为什么不应该使用一些变量名,如
$input
不确定我是否遵循了一些解释,即“继续退出管道并尝试移动到对象上方数组中的下一个对象”,我不确定示例是否与我的示例相近。我确实理解了您关于用return语句替换continue语句的说法,现在可以正常工作了。@ChiliYago如果此答案解决了您的问题,请将其作为正确的解决方案
Get-Array : Das Laufwerk wurde nicht gefunden. Ein Laufwerk mit dem Namen "x" ist nicht vorhanden.
In Q:\Test\2018\06\28\SO_51089096.ps1:34 Zeichen:11
+ $result = Get-Array -myArray $MyInput -verbose -InformationVariable $ ...
+           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Get-Array
AUSFÜHRLICH: [Get-Array] Processing completed.
one
two
four
five
function Get-Array {

    [CmdletBinding(
        SupportsShouldProcess=$false, ConfirmImpact='Medium'
    )]
    param(

        [string[]] $myArray

    )

    begin{

        Set-StrictMode -Version latest

        Write-Verbose ('[{0}] Processing begun ...' -f $MyInvocation.MyCommand)

        Write-Verbose ("Procesing {0} items" -f $myArray.Count)

    }

    process{
`
        for($i=0;$i -lt $myArray.Count;$i++) {

            if($myArray[$i] -eq "three"){

               try
               {
                    Get-Item -Path "x:\foo" -ErrorAction Stop
               }
               catch [System.Exception]
               {
                    Write-Error $myArray[$i]
                    continue;
               }
            } 


            Write-Output $myArray[$i]
        }


    }

    end{

        Write-Verbose ('[{0}] Processing completed.' -f $MyInvocation.MyCommand)
    }

}


$input = @("one","two","three","four","five")



$result = Get-Array -myArray $input -verbose -InformationVariable $info
$result 

# Expect: "one","two","four","five"
# Actual: "one","two"