Assigning -Context Parameters To A Variable

I have a Powershell 5.1 script I use to search for a keyword throughout all the files in a particular folder. In it I use -Context 2,3 to display 2 text lines before and 3 lines after each match. It works without a hitch. Thinking it might be useful if I could could change the displayed output format without having to change the hard coding every time, I tried using -Prompt to input the -Context parameters using a variable. I did this using $List1 as the variable. Here are the relevant lines of code I used:

    $List1 = Read-Host -Prompt '                                              Input List Context' 

and the -Context line for the formatting of the display:

    select-string  -pattern $term  -Context $List1  | 

This worked except that the value of $List1 ie 2,3 was read as 23 and, therefore, 23 lines of text after the match were duly displayed. Try as I might I can’t resolve this as the input keeps getting treated as 23 instead of the number 2 followed by a comma and followed by a 3. I even tried the separate input of the -Context parameters using three variables $List1, $List2 and $List3 and then used -Join to concatenate the three variables into one variable $List4. A check of the variable $List4 using Write-host then showed the output to be 2,3 yet when used within the script the value of $List4 was still processed as 23! Can anyone help me? I can obviously stick with having the parameters hard coded in the script but I would like to have this resolved one way or the other. What have I got wrong, or is it just not possible to read the -Context parameters from a variable?

The cmdlet Read-Host returns by default an object of the type [String]. You can show this with the method .GetType() of the varialbe $List1 you created:

$List1 = Read-Host -Prompt 'Input List Context' 
$List1.GetType()

It does not matter if you input only numbers or or numbers seperated by comma - it’ll be always a string.

Select-String on the other hand expects for its parameter -Context one or two integers. So the type should be [Int] or more precise [Int32].

You may (re-)read the help for that particular parameter

There you can read:

If you enter one number as the value of this parameter, that number determines the number of lines captured before and after the match.

So when you provide "2,3" it will be interpreted as 23 and it should display 23 lines before and after the match.

Now … if you want to provide separate values for before and after for this parameter you should use 2 separate variables.

[Int]$ContextBefore = Read-Host -Prompt 'Context before' 
[Int]$ContextAfter  = Read-Host -Prompt 'Context after' 

Select-String -Pattern $term -Context $ContextBefore,$ContextAfter

@Olaf. Again thank you for such a prompt response. Your advice was spot on. Everything now works perfectly. I appreciate your help and the mode you employ with your comments, explanations and references. It contributes greatly to the understanding of newbies like me. Through looking up your references I also learned that it is considered bad practice to use Write-Host except in very few circumstances and that Write-Output should be used instead. Thank you once again! More power to your elbow!
PS Can’t see on screen box to show you’ve solved this for me

In my experience Write-Host is mostly used where actually Write-Verbose or Write-Debug should be used. Implemented correctly you can switch on verbose output or debug output by providing the parameter -Verbose or -Debug while the default is “no unnecessary” output at all. :wink:

You may read up here:

I almost never use Write-Output, it’s rarely needed (really with implicit output the only time I ever need Write-Output is to keep a collection intact with -NoEnumerate.) However, Write-Host on the other hand, has some valid use cases. Write-Verbose can replace the majority of Write-Host I see people use… which would give control to the caller what is output.

1 Like