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.