Replace Odd and Even Values

I want to change the computer locations in multiple test files base on whether they are even or odd

What is the best cmdlet and also syntax to run, if you want to replace all the computers whose computername end with an even number and also all the computernames whose computername ends with odd numbers.

i.e If computername = Pec122(Even number) then

 $_.Replace (Locaion="Nedy" ','Location="Dale"')

else

  $_.Replace (Locaion="Jam" ','Location="Yale"')

Is that number on the end always three characters long?

Yes, the number at end for the computer name is always three characters long. i.e DaleHR-123 or DaleHR-122

Using a simple function from MOW: /\/\o\/\/ PowerShelled: PowerShell : How Can I Tell Whether a Number is Even or Odd?

Function check-even [$num] {[bool]![$num%2]}

$Computers = "Computer-102", "Computer-009", "Computer-015", "Computer-232", "Computer424"

foreach [$computer in $computers] {
    if [$computer -like "*-*"] {
        [int]$computerNum = $computer.Split["-"][1]
        if[[check-even $computerNum] -eq $true] {
            #even
            "Do something for even computer: {0}" -f $computer
        }
        else {
            #odd
            "Do something for odd computer: {0}" -f $computer
        }
    }
    else {
        "Computer does not meet naming standards:  {0}" -f $computer
    }
}

Output:

Do something for even computer: Computer-102
Do something for odd computer: Computer-009
Do something for odd computer: Computer-015
Do something for even computer: Computer-232
Computer does not meet naming standards:  Computer424

Thanks Rob. Below is what Iam trying to achieve.

I am trying replace values in an ini. file based on odd or even numbers in the last digits.

$files = Get-ChildItem -Path c:\Test*.ini
foreach ($file in $files) {
$newfilename = $file.fullname -replace “.ini”, “.txt”

Get-Content $file.fullname |
ForEach {
$PrinterName = @(

‘AC-10-170’
‘AC-11-171’
‘ac-11-173’
‘ac-11-175’
‘ac-11-176’
‘ac-11-180’
‘ac-11-181’
‘AC-11-182’
‘ac-11-183’
‘ac-11-185’
‘ac-11-186’
‘ac-11-187’
'ef-11-218
‘ef-11-219’
‘ef-11-222’
‘ef-11-223’
‘ef-4-207’
‘ef-4-208’
‘ef-4-211’
‘ef-4-212’
‘ef-4-213’
‘ef-4-215’
‘EF-4-220’
‘ef-4-224’
‘ef-4-225’
‘ef-4-226’
‘ef-4-227’
)

ForEach($name in $PrinterName) {

         If($name[-1] % 2 -eq 0) { 
      $_.Replace('Host="ACFILE01"','Host="VJJJRT02"').Replace('Host="effile01"','Host="VJJJRT02"') 
 } Else { 

 
 }$_.Replace('Host="ACFILE01"','Host="VSHHPRT01"') .Replace('Host="ACFILE01"','Host="VSHHPRT01"')
 
 }   

} |
Out-File $newfilename
}

***Desired output should be:

DefaultPrinter=SMB2
Printer=SMB2 Local Name=“Windows Printer | AC-10-170” Host=“VJJJRT02” Name=“AC-10-170” PrinterID=“HP LaserJet 4100 Series PCL6” Class=“PCL5” Enabled=yes

Quick Reply

The code you posted had a lot of syntax errors and I don’t know if it’s indented in your editor, but every time you don’t indent your code a puppy dies, so you should really do it. When the code is indented, the logic does not make sense

For each ini file
For each line in the ini file
For each printer in the list
if the printer is even replace this line else replace this line

So, you are going thru a list of printers on every line of the INI file. The logic would indicated that every line is going to be ODD because the last printer in the list is ‘ef-4-227’. Here is a cleaned up version of the code with indention, but you still need to check this logic as it will always result in ODD and you’re not doing anything with the printer names in the actual logic, like if you see this printer in the INI, then do X

#http://mow001.blogspot.com/2006/10/powershell-how-can-i-tell-whether.html
Function check-even ($num) {[bool]!($num%2)}


 $printers = @('AC-10-170',
               'AC-11-171',
               'ac-11-173',
               'ac-11-175',
               'ac-11-176',
               'ac-11-180',
               'ac-11-181',
               'AC-11-182',
               'ac-11-183',
               'ac-11-185',
               'ac-11-186',
               'ac-11-187',
               'ef-11-218',
               'ef-11-219',
               'ef-11-222',
               'ef-11-223',
               'ef-4-207',
               'ef-4-208',
               'ef-4-211',
               'ef-4-212',
               'ef-4-213',
               'ef-4-215',
               'EF-4-220',
               'ef-4-224',
               'ef-4-225',
               'ef-4-226',
               'ef-4-227')


foreach ($file in (Get-ChildItem -Path c:\Test\*.ini)) {
    $newfilename = $file.fullname -replace ".ini", ".txt"
    foreach ($line in (Get-Content $file.fullname)){
        foreach($printer in $printers) {
            # Get the number off the end of the printer name
            $printerNum = $printer.Split("-")[2]    

            ##############################################
            #####   Logic doesn't make sense here    #####
            ##############################################

            if((check-even $printerNum) -eq $true) {
                #even
                $line.Replace('Host="ACFILE01"','Host="VJJJRT02"').Replace('Host="effile01"','Host="VJJJRT02"')
            } 
            else { 
                #odd
                $line.Replace('Host="ACFILE01"','Host="VSHHPRT01"').Replace('Host="ACFILE01"','Host="VSHHPRT01"')
            }
        }
    } 
}

Rob,

Thank you very much for the feed back. I am new to powershell / scripting in general so I appreaciate all the suggestions that you have provided. I have run the script that you have provded and it did not update any of my files.

You are right my logic i might be off.
What Iam trying accomplish is for the script to go thru the ini files.
In the ini files there is a printer name, which ends with either a an odd number or an even number
If the printer name ends with an odd value then change the value in the Host='VJJJRT02"
If the printer name ends with an odd value then change the value in the Host='VJJJRT01"

Thanks

Good Morning Rob,

What would be best a better way to define the logic accomplish what am looking for. Ihave run the script that you have provded and it did not update any of my files.

Thanks

Where does the printer name exist? Is it in the INI file as well? Is there a Printer= line that indicates the printer in the INI? If you were doing it manually, how would you do it step by step? We need to understand how it is supposed to work and what is not working.

Thanks Rob,

Inside of the Ini files there is a printing section as below. The printer name field is called Name. i.e Name="AC-10-170. When I run the script it is not updating the Host field

DefaultPrinter=SMB2
Printer=SMB2 Local Name=“Windows Printer | AC-10-170” Host=“ACFILE01” Name=“AC-10-170” PrinterID=“HP LaserJet 4100 Series PCL6” Class=“PCL5” Enabled=yes

***Desired output should be:

DefaultPrinter=SMB2
Printer=SMB2 Local Name=“Windows Printer | AC-10-170” Host=“VJJJRT02” Name=“AC-10-170” PrinterID=“HP LaserJet 4100 Series PCL6” Class=“PCL5” Enabled=yes

What you need is a regular expression to match a pattern in your INI file. I am not a regex expert, but when you can figure them out you can do some really cool stuff. Someone might provide a better pattern for you, but this worked for what you posted.

INI:

DefaultPrinter=SMB2
 Printer=SMB2 Local Name="Windows Printer | AC-10-170" Host="ACFILE01" Name="AC-10-170" PrinterID="HP LaserJet 4100 Series PCL6" Class="PCL5" Enabled=yes

Code:

#http://mow001.blogspot.com/2006/10/powershell-how-can-i-tell-whether.html
Function check-even ($num) {[bool]!($num%2)}

foreach ($file in (Get-ChildItem -Path c:\Users\rsimmers\desktop\*.ini)) {
    "Processing file {0}" -f $file
    $newfilename = $file.fullname -replace ".ini", ".txt"
    $newContent = foreach ($line in (Get-Content $file.fullname)){
        # This is a regex and will look like something from Star Trek.  Regex will look for a pattern and return matches or do replaces,
        # which is actually what you are doing with.Replace, look for a pattern like 'Host="ACEFILE01"' You can also use pattern matching,
        # such as "| AC-10-170".  The \ is escape because a pipe is used in regex patterns.  Then space and parenthesis indicate a submatch, 
        # because you only what what is after the space and before the double qoute.  .*? basically is capture anything in between here.
        $printer = $line -match '\| (.*?)"'
        $printerName = $Matches[1]
        $printerNum = $printerName.Split("-")[2]    
            

        if((check-even $printerNum) -eq $true) {
            #even
            $line.Replace('Host="ACFILE01"','Host="VJJJRT02"').Replace('Host="effile01"','Host="VJJJRT02"')
        } 
        else { 
            #odd
            $line.Replace('Host="ACFILE01"','Host="VSHHPRT01"').Replace('Host="ACFILE01"','Host="VSHHPRT01"')
        }
    } 
}

$newContent
$newContent | Out-File $newfilename

Output:

DefaultPrinter=SMB2
 Printer=SMB2 Local Name="Windows Printer | AC-10-170" Host="VJJJRT02" Name="AC-10-170" PrinterID="HP LaserJet 4100 Series PCL6" Class="PCL5" Enabled=yes

Rob

Thank you very much. For your help. I was able to run the script against my ini files. What I find out was tha,t when I run the script against multiple files it is giving me the message below and is not updating any files. But when I run the script against one ini.file it is working fine.

Processing file \vfs04\Users$\kaendm\Desktop\Test00E8E627F9C.ini
Cannot index into a null array.
At C:\Powershell\TReplaceIniValues.ps1:12 char:9

  •     $printerName = $Matches[1]
    
  •     ~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidOperation: (:slight_smile: , RuntimeException
    • FullyQualifiedErrorId : NullArray

You cannot call a method on a null-valued expression.
At C:\Powershell\TReplaceIniValues.ps1:13 char:9

  •     $printerNum = $printerName.Split("-")[2]
    
  •     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidOperation: (:slight_smile: , RuntimeException
    • FullyQualifiedErrorId : InvokeMethodOnNull