1

I'm not able to force my function to skip a folder that doesn't exist and keeps checking others.

I created a small function that measure folders. It does work but if the path of the folder is wrong the whole function stops, even though the rest is fine.

I tried few things with try and catch, $ErrorActionPreference and errorAction but with no avail. It seems either I put those in a wrong place or the error is caused by the ValidateScriptParameter which stops the loop if the path does not exist.

I'd be glad for any suggestions how to best resolve this :) If I see my code working as I intended it would help me a lot with understanding error handling in PS.

function get-folder {
[cmdletbinding()]
param (
    [ValidateScript({
        if( -not ($_ | Test-Path) ){
            throw "PATH DOESN'T EXIST!" }
            return $true
            })]
    [parameter(valueFromPipeline=$true)]
    [string[]]$path)
begin {}
process 
{ 
foreach ($p in $path){
try {
   Get-ChildItem -path $p -Recurse -File | Measure-Object -Property Length 
-Sum 
    }
catch  
{Write-Warning "The path: $p doesn't exist"
}
}
}
end{}
}

The error msg I'm getting when one of the paths is not correct:

PS C:\powershell\Moje_nowe> get-folder "C:\powershell", 
"c:\!dump","c:\hostt"
get-folder : Cannot validate argument on parameter 'path'. PATH DOESN'T 
EXIST!
At line:1 char:12
+ get-folder "C:\powershell", "c:\!dump","c:\hostt"
+            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [get-folder], 
ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,get-folder
4
  • you need to wrap the CALL to the function in a try/catch block. something like this ... >>> try {get-folder -path c:\ziggity} catch {Write-Warning 'Something went WRONG!'} <<< will give you this >>> WARNING: Something went WRONG! <<< without the error text. Commented Sep 28, 2019 at 19:14
  • What you mean by "CALL"? I have this and for some reason it doesn't give me the warning defined in the "catch", just the error given in the parameter. Maybe I placed this in a wrong position? Commented Sep 28, 2019 at 20:33
  • the call is get-folder -path c:\FolderThatAintThere. when i use your code for the function and use it in the way shown in my previous reply, it suppresses the error message and only shows the catch block output. Commented Sep 28, 2019 at 21:14
  • I underastand you now but your way didn't help me. When I give it 3 folders from which one doesn't exist it gives me the measure of the 2 and na error that the third is not ok, but it still tries to find it on the disk C: :/ Commented Sep 28, 2019 at 21:36

2 Answers 2

1

this is NOT an answer - it exists to show the code involved & the response i get. note that your results seem to be wildly different from mine ... so this allows us both to test the same code.

i reformatted your code since the broken indentation made reading it annoying as all heck. [grin]

your code, reformatted ...

function get-folder
    {
    [cmdletbinding()]
    param (
        [ValidateScript({
            if( -not ($_ | Test-Path) ){
                throw "PATH DOESN'T EXIST!" }
                return $true
                })]
        [parameter(valueFromPipeline=$true)]
        [string[]]
        $path)

    begin {}

    process 
        { 
        foreach ($p in $path)
            {
            try {
                Get-ChildItem -path $p -Recurse -File |
                    Measure-Object -Property Length -Sum 
                }
                catch  
                {
                Write-Warning "The path: $p doesn't exist"
                }
            }
        } # end >>> process

    end {}

    } # end >>> function get-folder

my code to test it ...

try
    {
    get-folder -path c:\temp, C:\PerfLogs, c:\NotThere
    }
    catch
    {
    Write-Warning 'Something went wrong ...'
    }

screen output ...

WARNING: Something went wrong ...

note that there is no output for the two valid dirs, but you report that you got the two valid dir sizes AND the error was not caught.

Sign up to request clarification or add additional context in comments.

Comments

0

Read about_Throw: The Throw keyword causes a terminating error.

function get-folder {
    [cmdletbinding()]
    param (
        [ValidateScript({
            if( -not ($_ | Test-Path) ) {
                Write-Error "$_`: PATH DOESN'T EXIST!"  ### omit
            }
            return $true
        })]
        [parameter(valueFromPipeline=$true)]
        [string[]]$path
    )
    begin {}
    process { 
        foreach ($p in $path){
            try {
                [PSCustomObject] @{
                Name = $p
                Bytes = Get-ChildItem -path $p -Recurse -File -ErrorAction Stop | 
                    Measure-Object -Property Length -Sum |
                        Select-Object -ExpandProperty Sum
                }
            }
            catch {
                Write-Warning "The path: $p doesn't exist"
            }
        }
    }
    end{}
}

Output below shows that you can omit the ValidateScript validation attribute at all (or at least Write-Error "$_: PATH DOESN'T EXIST!") because

  • the Cannot find path 'D:\testttt' … error is generated by the Get-ChildItem cmdlet,
  • hence the D:\testttt: PATH DOESN'T EXIST! from the ValidateScript seems to be superabundant here.

Output:

. D:\PShell\SO\58149019.ps1
$Error.Clear(); get-folder C:\testC, D:\test, D:\testttt
$Error.Count
$Error | ForEach-Object { $_.Exception }
WARNING: The path: D:\testttt doesn't exist
Name          Bytes
----          -----
C:\testC        408
D:\test  3513654559
2
Cannot find path 'D:\testttt' because it does not exist.
D:\testttt: PATH DOESN'T EXIST!

3 Comments

@Dafsio Please consider using catch { Write-Warning $_.Exception.Message } instead of catch { Write-Warning "The path: $p doesn't exist" } as commands inside the try block could fail for another reason…
I tried both ways with a medium success. The script doesn't fail after the wrong path is added as parameter (thanks @JosefZ!) it gives the output for the 2 proper paths but if the third is wrong for some reason it's trying to, I guess, search for the incorrect folder in whole C: in the end giving me errors that it can't read some paths.
@Dafsio Please use Get-ChildItem -path "$p\*" -Recurse -File -ErrorAction Stop. Sorry, I tested it omitting the -Recurse parameter (and I can confirm the described behaviour which is by design of the -Recurse switch: searching the leaf of a given path recursively)…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.