Elegent way to set variables in .ini files

1

I'm currently trying to script the installation of Microsoft Sql Server 2012, and I've run into a problem with letting the user set options for the installation process in my powershell script

Because sql server's options are set in an .ini file, I'm not sure what the best way to edit said .ini file is. I could see myself

  • Copying the whole .ini file in powershell and setting variables within the quotes to write it out later, or
  • saving the ini file separately and searching for each line I need to set variables as a string to edit separately.

Is there any more elegant way to work with .ini files than this? Is there any "find and replace" powershell module for files that I could use?

comp.sci.intern

Posted 2017-07-28T15:01:34.303

Reputation: 13

Probably best to re-write the entire .ini file from an "in-script" variable that contains your template because then you can guarantee that the content will be what you need it to be (plus the values the user sets)... – Kinnectus – 2017-07-28T15:09:23.590

"Is there any "find and replace" PowerShell module for files that I could use?" INI files are just text, any of PS's standard find and replace commands would work on one. Load the file into memory, find and replace, dump back to file. – Ƭᴇcʜιᴇ007 – 2017-07-28T15:52:18.067

Answers

1

Treat the .ini as a text file. Say we have the following .ini:

[section1]
var1=foo1
[section2]
var2=foo2
var3=foo3

To change the value assigned to "var2", we can do:

(get-content .\test.ini).Replace('foo2','bar2') | Set-Content .\test.ini

Where "bar2" is the user defined value. To incorporate the user defined value, you could do:

$ini = ".\test.ini"
$userInput = Read-Host -Prompt "Enter a new value for var2"
(get-content $ini).Replace('foo2',$userInput) | Set-Content $ini

The way you choose to design how you handle the replace will rely on the data in your particular file.

root

Posted 2017-07-28T15:01:34.303

Reputation: 2 992

This is a bit too simple, what if there are multiple entries with =foo2, you need to specify the value-name as well. What if there are duplicate value-names in different sections? – Peter Hahndorf – 2017-08-03T09:03:36.070

0

from https://github.com/brandoncomputer/vds

function inifile ($a,$b,$c,$d){
switch ($a){ 
    open {
        $global:inifile = $b
    } 
    write {
        $Items = New-Object System.Collections.Generic.List[System.Object]
        $content = get-content $global:inifile
        if ($content)
        {
            $Items.AddRange($content)
        }
        if ($Items.indexof("[$b]") -eq -1)
            {
            $Items.add("")
            $Items.add("[$b]")
            $Items.add("$c=$d")
            $Items | Out-File $global:inifile
            }
        else
        {
        For ($i=$Items.indexof("[$b]")+1; $i -lt $Items.count; $i++) 
        {
        if ($Items[$i].length -gt $c.length)
            {
            if ($Items[$i].substring(0,$c.length) -eq $c -and ($tgate -ne $true))
                {
                    $Items[$i] = "$c=$d"
                    $tgate = $true
                }
            }
            if ($Items[$i].length -gt 0)
            {
                if (($Items[$i].substring(0,1) -eq "[") -and ($tgate -ne $true))
                {
                    $i--
                    $Items.insert(($i),"$c=$d")
                    $tgate = $true
                    $i++
                }
            }               
        }
        if ($Items.indexof("$c=$d") -eq -1)
        {
            $Items.add("$c=$d")
        }

        $Items | Out-File $global:inifile -enc ascii
        }
    } 
}}

Usage

  1. inifile open c:\temp\myini.ini
  2. inifile write header footer value

$a = $(iniread header footer)

function iniread($a,$b) {
$Items = New-Object System.Collections.Generic.List[System.Object]
$content = get-content $global:inifile
if ($content)
{
    $Items.AddRange($content)
}
if ($Items.indexof("[$a]") -eq -1)
    {
    $return = ""
    }
else
{
    $return = ""
    For ($i=$Items.indexof("[$a]")+1; $i -lt $Items.count; $i++) 
    {
    if ($Items[$i].length -gt $b.length)
        {
        if ($Items[$i].substring(0,$b.length) -eq $b -and $gate -ne $true)
            {
                $return = $Items[$i].split("=")[1]
                $gate = $true
            }
        }
        if ($Items[$i].length -gt 0)
        {
            if (($Items[$i].substring(0,1) -eq "[") -and ($tgate -ne $true))
            {$gate = $true}
        }
    }
}return $return}

Brandon Cunningham

Posted 2017-07-28T15:01:34.303

Reputation: 1