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.
CodePudding user response:
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
CodePudding user response:
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