Скрипт удаления старых драйверов

Сценарий к статье Павла Чубарова автоматизирующий удаление устаревших драйверов из папки С:\windows\system32\DriverStore\FileRepository.

При установке драйверов старые версии сохраняются в системе, данный скрипт удаляет все дубликаты кроме драйвера имеющего самую последнюю дату

Может кому пригодится.

Сценарий получает список драйверов в системе выполняя команду:

dism /online /get-drivers

Затем идет парсинг текстового вывода, на выходе получаются нормальные объекты с которыми можно работать.

После выбираются дубликаты и сортируются по дате. Самый последний драйвер из списка исключается

Для каждого файла в списке вызывается консольная утилита pnputil с параметром удаления драйвера, если какойто драйвер не удалится добавьте еще ключ -f.


<#
    2016.09.01
    перечисляет драйвера в системе
    находит дубликаты в хранилище и удаляет их
    если вам нужно только посмотреть драйвера закомментируйте 133 строку
    если драйвер нужно удалить принудительно используйте pnputil.exe -f -d
#>

#[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("cp866")

# получаем список драйверов
$temp = dism /online /get-drivers
$Lines = $temp | select -Skip 10

$Operation = "ItIsName"
$Drivers = @()

foreach ( $Line in $Lines ) {

    $temp1 = $Line
    $text = $($temp1.Split( ':' ))[1]

    switch ($Operation) {

        'ItIsName' { $Name = $text
                     $Operation = 'ItIsFileName'
                     break
                   }

        'ItIsFileName' { $FileName = $text.Trim()
                         $Operation = 'ItIsVhod'
                         break
                       }

        'ItIsVhod' { $Vhod = $text.Trim()
                     $Operation = 'ItIsClassName'
                     break
                   }

        'ItIsClassName' { $ClassName = $text.Trim()
                          $Operation = 'ItIsVendor'
                          break
                        }

        'ItIsVendor' { $Vendor = $text.Trim()
                       $Operation = 'ItIsDate'
                       break
                     }

        'ItIsDate' { # переводим дату в европейский стандарт, чтобы сортировать
                     $tmp = $text.split( '.' )
                     $text = "$($tmp[2]).$($tmp[1]).$($tmp[0].Trim())"
                     $Date = $text
                     $Operation = 'ItIsVersion'
                     break
                   }

        'ItIsVersion' { $Version = $text.Trim()
                        $Operation = 'ItIsNull'

                        $params = [ordered]@{ 'FileName' = $FileName
                                              'Vendor' = $Vendor
                                              'Date' = $Date
                                              'Name' = $Name
                                              'ClassName' = $ClassName
                                              'Version' = $Version
                                              'Vhod' = $Vhod
                                            }
    
                        $obj = New-Object -TypeName PSObject -Property $params
                        $Drivers += $obj

                        break
                      }

         'ItIsNull' { $Operation = 'ItIsName'
                      break
                     }

    }
}

Write-Host "все драйверы" -ForegroundColor Yellow
Write-Host "-------------------" -ForegroundColor Yellow
$Drivers | sort Filename | ft



Write-Host "несколько версий драйверов" -ForegroundColor Yellow
Write-Host "-------------------" -ForegroundColor Yellow

$last = ''
$NotUnique = @()

foreach ( $Dr in $($Drivers | sort Filename) ) {
    
    if ($Dr.FileName -eq $last  ) {  $NotUnique += $Dr  }
    $last = $Dr.FileName
}

$NotUnique | sort FileName | ft



Write-Host "устаревшие версии драйверов" -ForegroundColor Yellow
Write-Host "-------------------" -ForegroundColor Yellow
$list = $NotUnique | select -ExpandProperty FileName -Unique

$ToDel = @()
foreach ( $Dr in $list ) {
    Write-Host "найден дубликат" -ForegroundColor Yellow
    $sel = $Drivers | where { $_.FileName -eq $Dr } | sort date -Descending | select -Skip 1
    $sel | ft

    $ToDel += $sel
}

Write-Host "драйвера на удаление" -ForegroundColor Green
Write-Host "-------------------" -ForegroundColor Green
Write-Host "будте осторожны, любые автоматические действия опасны" -ForegroundColor Green

$ToDel | ft



# удаляем драйвера
foreach ( $item in $ToDel ) {
    $Name = $($item.Name).Trim()

    Write-Host " " -ForegroundColor Green
    Write-Host "удаляем $Name" -ForegroundColor Green
    Write-Host "pnputil.exe -d $Name" -ForegroundColor Green
    Invoke-Expression -Command "pnputil.exe -d $Name"
}

Спасибо за внимание!

Комментарии (5)

  • 9 января 2017 в 15:02 (комментарий был изменён)

    0

    Помню то же столкнулся с подобной проблемой. Винда сохранила драйвер для принтера, а в самом драйвере появилась ошибка. Он начал печатать пакеты один пакет одна страница. Беда в том что при простом удалении, винда восстанавливала драйвер и не давала переустановить. В итоге ползли в эту папку и удаляли с помощью рук все её драйверы. Тока потом она дала шанс установить новенький и чистенький драйвер.
    Как говорится век живи, век учись. Сохраню страничку вдруг пригодится.
  • 9 января 2017 в 15:12 (комментарий был изменён)

    0

    Благодарю, давно искал что-то консольное, что можно запускать автоматически по расписанию.
    До этого пользовался тоже хабраразработкой — pyWinClobber
  • 9 января 2017 в 16:57 (комментарий был изменён)

    0

    Начнём с ошибки:
    Cистема DISM
    Версия: 10.0.14393.0
    Версия образа: 10.0.14393.0
    /Get-Drivers [/Format:<формат_вывода>] [/all]
      Выводит сведения о драйверах в образе.  Чтобы определить вывод результата
      в виде списка или таблицы, используйте параметр /Format.  Если
      параметр /Format не задан, результат форматируется как список.  По
      умолчанию выводятся только готовые драйверы. Чтобы вывести все драйверы
      образа, используйте параметр /all.
        Примеры:
          DISM.exe /Image:C:\test\offline /Get-Drivers
          DISM.exe /Image:C:\test\offline /Get-Drivers /all
          DISM.exe /Image:C:\test\offline /Get-Drivers /Format:Table
    

    Вы же понимаете что обновляются не только драйвера oem*.inf.
    • 9 января 2017 в 17:01 (комментарий был изменён)

      0

      это скрипт на статью, механизм описанный в статье автоматизирован
  • 9 января 2017 в 17:01

    0

    Как полный ноль в скриптах хочу спросить. Я правильно понял, выделяем всё и запускаем в PS?

© Habrahabr.ru