2

Is there a native, built-in construct that automatically parses console inputs into variables using the same rules as cmdlet parameters?

For example, many cmdlets accept parameter-value pairs in the form of -parameter1 unspaced-value1 -parameter2:"spaced value2".

I want to read a string using maybe Read-Host, and then parse the string into parameter-value pairs and store them into $variables, something like int main(argv, argc), but maybe in an associative array or something similar.

2
  • Do you just mean like a hastable? @{Name="Value"} Commented Dec 24, 2014 at 3:36
  • A hashtable is the main associative array in PowerShell, yes, @Matt. Commented Dec 24, 2014 at 3:44

1 Answer 1

4

Not sure if i understand exactly what you want but you are definitely describing a hashtable which can simply be defined as

@{Name="Value";AnotherName="AnotherValue"}

Or more readable

@{
    Name="Value"
    AnotherName="AnotherValue"
}

Both would output the following which could be assigned to a variable which could be used for splatting (more on that later)

Name        Value       
----        -----       
Name        Value       
AnotherName AnotherValue

Ok, that's nice but you were looking for a way to use this adhoc with Read-Host maybe? This could be where ConvertFrom-StringData saves the day. In it's simplest form :

PS C:\Users\Cameron> $data = "Data=Awesome"

PS C:\Users\Cameron> $data | ConvertFrom-StringData

Name                           Value                                                                                                                                        
----                           -----                                                                                                                                        
Data                           Awesome          

Ok... that's great.. but what about Read-Host. Let's try that now!

PS C:\Users\Cameron> Read-Host | ConvertFrom-StringData
Something=Blah

Name                           Value                                                                                                                                        
----                           -----                                                                                                                                        
Something                      Blah     

This can get complicated if you want to do more than one key/value pair since Read-Host doesn't seem to like inserting new lines in the prompt. To cheat I use -Split and -Join. Split break up the pairs and join ends up creating a newline delimited string which ConvertFrom-StringData plays with better. Side Note There is a post that has a snippet for creating multiline input from Read-Host but this is simpler.

PS C:\Users\Cameron> ((Read-Host) -Split ";") -Join "`r`n" | ConvertFrom-StringData
Key1=Value1;Key2=Value2;Key3=Value3  <---- That is what I typed in as a response to Read-Host 

Name                           Value                                                                                                                                        
----                           -----                                                                                                                                        
Key1                           Value1                                                                                                                                       
Key2                           Value2                                                                                                                                       
Key3                           Value3 

If you are still reading lets use splatting and give an actual reason to use this logic.

PS C:\Users\Cameron>  $results = ((Read-Host) -Split ";") -Join "`r`n" | ConvertFrom-StringData
Get-ChildItem @results

Filter=*.txt;Path=C:\\temp    <---- That is what I typed in as a response to `Read-Host`                                                                                                                                    

LastWriteTime : 10/22/2014 11:43:38 PM
Length        : 653018
Name          : out1.txt

....output truncated....

Note: You should notice in the path I typed in the second backslash Path=C:\\temp. The reason comes from the TechNet article for ConvertFrom-StringData

ConvertFrom-StringData supports escape character sequences that are allowed by conventional machine translation tools. That is, the cmdlet can interpret backslashes (\) as escape characters in the string data by using the Regex.Unescape Method, instead of the Windows PowerShell backtick character (`) that would normally signal the end of a line in a script. Inside the here-string, the backtick character does not work. You can also preserve a literal backslash in your results by escaping it with a preceding backslash, like this: \\. Unescaped backslash characters, such as those that are commonly used in file paths, can render as illegal escape sequences in your results.

Small Update

While the ((Read-Host) -Split ";") -Join "`r`n" | ConvertFrom-StringData works I'm sure that the following is much simpler.

(Read-Host).Replace(";","`r`n") | ConvertFrom-StringData
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.