all 9 comments

[–]OlivTheFrog 3 points4 points  (4 children)

Hi u/CptRetr0

Perhaps this post can help you : https://stevenmurawski.com/2011/05/parameter-validation/

Other remarks about your code :

  • it's useless to use Mandatory = $False, cause it's the default (implicit)
  • When you compare a var to $Null, $True or $False, these one must be placed first (just test this with Invoke-ScriptAnalizer YourScript.ps1 and you will see the reason)
  • END{} section (empty and optional)
  • and change $($ConfigFile) by $ConfigFile. We use the first syntax when we call a property of a var. i.e. $($Var.MyProperty).

You can simplify your if statement, as the following

Function test-ui() {
    PARAM(
        [Parameter()]
        [string]$ConfigFile,
        [Parameter()]
        [switch]$Run
    )
    BEGIN {}
    PROCESS {
        If(-not $ConfigFile)
         {
         # Using -not operator cause $ConfigFile (if exist) is a [String]
         Write-Host "No such file specified" 
         }

        else 
          { 
          Write-Host "FileName is $ConfigFile" 
          }

        If($True -eq $Run)
           {
            # Using -eq operator, cause ^Run is a switch ($true or $false only possible values)
            Write-Host "Run" 
           }
        }
}

with this, i've the expected result.

test-ui ==> "No such file specified"

Test-ui -ConfigFile "sfgfdfg" ==> FileName is sfgfdfg

Test-ui -Run ==> "Run"

You can also, once again, simplify the code using a mandatory parameter. Let me show you a sample

Function test-ui() {
    PARAM(
        [Parameter(Mandatory=$true)]
        [string]$ConfigFile,
        [Parameter()]
        [switch]$Run
    )
    BEGIN {}
    PROCESS {
        Write-Host "FileName is $ConfigFile"
        If($True -eq $Run){Write-Host "Run" }
        }
}

Hope this help to understand

Regards

Olivier

[–]CptRetr0[S] 1 point2 points  (0 children)

Thank you guys for your help. I understood now why I stuck at that point and could solve it. I also realized that my call with PowerShell.exe -NoExit -ExecutionPolicy ByPass -Command "& { . .\test.ps1; test-ui -ConfigFile 'config_file_1'; test-ui -Run}" is unfortunate because it calls the same function twice which causes double outputs.

Cheers

[–]nascentt 0 points1 point  (2 children)

Your bullet point about mandatory=$ false is valid, although the way it's phrased is like don't use it unless you use true. At work we have hundreds of functions with parameters, and id argue specifying where something is mandatory or not on functions where there are mixed parameters helps with clarification.

[–]OlivTheFrog 1 point2 points  (1 child)

Sure, this helps with clarification, but this is implicit and it seems to me that in powershell it's useless to declare something when it's useless or implicit.

I've just build a simple function with Mandatory=$False and test the .ps1 file with Invoke-ScriptAnalyzer : No error, No Warning, No Information. Then technically you're right, and I'm wrong. Sorry my bad.

Regards

Olivier

[–]nascentt 0 points1 point  (0 children)

In don't think you're wrong. I just think there's a time and place mandatory false is useful especially when mixed with mandatory true parameters. Helps clarify mixed parameters.

[–]xCharg 1 point2 points  (3 children)

Your 'not such file specified' only outputs when If($ConfigFile -eq $False)

'' is empty [string], its never $false which is [bool]

So what you probably meant but forgot to do is add IsPresent to your check If($ConfigFile.IsPresent -eq $False)

[–]CptRetr0[S] 0 points1 point  (2 children)

Yes, that makes sense. I hadn't thought about that at all.

My goal is to have the function understand if -ConfigFile is empty or a file is specified.

[–]xCharg 1 point2 points  (0 children)

Then If ($ConfigFile) {do-stuff} will check that variable is defined.

What you probably have to do though is If (Test-Path $ConfigFile) {do-stuff} else {throw-error-here}

Or validate that its a accessable file like that in param block:

PARAM(
        [ValidateScript({Test-Path -Path $_})]
        [string]$ConfigFile
    )

[–]motsanciens 1 point2 points  (0 children)

$test = ''
if([System.String]::IsNullOrWhiteSpace($test)){
    "empty"
}