functionpowershellparametersveeam

Cannot use variable in a Where-Object in a function


I am trying to have a function that can count jobs based on the LatestStatus value that I would pass a parameter. So far what I got:

Function JobCountStatus {
  Write-Output (Get-VBRJob | ?{$_.Info.LatestStatus -eq $args} | Measure-Object).Count
}

The issue is that as I've read somewhere there will be a subshell(?) executing the where so the argument is not passed.

If I replace the $args with a specific string like "Failed" it will work.

Is there a way to overcome this? I do not want to write separate functions for all possible values.

I would appreciate any comments - Thanks


Solution

  • $args is an array, not a single value. In any case, a ScriptBlock {} is an unnamed function and $args has it's own meaning within it, so you can't use it without some modification in something like Where-Object. You would have to store the elements of $args as another variable or multiple variables to reference within a child ScriptBlock. Not a huge change for this function, but for one where more parameters are expected this can result in a lot of unnecessary code which can be difficult to maintain.


    I prefer to recommend defining named parameters in most cases, and this would be a simpler change than making the parent $args work in a child ScriptBlock:

    Function JobCountStatus {
      Param(
        [string]$Status
      )
      ( Get-VBRJob | Where-Object { $_.Info.LatestStatus -eq $Status } ).Count
    }
    

    I've also made a few more changes in this function, I'll explain below:

    Note that you can invoke the function/cmdlet (the difference is minimal for PowerShell-defined cmdlets) with or without the parameter, as when you don't define a positional order, the order is automatically determined in the order of declaration:

    # Either will work
    JobCountStatus -Status Running
    JobCountStatus Running
    

    Here is some more documentation you may find useful:

    @Ash's answer gives some more advanced examples of what you can do with param() which are mentioned in the the Advanced Functions link above. You cannot use advanced parameter attributes with the simple function syntax I mentioned in the first bullet point.