A Fahad A Fahad - 1 year ago 241
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:

Param(
[Parameter(Mandatory=$true)][string]$config
)

#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..."
Break
}

# 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:

[COMMANDS]
; 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:
Error

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download