Check for value and modify if there, add if not, in notes.ini file

First off, I am OK with powershell but not anywhere close to an expert. Typically if I find code that is close I can make it work but sometimes like right now I get stuck. I am trying to do a few things in a script. We are migrating from Notes to Outlook (Finally) and I have a PS script that does all the required changes EXCEPT checking the notes.ini file for each user for “DontCheckDefaultMail” If not there write it, if there check the value if “1” leave it alone, of “0” change to “1”

here is the chunk of code I am trying to use but I am being prompted to “supply values for the following parameters: Process” Im at a loss as to what it is asking for.

This code is a combo of code from a couple different sources, so its 100% possible that its all goofed up :slight_smile: What I an trying, and failing, to do is read through all user profiles and look for AppData\Local\IBM\Notes\data\notes.ini, If found read the INI file and look for “DontCheckDefaultMail”, what I need it to then do is… If not found add it with a value of “1”, if found and value is “1” leave it along, If value not “1” set it to “1”. I know my script currently doesnt do all of these items, but I can’t even get it to run currently.

$Destination = ‘C:\Users*\AppData\Local\IBM\Notes\data’
Get-ChildItem $Destination | ForEach-Object
{
$files = Get-ChildItem -Path “$Destination\notes.ini”
foreach ($file in $files)
{
#$newfilename = $file.fullname -replace “.ini”, “-2.ini”
Get-Content $file |
ForEach {

						$_.Replace('DontCheckDefaultMail=0 ', 'DontCheckDefaultMail=1')
					} | Out-File $file
		
			
		}
	}

Ah, I see you’ve stumbled onto on of the issues with One True Brace styling in PS. ForEach-Object, along with several other cmdlets (and its alias foreach, which is confusing and should be removed, really!) are NOT code keywords. They’re cmdlets. This means that this will not work:

$Thing | ForEach-Object
{
    $Stuff
}

It must be done like this:

$Thing | ForEach-Object {

}

This is because the script block here is passed as a parameter to the cmdlet. A line break means in most cases to PS, and always after a cmdlet, “this line is finished, move on”, so if you do this when a cmdlet requires a parameter (in this case, a script block), PS cannot continue.

So, your code needs to be more like:

$Destination = 'C:\Users\*\AppData\Local\IBM\Notes\data'
Get-ChildItem $Destination | ForEach-Object {
    $files = Get-ChildItem -Path "$Destination\notes.ini"
    foreach ($file in $files) {
        #$newfilename = $file.fullname -replace ".ini", "-2.ini"
        Get-Content $file | ForEach-Object {
            $_.Replace('DontCheckDefaultMail=0 ', 'DontCheckDefaultMail=1')
        } | Set-Content $file
    }
}

Although I too like OTBS, I would recommend that to avoid weird things like this, consider simply switching over to the other syntax in general:

foreach ($i in $j) {

}

Because while a line break before a brace will work for language keywords (function, try, catch, if, else, class, filter, while, foreach, etc.) it will not work for any cmdlet (ForEach-Object, a ‘foreach’ that is in a pipeline [because it’s just the ForEach-Object alias, same cmdlet], Where-Object, etc., etc.)

Im closer now :slight_smile:

 
		$name = "DontCheckDefaultMail"
		$Destination = 'C:\Users\*\AppData\Local\IBM\Notes\data'
		$output = "$Destination\notes.ini"
		Get-ChildItem $Destination | ForEach-Object {
			$files = Get-ChildItem -Path "$Destination\notes.ini"
			foreach ($file in $files)
			{
				Get-Content $file.fullname |
				ForEach {
					$_.Replace('DontCheckDefaultMail="0"', 'DontCheckDefaultMail="1"')
					
				} |
				Out-File $file
			}
		}

But instead of writing the correct “1” after the key it blanked the entire INI :slight_smile:

I know I did something stupid, but I’m not sure what

oh, right, I’m surprised I didn’t catch that.

.Replace() is a .NET based method that’s designed to replace single characters. It doesn’t work predictably if you give it entire strings. Swap that replace line for the Powershell native replace method, which is comfortable with whole strings, and regex if you ever need it:

$_ -replace 'DontCheckDefaultMail\="0"', 'DontCheckDefaultMail\="1"'

I inserted some backslashes to escape the equal signs because I’m pretty sure they’re used for something specific in regex, and we just want to match the exact characters. You can also use [Regex]::Escape(‘string’) to automatically escape special characters if you’re just matching a literal string.

Joel,

Thank you for your help but it is still blanking out the entire ini file.
here is the code I am using.

		$name = "DontCheckDefaultMail"
		$Destination = 'C:\Users\*\AppData\Local\IBM\Notes\data'
		$output = "$Destination\notes.ini"
		Get-ChildItem $Destination | ForEach-Object {
			$files = Get-ChildItem -Path "$Destination\notes.ini"
			foreach ($file in $files)
			{
				Get-Content $file.fullname |
				ForEach {
					$_ -replace 'DontCheckDefaultMail\="0"', 'DontCheckDefaultMail\="1"'
					
				} |
				Out-File $file
			}
		}

Bill

I have been beating my head against this all morning and I have found a different method that is very close to working…
This code now searches for the DontCheckDefaultMail key, and if the value is 0 changes it to 1… BUT I can’t figure out how to add the line if it isnt there. I know the line $_.Replace(‘’, ‘DontCheckDefaultMail=1’) is not correct, it was just an attempt :stuck_out_tongue:

		$files = Get-ChildItem -Path C:\Users\pta87081\AppData\Local\IBM\Notes\Data\notes.ini
		foreach ($file in $files)
		{
			$newfilename = $file.fullname -replace ".ini", "-2.ini"
			Get-Content $file.fullname |
			ForEach {
				
				if ('dontcheckdefaultmail'){
					$_.Replace('DontCheckDefaultMail=0', 'DontCheckDefaultMail=1')
				}
				else
				{
					$_.Replace('', 'DontCheckDefaultMail=1')
				}
			} |
			Out-File $newfilename
		}

I have it working, except teh search for if the key is in the INI already…

It is kludgy but works :stuck_out_tongue:

$Destination = 'C:\Users\*\AppData\Local\IBM\Notes\data'
	
		Get-ChildItem $Destination | ForEach-Object {
			$files = Get-ChildItem -Path "$Destination\notes.ini"
			
			foreach ($file in $files)
			{
				$newfilename = $file.fullname -replace ".ini", "-2.ini"
				$fileold = $file.fullname -replace ".ini", ".old.ini"
				Get-Content $file.fullname |
				ForEach {
					
					if ('dontcheckdefaultmail')
					{
						$_.Replace('DontCheckDefaultMail=0', 'DontCheckDefaultMail=1')
					}
					
				} |
				Out-File $newfilename
				
				Rename-Item -Path "$file" -NewName "$fileold" -force
				Rename-Item -Path "$newfilename" -NewName "$file" -force
			}
		}

I responded to this in a different thread.

https://powershell.org/forums/topic/check-for-ini-value-and-modify-if-there-add-if-not-in-notes-ini-file/

Im not sure how this got double posted.

Rob thank you for your link to the other post.