One script to handle CSV File or array

TL;DR: is it possible to send a pipeline to a script from a script?

When users call my script, I’d like to give them the option to specify either a CSV file with the various parameters defined, OR let them specify the parameters directly. If the latter, the parameters would be submitted to the pipeline.

For example, if mycsv.csv contains:
Name, Rank
Jon, Sergeant
Jane, Lieutenant

then ./myscript.ps1 -CSVFile .\mycsv.csv should process Jon and Jane.

Alternately, if someone wants to specify the Name and Rank values explicitly, they could do something like:
(@{Name=Jon; Rank=Sergeant), @{Name=‘Jane’; Rank=‘Lieutenant’}) | .\myscript.ps1

What I have right now is:

[CmdletBinding(DefaultParameterSetName="Pipeline")] 
param( 
    [parameter(Mandatory=$true,ParameterSetName="FromCSV",ValueFromPipeline=$false)] 
        [String]$CSVFile,
    [parameter(Mandatory=$true,ParameterSetName="Pipeline", ValueFromPipelineByPropertyName = $true)]
        [String] $Name, 
    [parameter(Mandatory=$false,ParameterSetName="Pipeline", ValueFromPipelineByPropertyName = $true)]
        [String] $Rank
) 

 begin { 
    $ParamSetName = $PSCmdlet.ParameterSetName 
    if ($ParamSetName -eq 'FromCSV') {
        $scriptName = '\\fullpath\mscript.ps1'
        get-item $scriptName #I just do this to confirm that the file exists and is accessible
        $values = import-csv -path $CSVFile;
        $values | $scriptname  #THIS FAILS
        exit 0;
    }
process { 
    write-host $Name, $Rank;
}

As you can see, I’m trying to send the contents of the CSV into the pipeline of the same script, but I keep getting errors that the ps1 file doesn’t exist or that I can’t have an expression at the end of a pipe.

$values | $scriptname
$values | Invoke-Expression $ScriptName
$values | (Invoke-Expression $ScriptName)

OTOH, the following does execute, so maybe I should stop being clever with pipelines?

        $values | foreach-object {
            $cmd = "$scriptName -Name ""$($_.Name)"" -Rank ""$($_.Rank)"""
            invoke-expression $cmd;
        }

Advice welcomed. For now I’ll just use the foreach-object.

Thanks.

I’d expect users clever enough to use a command line interface like PowerShell with a script to be clever enough as well to do it the proper PowerShell way. :wink:

… something like this:

Import-Csv -Path .\mycsv.csv | .\myscript.ps1

I’d rather create a function instead of a script actually to make the experience even more “powershelly”.

I finally figured it out.

$values | .($scriptname)

I’m not entirely sure what the dot is doing there syntactically - it’s not dot sourcing because there’s no space - but it worked.

Great that you’ve found a solution and thanks for sharing. :+1:t4: :metal:t4: :slightly_smiling_face: