Link to home
Start Free TrialLog in
Avatar of D B
D BFlag for United States of America

asked on

Modify PowerShell Script for Unknown Number of Entries in "config" File

I have a file that contains the following data:
key,value
FILE_SRC_TGT_PATH.0,TargetrServer|SourceFilename|TargetFilename|TargetPath\
FILE_SRC_TGT_PATH.1,localhost|xxxx.xml||C:\temp\test\MyTestDir\Dir1\
FILE_SRC_TGT_PATH.2,localhost|Setup.ktr||C:\temp\test\MyTestDir\Dir2\
FILE_SRC_TGT_PATH.3,localhost|Loading.kjb||C:\temp\test\MyTestDir\Dir2\
FILE_SRC_TGT_PATH.4,localhost|Mapping.kjb||C:\temp\test\MyTestDir\Dir2\
FILE_SRC_TGT_PATH.5,localhost|download.properties||C:\temp\test\MyTestDir\Dir1\
FILE_SRC_TGT_PATH.6,
FILE_SRC_TGT_PATH.7,
FILE_SRC_TGT_PATH.8,
FILE_SRC_TGT_PATH.9,
FILE_SRC_TGT_PATH.10,

Open in new window


It is processed within a PowerShell script using the following code:
$FileInfo = "FILE_SRC_TGT_PATH.1","FILE_SRC_TGT_PATH.2","FILE_SRC_TGT_PATH.3","FILE_SRC_TGT_PATH.4","FILE_SRC_TGT_PATH.5","FILE_SRC_TGT_PATH.6","FILE_SRC_TGT_PATH.7","FILE_SRC_TGT_PATH.8","FILE_SRC_TGT_PATH.9","FILE_SRC_TGT_PATH.10" | ForEach { GetParameterValue $PARMS $_ }

Open in new window


where GetParameterValue is a function that accepts a parameter list name ($PARAMS) and parameter name (key) and returns the value (value) of that parameter.

$PARMS is populated using "$PARMS = import-csv $PropertiesFileName" where $PropertiesFileName is the name of the file that contains the above information.

As can be seen from the above code, the list is limited to 10 items. Is there a way to make it variable, so if there were 18 items (FILE_SRC_TGT_PATH.1..FILE_SRC_TGT_PATH.18) the PowerShell code would take that into account and properly populate the variable $FileInfo? $FileInfo is subsequently used in a ForEach loop [ForEach($file in $FileInfo)]

Please do not suggest an alternate way of creating $PARMS, or divert from the key/value format of the file, as this is a standard way we process our property files and can't be deviated from.

Basically, I just need to replace the line:
$FileInfo = "FILE_SRC_TGT_PATH.1","FILE_SRC_TGT_PATH.2","FILE_SRC_TGT_PATH.3","FILE_SRC_TGT_PATH.4","FILE_SRC_TGT_PATH.5","FILE_SRC_TGT_PATH.6","FILE_SRC_TGT_PATH.7","FILE_SRC_TGT_PATH.8","FILE_SRC_TGT_PATH.9","FILE_SRC_TGT_PATH.10" | ForEach { GetParameterValue $PARMS $_ }

with code that can handle an unknown number of items, that could exceed 10.
Avatar of D B
D B
Flag of United States of America image

ASKER

I don't need to know how many entries there are, as they are being processed using ForEach() and they cannot have the same value for 'key' as each key has to be unique. That is the reason for FILE_SRC_TGT_PATH.1..FILE_SRC_TGT_PATH.n.
Avatar of oBdA
oBdA

So $FileInfo just contains an array of the values?
You can drop the GetParameterValue function. All you need is
$FileInfo = Import-Csv $PropertiesFileName | Where-Object {$_.value} | Select-Object -ExpandProperty value

Open in new window

Maybe counting the number of lines in the file (minus one for the header)?
$file = "yourfile.txt"
$count = (Get-Content $file).count - 1
$FileInfo = 0..$count | ForEach { GetParameterValue $PARMS "FILE_SRC_TGT_PATH.$_" }

Open in new window

Of course the lines in the file would still have to match the format.
possible starting point
$tests = import-csv .\eetest.csv
foreach($test in $tests){
$strings = ($test.value).split("|")
$targetserver  = $strings[0]
$sourcefilename =$strings[1]
$targetFilename = $strings[2]
$targetPath =  $strings[3]
write-output ("Target Server: {0} Source Filename: {1} Target Filename: {2} TargetPath: {3}" -f $targetserver,$sourcefilename,$targetFilename,$targetpath)
}

Open in new window

Based on your description of the GetParameterValue, you are loosing the binding to the paramter name (key) after collecting the values. If so then just collecting values like oBdA showed should be good.
Avatar of D B

ASKER

Thought I'd sent this earlier. There can be other entries in the config file; I did not show that in my example. Obviously that was not a bright idea.
So you need a filter, but you do not need to enumerate the exact key, as they all have a common prefix as shown in your example? If you cannot do wildcards, you need exact matches and exact enumeration of keys, and that contradicts a dynamic amount of keys.
Expanding on oBdA's suggestion, and assuming common prefix:
Import-Csv $PropertiesFileName |
  Where-Object {$_.value -and $_,key like 'FILE_SRC_TGT_PATH.*'} |
  Select-Object -ExpandProperty value |
  Set-Variable FileInfo

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of oBdA
oBdA

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of D B

ASKER

I am going to accept this as the answer. It definitely gives me the most possibilities. I know I said we did not want to change the current logic since it is in place in many other scripts, but sometimes it is best to move on. The function GetParameterValue was written initially about 6 years ago, likely using PoSh v1. Time to do something else. Doing something a certain way because that is the way it has always been done isn't always the best way to get something done and I think now is the time to do it another way.