1

Have been looking at what I thought would be a really simple task this morning.... and turns out it wasn't, at least not for me.

What I am trying to do is get powershell to read through an ini-file, and change multiple values under specific headers only.

[Datoformat] Separator=. [Database] Path=servername:d:\mycompany\nextsys_db\next.fdb DokumentDbPath= FireBird25=Nei [Pictures] Path=T:\nextsys_bilde DbExtractFolder= [Brukerinnstillinger] Prioriter=Ja �pneJournalAuto=Nei TillatBrukerBytte=Ja EnkelJournal=Nei AvtBokRadHoyde= AvtBokMndKolonneBredde= Resepsjonsmaskin=Nei Tilgangsoversikt=Nei AvtaleHentPasientAutomatisk=Ja VisFargeForAnsvarlig=Nei [Eksport] Automatisk=Nei [Import] Automatisk=Nei [Skjerm] HuskSkjermPosisjon=Ja ProgramSkjermPosX=-8 ProgramSkjermPosY=-8 ProgramSkjermBredde=1936 ProgramSkjermHoyde=1056 MaksimertSkjermPosisjon=Ja EgenDefSkjermSizeX=1919 EgenDefSkjermSizeY=1080 UtvidetAvtalebok=Ja UtvidetJournal=Ja UtvidetRecall=Ja UtvidetOmsetning=Ja UtvidetUtestaaende=Ja UtvidetRegnskap=Ja UtvidetFakturaOversikt=Ja UtvidetGenerelleModuler=Ja UtvidetAlleModuler=Ja 1280800=Nei 1440900=Nei 16801050=Nei 19201080=Nei Egendefinert=Ja AutomaticSize=Nei [Spesialinnstillinger] EnForekomst=Nei TestModusInfo=Nei AktiverRegningskortJournalSjekk=Nei IkkeSpmOmHelseskjema=Nei IkkeSpmOmBrukerBytteAvtale=Nei IkkeSpmOmBrukerBytteAnsvarlig=Nei [Vedlegg] Path= [Avtalebok] Utseende= Bakgrunn= [Journal] JournalTextSize=8 JournalTextFont= JournalTextStyle= FetSkrift=Nei [Rontgen] AlternativAapning=Nei [Utseende] IkkeVisDagensPasienter=Nei [MediLink] BenyttMediLink=Nei AutomatiskInnlesing=Nei MediLinkInnlesingIntervall= [AutomatiskOppdatering] VedOppstart=Nei Alltid=Nei FraLokaltNettverk=Nei NettverkPath= UtenBekreftelse=Nei [BankTerminal] PosPay=Nei BetTermAlwaysOn=Ja BBSFlerBrukerTerminal=Nei ThisMerchantHighest=Nei MerchantId= TerminalId= BrukerBoPosDrivere=Nei BrukerBaxiDrivere=Ja BaxiAktiverXReport=Ja BaxiAktiverZReport=Nei BaxiAktiverReversal=Nei [EasyPanel] Benytt=Nei Notat=Nei Diagnose=Nei Epikriser=Nei Sykemelding=Nei Resept=Nei Henvisning=Nei Helseskjema=Nei Endo=Nei Perio=Nei Bilder=Nei Tekn.skjema=Nei Skjema=Nei Dokumentmodul=Nei [Oppstartsbilde] VisesVedOppstart=Nei [Printer] LokaltOppsett=Ja TryktA5Resept=Nei TryktA5ReseptDesign2=Nei TimeKortKvittSkriver=Nei VisMinimalBaxInfo=Nei ReseptKvittSkriver=Nei JusteringVenstreMargX= JusteringToppMargY= Faktura=HP LaserJet Pro MFP M125-M126 PCLmS Recallkort=HP LaserJet Pro MFP M125-M126 PCLmS Timekort=HP LaserJet Pro MFP M125-M126 PCLmS Kvittering=HP LaserJet Pro MFP M125-M126 PCLmS Resept=HP LaserJet Pro MFP M125-M126 PCLmS Standard=HP LaserJet Pro MFP M125-M126 PCLmS Tekniker=HP LaserJet Pro MFP M125-M126 PCLmS FakturaStorrelse=A4 RecallKortStorrelse=A4 TimekortStorrelse=A4 KvitteringStorrelse=A4 ReseptStorrelse=A4 TeknikerStorrelse=A4 StandardStorrelse=A4 FakturaOppsettKode= RecallkortOppsettKode= TimekortOppsettKode= KvitteringOppsettKode= ReseptOppsettKode= TeknikerOppsettKode= StandardOppsettKode= FakturaPapirretning=St�ende RecallKortPapirretning=St�ende TimekortPapirretning=St�ende KvitteringPapirretning=St�ende ReseptPapirretning=St�ende TeknikerPapirretning=St�ende StandardPapirretning=St�ende FakturaPreview=Ja RecallKortPreview=Ja TimekortPreview=Ja KvitteringPreview=Ja ReseptPreview=Ja TeknikerPreview=Ja StandardPreview=Ja [Paaminnelse] Automatisk=Nei AutomatiskService=Nei Tidspunkt= Dagens=Nei KunMerketOnsker=Nei AutomatiskEpost=Nei AntallDagerFrem=Nei AntallDagerFremAntall=2 ErstattTekst=Nei PaaminnelseTekst=Hei [fornavn], minner om time reservert til deg: [dato] kl. [tid]. Timer som ikke passer m� avbestilles senest 24 timer i forveien. Mvh. [tittel] [brukernavn] [SMS] Testmodus=Nei VisAdvarslerVedIkkeSendtSMS=Nei [Innlogging] TillatInnloggingMedEldreProgramversjonEnnDatabase=Nei 

