help with switch

This topic contains 8 replies, has 4 voices, and was last updated by  michael glenn 2 years, 1 month ago.

  • Author
    Posts
  • #29835

    michael glenn
    Participant

    trying to build a script that will test for numerous paths(in the registry.. but im using a file path to keep it simple)
    from what iver read, "switch" would be a better option then just "if/else".
    im having a problem figuring out the logic/flow/process and im looking for suggestions.
    this is what ive got so far.. and ive tried some other things as well.

    foreach ($computer in $computers) {
                             
        if (test-connection -cn $computer -quiet -count 1) {
                try {       
                    if( invoke-command -computername $computer -scriptblock {test-path -path c:\ver1 } -ErrorAction Stop)
                        {$ver -eq $true }
                    if( invoke-command -computername $computer -scriptblock {test-path -path c:\ver2 } -ErrorAction stop)
                        {$ver -eq $true}
                    if( invoke-command -computername $computer -scriptblock {test-path -path c:\ver3 } -ErrorAction stop)
                        {$ver-eq $true}
                    if(invoke-command -computername $computer -scriptblock {test-path -path c:\ver4 } -ErrorAction stop)
                        {$ver-eq $true}
                    if(invoke-command -computername $computer -scriptblock {test-path -path c:\ver5} -ErrorAction stop )
                        {$ver-eq $true}
                                   
                }     
                catch [Management.Automation.Remoting.PSRemotingTransportException] { 
                       write-host "$computer might not be online and reachable...catch statment"
                } 
            }
        
     switch ($ver){
        1 {write-host "$computer has ver 1 on it" }
        2 {write-host "$computer has ver 2 on it" }
        3 {write-host "$computer has ver 3 on it" }
        4 {write-host "$computer has ver 4 on it" }
        5 {write-host "$computer has ver 5 on it" }
        
        default {write-host "$computer has no detected version" }                 
     }
        
        }
       
    
  • #29837

    Daniel Krebs
    Moderator

    You approach with multiple ifs and switch does not scale very well and contains a lot of duplicated code.

    Check out below refactored code (not tested) based on your example:

    #Requires -Version 3.0
    # Needs PowerShell version 3.0 or newer
    
    $PathList = @(
        'c:\ver1'
        'c:\ver2'
        'c:\ver3'
        'c:\ver4'
        'c:\ver5'
    )
    
    $OverallResults = foreach ($computer in $computers)
    {
        if (Test-Connection -ComputerName $computer -Quiet -Count 1)
        {
            try {
                $Results = @(
                    Invoke-Command -ComputerName $computer -ErrorAction Stop -ScriptBlock {
                       
                        foreach ($Path in $Using:PathList)
                        {
                            [PSCustomObject]@{
                                Path = $Path
                                Found = (Test-Path -Path $Path)
                            }
                        }
                    }
                )
            }     
            catch [Management.Automation.Remoting.PSRemotingTransportException] 
            { 
                Write-Error -Message "$computer might not be online and reachable...catch statment"
            }
            
            if ($Results.Count -eq 0)
            {
                Write-Verbose -Message "$computer has no detected version" -Verbose
            }
            else
            {
                Write-Output -InputObject $Results
            }
        }
    }
    
    $OverallResults | Format-Table -AutoSize
    
  • #29839

    michael glenn
    Participant

    but what im trying to eventually do is run a script that will remove the found version/versions of the application, hence the thought that "switch" would be a better option. so testing a pc for various version/s.. and if numerous versions are found.. running different commands based on which version or versions that it finds.

  • #29845

    Bob McCoy
    Participant

    In the first place, you're only returning $true to the $ver variable, so it's never going to satisfy any of the switch conditions. So you'll always end up with the default.

    The best approach is to do some more efficient detection logic like Daniel mentioned (being sure to break out of the foreach loop so you don't continue to test for conditions that won't be met), that you can then use in your switch statement to affect whatever action you want to take.

  • #29869

    michael glenn
    Participant

    ok.. ill look in that direction a little more... im not understanding the switch logic. gotta keep reading. thanks for the help guys.

  • #29875

    Dan Potter
    Participant

    Way over complicating things. Get-childitem \\$server\c$ |where name -like ver*

    output the name and the server.

  • #29877

    michael glenn
    Participant

    my apologies dan.. I was attempting to minimize my coding here and not bog down the forum with my not so great attempt at coding,and use a directory path as opposed to a registry path. the end result being to detect the presence of an application and then run an msi to remove the version....the fact that there were more then one version of the app on a pc, I thought the best solution would be a script using "switch" as opposed to if else statements. up until now I hadn't experimented with switch at all and was looking forward to giving it a go. I think I understand the basic premise of switch, but ive confused myself by complicating it, or perhaps im asking powershell to do something it cant. various paths being tested... a different solution for each of those paths... perhaps a simple if statement for each of those paths is the better choice.. no need for switch in this situation. it will run through each if statement and if its a match will do what is expected.

  • #29881

    Dan Potter
    Participant

    $ver -eq $true wouldn't actually set anything. You would have to use =. That said, for your switch to work you would have to set $ver = 1,2,3 etc.

    $answer = read-host 'pick a number 1-3'
    switch($answer){1{'one'};2{'two'};3{'three'}}

    get-childitem works with reg items as well.

  • #29883

    michael glenn
    Participant

    didn't realize that about get-childitem... good to know thanks.
    ive got my script working well with the multiple if's.. im gonna keep playing with switch though... eventually im thinking im gonna be needing it for something else.
    thanks for the suggestions.

You must be logged in to reply to this topic.