none
Switch statement giving unexpected results RRS feed

  • Question

  • Hi,

    I have a task to upgrade all versions of Firefox on the network to the latest version available and should be the same language as the original installation. In my snippet below, I have commented out all of the variables. When I execute the script, I was expecting it to run the 'default' statement but instead is setting the variable with one of the other values. The list of variables are being used to represent samples of the results that will be collected from the registry for unit testing purposes. When it runs in production, there will only be one variable with a string similar to what is assigned to the variables at the top of the script.

    I have tried using double quotes on the cases, tried single quotes on the cases, deleting all variables but one, and adding the break statement but the result is the same. I am testing this using ISE as admin.

    Why is this script doing this? Shouldn't this switch statement use default in this example? Does ISE keep the values of the variables between executions using values that already exist in memory?  It is acting as though the variables are receiving their assignments even though they are commented out.

    #$var1 = "Mozilla Firefox 69.0 (x64 en-US)"
    #$var2 = "Mozilla Firefox 53.0 (x86 ru)"
    #$var3 = "Mozilla Firefox 68.0.2 (x64 nl)"
    #$var4 = "Mozilla Firefox 43.0.3 (x86 es-ES)"
    #$var5 = "Mozilla Firefox 43.0.3 (x86 es-MX)"
    #$var6 = "Mozilla Firefox 40.0.3 (x86 en-US)"
    #$var7 = "Mozilla Firefox 60.0 (x64 es-ES)"
    #$var8 = "Mozilla Firefox 60.0.2 (x64 es-MX)"
    
    $setup = ""
    
    switch -wildcard ($var8) {
    
    '*(x86 en-US)' {$setup = "Setup-x64-us.msi"}
    '*(x64 en-US)' {$setup = "Setup-x64-us.msi"}
    
    '*(x86 es-ES)' {$setup = "Setup-x64-es.msi"}
    '*(x64 es-ES)' {$setup = "Setup-x64-es.msi"}
    
    '*(x86 es-MX)' {$setup = "Setup-x64-mx.msi"}
    '*(x64 es-MX)' {$setup = "Setup-x64-mx.msi"}
    
    '*(x64 nl)' {$setup = "Setup-x64-nl.msi"}
    '*(x86 ru)' {$setup = "Setup-x64-ru.msi"}
    
    default {$setup = "language unknown"}
    
    }
    
    write-host ""
    $setup
    write-host ""

    I have done some research but haven't found a similar scenario in my searches. As the script is configured in this example, the result is always Setup-x64-mx.msi when I am expecting the output to be 'language unknown'.

    Thank you!

    Rob


    • Edited by robwm1 Friday, September 6, 2019 8:22 PM
    Friday, September 6, 2019 8:21 PM