I want to change the values "Automatisk=Nei" to "Automatisk=Ja", "Tidspunkt=" to "Tidspunkt=10:00" and "AntallDagerFrem=Nei" to "AntallDagerFrem=Ja"... The Tidspunkt and AntallDagerFrem values shouldn't be that hard since they only appear once in the file, but "Automatisk=Nei" appears 4 times, and I only want to change the one below [Paaminnelse]

$content = @(if ((Get-Content $inifile) -join "`n" -match '\[Paaminnelse\]([\s\S]*)\[SMS\]') { $Matches[1] }) $newcontent = $test -replace 'Automatisk=Nei','Automatisk=Ja' -replace 'Tidspunkt=','Tidspunkt=10:00' -replace 'AntallDagerFrem=Nei','AntallDagerFrem=Ja' 

This finds the correct lines from the ini-file and changes the values I want to change, but using Set-Content $inifile -Value $newcontent will of course remove all everything else from the file which is not what I want :)

More used to cat, grep, awk and sed than PowerShell to be honest so any pointers would be helpful.

2
  • 2
    For manipulating INI files, best use a dedicated parser module like PsIni. BTW. It looks like your ini file should have been saved in UTF8 encoding, but it appears that is not the case.. Commented Apr 6, 2022 at 19:53
  • Thanks @Theo will take a look at the module - and yea the ini-file does look a bit funny with the encoding, but I will leave that part to the actual developers. Commented Apr 6, 2022 at 20:10

2 Answers 2

2

As Theo notes, consider using a dedicated INI file parser, such as the one provided by the third-party PsIni module - see this answer for how to install and use it.

  • Update: Your own answer now shows how to use it to solve your specific problem.

If installing a module isn't an option, I suggest using a -switch statement, which has awk-like capabilities:

# Array of sample lines, as would be returned by: # Get-Content $inifile $iniFileLines = @' [Datoformat] Separator=. [Eksport] Automatisk=Nei [Paaminnelse] Automatisk=Nei AutomatiskService=Nei Tidspunkt= [Printer] AutomatiskEpost=Nei AntallDagerFrem=Nei AntallDagerFremAntall=2 '@ -split '\r?\n' $inPaaminnelseSect = $false # Note: To operate directly on your file, replace # ($iniFileLines) with -File $iniFile switch -Regex ($iniFileLines) { '^(Tidspunkt)=$' { '{0}=10:00' -f $Matches[1]; continue } '^(AntallDagerFrem)=Nei' { '{0}=Ja' -f $Matches[1]; continue } '^(Automatisk)=Nei' { if ($inPaaminnelseSect) { '{0}=Ja' -f $Matches[1] } else { $_ }; continue } '^\[(.+)\]' { $inPaaminnelseSect = $Matches[1] -eq 'Paaminnelse'; $_ } default { $_ } # pass through } 

Note:

  • The above assumes:

    • that your file has exactly the format as shown in your question. However, it would be easy to make parsing more flexible with respect to optional whitespace.

    • that you only want to replace entries if they have a specific current value (or none); this too could easily be changed to replace the values irrespective of the current value.

  • Matching is case-insensitive, as PowerShell generally is by default; add the -CaseSensitive switch to make it case-sensitive.

Output:

[Datoformat] Separator=. [Eksport] Automatisk=Nei [Paaminnelse] Automatisk=Ja AutomatiskService=Nei Tidspunkt=10:00 [Printer] AutomatiskEpost=Nei AntallDagerFrem=Ja AntallDagerFremAntall=2 
Sign up to request clarification or add additional context in comments.

Comments

1

Theo and mklement0 have both pointed to the PsIni-module which does exactly what I wanted to do - so consider the question answered.

Set-IniContent $inifile -Sections 'Paaminnelse' -NameValuePairs @{ Automatisk='Ja'; Tidspunkt='10:00'; AntallDagerFrem='Ja' } | Out-IniFile $inifile -Force 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.