Home > Mobile >  Not Running Second elseif Statement - Powershell
Not Running Second elseif Statement - Powershell

Time:09-17

I am having problems getting this script to run both statements. I have to run the script twice for this to work. When I run once it does the first statement and installs driver. But it doesn't do the second. But when I run it again then it does the second. Any help would be appreciated. Also please forgive my script not being well written. I know I can do this with less code too. I am learning and flying by the seat of my pants. Here is the script below:

$devicesTwo = Get-WmiObject Win32_PNPEntity | Where-Object{$_.ConfigManagerErrorCode -ne 0} | Select-Object -Property CompatibleID 
$devices = Get-WmiObject Win32_PNPEntity | Where-Object{$_.ConfigManagerErrorCode -ne 0} | Select-Object -Property HardwareId 
$unknown_Dev = $devices
$unknown_Dev_Two = $devicesTwo


 ForEach($ProblemDevice in $unknown_Dev) {

    $ProblemDevice.HardwareID[0]
 
    $test = $ProblemDevice

    } 

 ForEach($ProblemDeviceTwo in $unknown_Dev_Two) {

    

    $ProblemDeviceTwo.CompatibleID[0]
 
    $testTwo = $ProblemDeviceTwo

    } 


#Get List of Drivers from Folder
$folderWithDrivers = "C:\Users\Tech\Desktop\Drivers"
#Collect driver info
$drivers = Get-ChildItem $folderWithDrivers -Include *.inf -Recurse
#$drivers | Select Name 

 forEach ($device in $drivers){
       
      $found = Get-Content $device

       if ($found | Select-String $test.HardwareID -SimpleMatch) {

           pnputil /add-driver $device /install


        }
        

        elseif ($found | Select-String $testTwo.CompatibleID -SimpleMatch) {
            
            pnputil /add-driver $device /install

        }

        
        else {
       
    
            Write-Host "Not Found"

        }
        } 

CodePudding user response:

Continuing from my comment. . . here's some quick scripting that may work for you.

# Assign folder folder path that contains drivers to variable
$Divers_Path = "C:\Users\Tech\Desktop\Drivers"

# Get a listing of all .inf files in my Drivers folder.
$Driver_Files = Get-ChildItem -Path $Divers_Path -Filter '*.inf' -File -Recurse -ErrorAction SilentlyContinue

# Get all unknown devices
$UNK_Devices = Get-CimInstance -Query "Select Name,CompatibleID,HardwareID From Win32_PNPEntity Where ConfigManagerErrorCode != 0"
    foreach ($Device in $UNK_Devices) 
    {
        $MaxCount = ($Device.HardwareID.Count, $Device.CompatibleID.Count | Measure-Object -Maximum).Maximum
            if ($MaxCount -ge 1) {
                # Something here. Preferably a verbose message:)
                for ($i=0; $i -lt $MaxCount; $i  )
                {
                
                    $HWID_Found_Match = try { Select-String -Path $Driver_Files -Pattern $Device.HardwareID[$i] -SimpleMatch } catch { }
                        if ($HWID_Found_Match) {
                        
                            foreach ($File in $HWID_Found_Match.Path) 
                            {
                                PNPUtil.exe /Add-Driver $File /Install
                            }

                        }
                        else {

                            # no matches $HWID found

                        }

                    $CID_Found_Match  = try { Select-String -Path $Driver_Files -Pattern $Device.CompatibleID[$i] -SimpleMatch } catch { }
                        if ($CID_Found_Match) {

                            foreach ($File in $CID_Found_Match.Path) 
                            {
                                PNPUtil.exe /Add-Driver $File /Install
                            }

                        }
                        else {

                            # no matches $CID found

                        }

                }
            }
            else {

                "No matches found for:$($Device.Name)"

            }

    }

It would honestly benefit you a little more to use a switch statement instead but, this will do. As to your question, like mentioned in my comment, only the first condition that is met will run:

$One = 'one'
    if ($One -eq 'One') {
        # Condition is met.
        # Only run this block of code.
        'One Found'

    }
    elseif ($One -eq 'One') {
        # Condition is met but, so was the 1st "if", so this
        # will not Run.
        'One Found Again'

    }
    else {
        # This runs if none of the top conditions are met.
        'anything'

    }

# result:
# One Found

Whereas a switch statement run all blocks of codes where the condition is met unless specified to stop (break).

$One = 'one'
    switch ($One) {

        'one' { "I ran Once" }
        'one' { "I ran twice" }
        'Two' { "Two"}
        'three' {'Three' }

    }
# result:
# I ran Once
# I ran twice

You could technically switch out everything inside the for loop to just this:

                    $Found_Matches = try   { Select-String -Path $Driver_Files -Pattern $Device.HardwareID[$i],$Device.CompatibleID[$i] -SimpleMatch } 
                                     catch { try { Select-String -Path $Driver_Files -Pattern $Device.HardwareID[$i] -SimpleMatch } catch { Select-String -Path $Driver_Files -Pattern $Device.CompatibleID[$i] -SimpleMatch } }

                        switch ($Found_Matches) 
                        {
                            { $_ -match $Device.HardwareID[$i] }   { $_.Path}
                            { $_ -match $Device.CompatibleID[$i]}  { $_.Path }
                        }

Excuse the ugly try and catch blocks, as it was the only way to silence the errors I was getting.

  • Related