Replace Odd and Even Values

This topic contains 11 replies, has 3 voices, and was last updated by  Mikhael Kaendera 2 years, 5 months ago.

  • Author
    Posts
  • #24113

    Mikhael Kaendera
    Participant

    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"')

  • #24124

    Ondrej Zilinec
    Participant

    Is that number on the end always three characters long?

  • #24133

    Mikhael Kaendera
    Participant

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

  • #24139

    Rob Simmers
    Participant

    Using a simple function from MOW: http://mow001.blogspot.com/2006/10/powershell-how-can-i-tell-whether.html

    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
  • #24146

    Mikhael Kaendera
    Participant

    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

  • #24148

    Rob Simmers
    Participant

    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"')
                }
            }
        } 
    }
    
  • #24151

    Mikhael Kaendera
    Participant

    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

  • #24197

    Mikhael Kaendera
    Participant

    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

  • #24200

    Rob Simmers
    Participant

    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.

  • #24202

    Mikhael Kaendera
    Participant

    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" [b]Host="ACFILE01"[/b] 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[b]="VJJJRT02"[/b] Name="AC-10-170" PrinterID="HP LaserJet 4100 Series PCL6" Class="PCL5" Enabled=yes

  • #24204

    Rob Simmers
    Participant

    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
    
  • #24209

    Mikhael Kaendera
    Participant

    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: (:) [], 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: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

You must be logged in to reply to this topic.