Answers

  • My psychic debugging tells me that you have defined the variables in the current session and expecting them to disappear after you run your code again in the current session. Where variables appear and when is called scope.

    Close your PowerShell instance, put your code in a script file, and then run the script to make sure that the variable are only defined when the script runs (when the script ends, the variables disappear).

    (Also, you don't need $var1, $var2, etc. We have arrays.)


    -- Bill Stewart [Bill_Stewart]

    • Marked as answer by robwm1 Friday, September 6, 2019 10:00 PM
    Friday, September 6, 2019 8:46 PM
    Moderator

All replies

  • My psychic debugging tells me that you have defined the variables in the current session and expecting them to disappear after you run your code again in the current session. Where variables appear and when is called scope.

    Close your PowerShell instance, put your code in a script file, and then run the script to make sure that the variable are only defined when the script runs (when the script ends, the variables disappear).

    (Also, you don't need $var1, $var2, etc. We have arrays.)


    -- Bill Stewart [Bill_Stewart]

    • Marked as answer by robwm1 Friday, September 6, 2019 10:00 PM
    Friday, September 6, 2019 8:46 PM
    Moderator
  • I started to feel like that was the case. When I run the script in the PowerShell app (not ISE), it executes as expected every time. I want to try out using -or on the strings that have the same language too. That didn't work in ISE but now I am starting to realize why. I had no idea ISE cached variables.

    This was a simple unit test. I do use arrays often but I wanted more isolation in this case. Perhaps I'm not thinking of this correctly based on your comment.


    • Edited by robwm1 Friday, September 6, 2019 8:54 PM
    Friday, September 6, 2019 8:52 PM
  • This doesn't seem to work reliably:

    $var1 = "Mozilla Firefox 69.0 (x64 en-US)"
    $var2 = "Mozilla Firefox 53.0 (x86 ru)"
    $var3 = "Mozilla Firefox 68.0.2 (x64 nl)"
    $var4 = "Mozilla Firefox 43.0.3 (x86 es-ES)"
    $var5 = "Mozilla Firefox 43.0.3 (x86 es-MX)"
    $var6 = "Mozilla Firefox 40.0.3 (x86 en-US)"
    $var7 = "Mozilla Firefox 60.0 (x64 es-ES)"
    $var8 = "Mozilla Firefox 60.0.2 (x64 es-MX)"
    
    $setup = ""
    
    switch -wildcard ($var1) {
    
    {"*(x86 en-US)" -or "*(x64 en-US)"} {$setup = "Setup-x64-us.msi"}
    
    
    {"*(x86 es-ES)" -or "*(x64 es-ES)"} {$setup = "Setup-x64-es.msi"}
    
    
    {"*(x86 es-MX)" -or "*(x64 es-MX)"} {$setup = "Setup-x64-mx.msi"}
    
    
    "*(x64 nl)" {$setup = "Setup-x64-nl.msi"}
    "*(x86 ru)" {$setup = "Setup-x64-ru.msi"}
    
    default {$setup = "language unknown"}
    
    }
    
    write-host ""
    $setup
    write-host ""

    I saw an example of doing this but not exactly like this snippet.

    Friday, September 6, 2019 9:00 PM
  • Here is how to use an "OR" condition in a switch statement.

    $var8 = 'Mozilla Firefox 60.0.2 (x64 es-MX)'
    
    $setup = switch -RegEx ($var8) {
        '.*x64 nl|.*x64 es-MX'  {'OR CONDITION - Setup-x64-ru.msi'}
        '.*x86 en-US'           {'Setup-x64-us.msi'}
        '.*x64 en-US'           {'Setup-x64-us.msi'}
        '.*x86 es-ES'           {'Setup-x64-es.msi'}
        '.*x64 es-ES'           {'Setup-x64-es.msi'}
        '.*x86 es-MX'           {'Setup-x64-mx.msi'    }
        '.*x64 es-MX'           {'Setup-x64-mx.msi'}
        '.*x64 nl'              {'Setup-x64-nl.msi'}
        '.*x86 ru'              {'Setup-x64-ru.msi'}
        default                 {'language unknown'}
    }
    $setup[0]
    $setup[1]

    Note the results.  If you don't want all matches then use "break".


    \_(ツ)_/





    • Edited by jrv Friday, September 6, 2019 9:11 PM
    Friday, September 6, 2019 9:08 PM
  • Nice approach. I like it!

    Below is working as expected. I learned that spaces in your regex case does not give expected results.

    $var1 = "Mozilla Firefox 69.0 (x64 en-US)"
    $var2 = "Mozilla Firefox 53.0 (x86 ru)"
    $var3 = "Mozilla Firefox 68.0.2 (x64 nl)"
    $var4 = "Mozilla Firefox 43.0.3 (x86 es-ES)"
    $var5 = "Mozilla Firefox 43.0.3 (x86 es-MX)"
    $var6 = "Mozilla Firefox 40.0.3 (x86 en-US)"
    $var7 = "Mozilla Firefox 60.0 (x64 es-ES)"
    $var8 = "Mozilla Firefox 60.0.2 (x64 es-MX)"
    
    $setup = switch -regex ($var1) {
    
    '.*x86 en-US|.*x64 en-US' {'Setup-x64-us.msi';break}
    '.*x86 es-ES|.*x64 es-ES' {'Setup-x64-es.msi';break}
    '.*x86 es-MX|.*x64 es-MX' {'Setup-x64-mx.msi';break}
    '.*x64 nl' {'Setup-x64-nl.msi';break}
    '.*x86 ru' {'Setup-x64-ru.msi';break}
    
    default {'language unknown'}
    
    }
    
    write-host ""
    $setup
    write-host ""

    Thank you for your help on this!

    Rob

    • Edited by robwm1 Friday, September 6, 2019 9:37 PM
    Friday, September 6, 2019 9:16 PM