In PowerShell, can Test-Path (or something else) be used to validate multiple files when declaring a string array parameter

前端 未结 3 1865
萌比男神i
萌比男神i 2021-01-11 14:18

I have a function that accepts a string array parameter of files and I would like to use Test-Path (or something else) to ensure that all the files in the string array param

相关标签:
3条回答
  • 2021-01-11 14:36

    You can set the parameter to use a validation script like this:

    Function DoStuff-WithFiles{
    Param([Parameter(Mandatory=$true,ValueFromPipeline)]
        [ValidateScript({
            If(Test-Path $_){$true}else{Throw "Invalid path given: $_"}
            })]
        [String[]]$FilePath)
    Process{
        "Valid path: $FilePath"
    }
    }
    

    It is recommended to not justpass back $true/$false as the function doesn't give good error messages, use a Throw instead, as I did above. Then you can call it as a function, or pipe strings to it, and it will process the ones that pass validation, and throw the error in the Throw statement for the ones that don't pass. For example I will pass a valid path (C:\Temp) and an invalid path (C:\Nope) to the function and you can see the results:

    @("c:\temp","C:\Nope")|DoStuff-WithFiles
    Valid path: c:\temp
    DoStuff-WithFiles : Cannot validate argument on parameter 'FilePath'. Invalid path given: C:\Nope
    At line:1 char:24
    + @("c:\temp","C:\Nope")|DoStuff-WithFiles
    +                        ~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidData: (C:\Nope:String) [DoStuff-WithFiles], ParameterBindingValidationException
        + FullyQualifiedErrorId : ParameterArgumentValidationError,DoStuff-WithFiles
    

    Edit: I partially retract the Throw comment. Evidently it does give descriptive errors when the validation fails now (thank you Paul!). I could have sworn it (at least used to) just gave an error stating that it failed the validation and left off what it was validating and what it was validating against. For more complex validation scripts I would still use Throw though because the user of the script may not know what $_ -match '^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$' means if the error throws that at them (validating IPv4 address).

    0 讨论(0)
  • 2021-01-11 14:38

    You can use ValidateScript

    param(
    [parameter()]
    [ValidateScript({Test-Path $_ })]
    [string[]]$paths
    )
    

    For more documentation on parameter validation visit about_Functions_Advanced_Parameters

    0 讨论(0)
  • 2021-01-11 14:43

    As @Matt said. Test-Path already accepts pipeline input, so you really just have to send the array directly in:

    @($path1, $path2) | Test-Path
    

    Which then returns:

    > @("C:\foo", "C:\Windows") | Test-Path
    False
    True
    

    If you just want to know if ALL of them exist:

    ($pathArray | Test-Path) -notcontains $false
    

    Which yields:

     False
    
    0 讨论(0)
提交回复
热议问题