Author Posts

September 16, 2015 at 10:38 am

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" }                 
 }
    
    }
   

September 16, 2015 at 11:09 am

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

September 16, 2015 at 11:26 am

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.

September 16, 2015 at 7:54 pm

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.

September 17, 2015 at 4:10 am

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

September 17, 2015 at 7:43 am

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

output the name and the server.

September 17, 2015 at 8:09 am

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.

September 17, 2015 at 9:41 am

$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.

September 17, 2015 at 10:05 am

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.