函数通过try Catch停止处理

时间:2018-06-28 18:11:04

标签: powershell

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

在下面的示例中,当到达“三”时,我尝试使用无效的Get-Item,希望可以捕获ErrorAction Stop语句,然后继续执行“四”和“五”。

结果应为

one
two
four
five

但是我只能得到前两个值

one
two

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 {

            if($_ -eq "three"){

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

            Write-Output $_
        }

        }

    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"

3 个答案:

答案 0 :(得分:0)

因为它在管道中,所以continue退出管道,并尝试继续移动到对象上方数组中的下一个对象。而是使用Return键,它会返回到管道中的下一个对象

在这种情况下继续可以使用:

foreach($item in $OutsideArray){
    if($item -eq "three"){
        continue
    }
    $item
}

返回将在此操作中起作用:

$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 $_
}

在下面的最后一个示例中,您将看到在管道中单击“继续”时,它将转到 $ 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"
}

答案 1 :(得分:0)

整个想法只能在万一的情况下起作用

  • 写入输出,
  • 如果尝试获取项目,则整个

位于尝试捕获块的内部。

## 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
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

答案 2 :(得分:0)

不知道为什么,但是我发现使用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"