Welcome to the Inedo Forums! Check out the Forums Guide for help getting started.

If you are experiencing any issues with the forum software, please visit the Contact Form on our website and let us know!

Otter: Output variables from PSCall



  • In an effort to store our PowerShell code as Script assets instead of embedded script and using "PSEval". PSEval currently works in that it properly return data from PowerShell scripts (even can return lists). When I use PSCall, I am unable to figure out how to get the output. Here is a sample:

    # Script asset
    function Get-Data {
         $OutVar = "HELLO WORLD"
    }
    
    
    template Test-PowerShellOutput
    {
    
    # Otter script
    PSCall Get-Data {
         OutVar => $OutData
    }
    
    Log-Debug $OutData;
    
    }
    

    I also would really like to be able to return a list or map using PSCall.



  • I am starting to think that PSCall behaves differently than $PSEval, in terms of whether it runs during the collection phase. $PSEval appears to be executed in both the collection and configuration phases. But the PSCall does not appear to be executed during the collection phase. Is this by design? I suppose I would be ok with this if I were able to execute script assets from PSEval, something like

    Script Asset content for Get-FileList

    dir c:\ | select-object -ExpandProperty FullName
    

    Plan

    set @PathList = $PSEval(".\Get-FileList")

    This would actually be a a bit better that PSCall, because PSEval can return actual lists to Otter from PowerShell, whereas PSCall is limited to returning only scalar values.



  • Yes, PSCall is an Execute operation, so by default it will only run during Execution phase, not the collect. You can override the behavior of a block using an Execution Policy token.

    with execute=always { ... }

    It's not supported by the visual editor.

    That said, I think you're right.... PSEval is best for something like this. I suppose, we didn't consider anything but short literal statements for PSEval.

    What do you think of these ideas...

    1. set $myVar = $PSEval($PSAsset(my-asset-name));
    2. set $myVar = $PSEvalAsset(my-asset-name);
    3. set $myVar = $PSEval(asset, my-asset-name);

    ... just some rough ideas I had, but i'd need to run past design team here too..



  • Hi Alana,
    The "with execute=always { }" is great to know about, that would allow me to run the PSCall operation during both the collection and execution phases. PSCall still lacks the ability to return OtterScript Lists (which PSEval does do), so for now, I would have to return a delimited string and split apart with $Split.

    With regard to executing script assets via PSEval, I think any of the 3 options you provided would be fine, but I would also need the ability to pass parameters into the script asset (probably an OtterScript Map of the parameters same as PSCall).

    Another option might be to modify the PSCall operation to support an "execute: always" optional parameter. Also, add a default output parameter/variable that captures all PowerShell object stream content (rather than requiring setting a specific output variable) that could return both Scalar and Vector OtterScript variables.

    Thanks!



  • Just a quick update...

    Upon researching it further, it seems that modifying PSCall in this manner might be quite a bit complicated; not so much technically, but we'd have to balance with how PSExec works as well. Definitely something for us to consider as we work towards getting closer with PowerShell/DSC in the coming versions.

    The current thought is to add a new variatic variable function:
    PSEvalAsset(OptionalRaftName::AssetName[, arg.1..n])

    This could return a scalar ($), vector (@), or map (@).

    Unfortunately there are no named arguments in OtterScript variable functions (unlike operations), but I think that's OK... hopefully assets will be very simple and not have a lot of arguments.



Inedo Website HomeSupport HomeCode of ConductForums GuideDocumentation