A Fahad A Fahad - 1 year ago 141
PowerShell Question

how to execute a script which reads an .ini file to execute a command from a text file

Basically I have a script, which is trying to read the content of a configuration file called commands.ini which redirects to a text file which contains a command to execute.

Here is the content of my script .ps1 file:


#Function to read *.ini file and populate an hashtable
Function Get-IniFile ($file) {
$ini = @{}

switch -regex -file $file {
"^\[(.+)\]$" {
$section = $matches[1].Trim()
$ini[$section] = @{}
"^\s*([^#].+?)\s*=\s*(.*)" {
$name,$value = $matches[1..2]
# skip comments that start with semicolon:
if (!($name.StartsWith(";"))) {
$ini[$section][$name] = $value.Trim()
return $ini

# Getting parameters from *.ini file
$ini = Get-IniFile($config)
$commands_file = $ini['COMMANDS']['commands_file']

# In case any of the files containing the commands: EXIT.
if (Test-Path $commands_file) {
[string[]]$commands = Get-Content $commands_file
} else {
Write-Output "# ERROR: cannot read commands_file. Please check configuration. Exiting..."

# This is the command I am trying to run among the various other similar command just to read the ini file
# and execute the command from the text file which is directed to from the ini file
invoke-expression $commands_file[0]

I have also changed around a bit and used invoke-command command, but does not work.

Here the content of commands.ini file:

; this is where the file to the list of commands to execute will be mentioned
commands_file = C:\test\Test\find\commands.txt

and the content of the commands.txt file:

'Get-Process | Where-Object { $_.Name -like "a*"}'

but I always get the same error no matter how much changes I make, i am sure something is wrong the way my hash tables are called or something but I can't figure out what exactly is causing this error.

Error displayed in PowerShell:

C : The term 'C' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ C
+ ~
+ CategoryInfo : ObjectNotFound: (C:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

Please advice guys, thanks in advance.

Will be also much appreciated if some one can explain me the "Getting parameters from *.ini file" part in the script in details, I do have the basic PowerShell Knowledge.

Answer Source

It's this part which is flawed:

invoke-expression $commands_file[0]

$commands_file at this point contains a string, "C:\test\Test\find\commands.txt", so when it uses [0] to index into that it picks the first character (as strings can be accessed by index). The first character is C so it tries to run Invoke-Expression against that and you get the error message.

It is not sufficient to simply remove the index ([0]), all you'll do is open the text file. To use it as it stands you'd need to run:

Invoke-Expression (Get-Content $commands_file -Raw)

You might simply change $commands_file (in the ini) to a .ps1, then you can call it rather than worrying about Invoke-Expression and Get-Content.

The ini file parser is reasonably simple. It reads the ini file one line at a time and loads the content into a nested hashtable (key-value pair). Every time it encounters a value in square brackets ([something]) it creates a "section" hashtable. Every time it encounters a key and value (this = that) it adds a new entry under the section. You end up with this structure:

    'COMMANDS' = @{
        'commands_file' = 'C:\stuff\working\scratch\commands.txt'

ini files aren't the nicest things to work with, very old fashioned these days. Json, CSV and XML formats tend to be less troubled by regular expression based parsing.