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

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

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

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

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

    dism /online /get-drivers

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

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

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

    для того чтобы создать контрольную точку на всякий случай выполните в консоли повершелла из под админа команду Checkpoint-Computer -Description «Driversdelete». Чтобы проверить создалась ли точка восстановления выполните командлет Get-ComputerRestorePoint
    код скрипта тут
    Содержимое спойлера
    
    <#
        2016.09.01
        перечисляет драйвера в системе
        находит дубликаты в хранилище и удаляет их
        если вам нужно только посмотреть драйвера закомментируйте 135 строку
        если драйвер нужно удалить принудительно используйте pnputil.exe -f -d
    #>
    
    #[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("cp866")
    
    #расскомментируйте если вам нужно создать точку восстановления
    #Checkpoint-Computer -Description "Driversdelete"
    
    # получаем список драйверов
    $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"
    }
    


    Спасибо за внимание!
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 74

      0
      Помню то же столкнулся с подобной проблемой. Винда сохранила драйвер для принтера, а в самом драйвере появилась ошибка. Он начал печатать пакеты один пакет одна страница. Беда в том что при простом удалении, винда восстанавливала драйвер и не давала переустановить. В итоге ползли в эту папку и удаляли с помощью рук все её драйверы. Тока потом она дала шанс установить новенький и чистенький драйвер.
      Как говорится век живи, век учись. Сохраню страничку вдруг пригодится.
        0
        Благодарю, давно искал что-то консольное, что можно запускать автоматически по расписанию.
        До этого пользовался тоже хабраразработкой — pyWinClobber
          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.
            0
            это скрипт на статью, механизм описанный в статье автоматизирован
            0
            Как полный ноль в скриптах хочу спросить. Я правильно понял, выделяем всё и запускаем в PS?
              0
              сохраните его в файл с расширением ps1 и запустите от админа.
              если скажет что сценарии в данной системе запускать нельзя то запустите его так
              powershell -executionpolicy bypass -file "путь до скрипта"
              
              –2
              Скрипт в Win10 64 не работает. Просто выдает текст:
              все драйверы
              — несколько версий драйверов
              — устаревшие версии драйверов
              — драйвера на удаление
              — будте осторожны, любые автоматические действия опасны


              От админа скрипты запустить низя, нет такой опции. Можно сказать «Yes» на предупреждение о запуске нелогичного сценария, и только один раз, потом уже не спрашивает.
                0
                В самой среде PS действительно не запускает, пишет выполнение сценариев отключено.
                Но то же самое выдает по команде powershell -executionpolicy bypass -file, просто текст без цифр, т.е. скрипт не выполняется, список драйверов он из системы не получает и далее, соответственно, не парсит.
                  0
                  У меня работает под Win10 64, пользователь — локальный админ.

                  1. Нажать на клавиатуре кнопку Windows
                  2. Печатаем ISE. Список программ сокращается до Windows PowerShell ISE
                  3. Правая кнопка мыши на оставшейся программе -> «Run as administrator»
                  4. Копипастим скрипт
                  5. Нажимаем зелёную кнопку Run


                  У меня нашло 4 дубликата.
                    +1
                    От админа скрипты запустить низя, нет такой опции.

                    У самой консоли PowerShell есть эта опция (проверил на Win7, Win10 под рукой сейчас нет).
                    Так что сперва сам PS, и потом в нём уже скрипт.
                      0

                      На самом деле это "опция" не PS, а UAC. Любая программа может быть запущена либо от админа, либо от ограниченного пользователя (кроме тех у которых в манифесте прописано что они из-под ограниченного пользователя не запускаются).

                      –2
                      Такая же ерунда (Windows 10, x64). Из Powershell ISE отработало ок.
                        –1
                        Кошмар какой. Если берётесь за PowerShell и не знаете, как запускать скрипты из-под админа, лучше не беритесь вовсе. Можно много бед наворотить.
                        Мне это напоминает историю, когда сотрудник обратился в поддержку с просьбой выполнить скрипт с админскими правами в духе «вот я тут скрипт обалденный нашёл — он всё супер круто делает, но мне прав не хватает». А инженер взял и выполнил, не проверив толком, что за скрипт. В итоге BSOD -> перезаливка. Что был за скрипт и что конкретно поломал даже уже и разбираться не стали.

                        Это я всё к тому, что если вы не знаете PowerShell — НИ В КОЕМ СЛУЧАЕ НЕ ЗАПУСКАЙТЕ СКРИПТЫ PowerShell ОТ ИМЕНИ АДМИНИСТРАТОРА! Тем более, если не знаете как.

                        На всякий случай научу — авось своих шишек набьёте:
                        Первый вариант: В открывшейся консоли пишете путь к скрипту и жмакаете ENTER.
                        Второй вариант (если первый говорит, что запуск скриптов запрещён политикой): Нажимаете сочетание клавиш Win + X, там выбираете пункт . В открывшейся консоли пишете
                        powershell -executionpolicy bypass -file "X:\тут\мой\скрипт.ps1"


                        P.S. простите за английскую винду. Привычка-с...
                          –1
                          Капитан очевидность, у вас залет. Почитайте посты ниже, вы не поняли суть проблемы.
                          Но мы уже вроде разобрались, кэп.
                            0
                            От админа скрипты запустить низя, нет такой опции.
                            Вся суть проблемы в одном предложении. Это вы не понимаете суть вашей проблемы ;)
                            Проблема в том, что процитированная фраза могла исходить только от технически неграмотного, либо совершенно не знакомого с PowerShell человека.

                            Ваш К.О.
                              –1
                              Действительно, первый раз вчера открыл PS. На Делфи ни разу не похоже, но интересно.
                              Так вот, прелесть законченного решения состоит в том, что законченный скрипт.ps1 запускается по правой клавише мыши «Выполнить в PowerShell», чистит машину и не спрашивает о безопасности, админских правах и не портит аппетит всякими «Если не это, то попробуйте вот так, но все очень индивидуально на каждой машине».
                              Для меня проблема ФрендлиЮзерИнтерфейса решается оберткой powershell -executionpolicy bypass -file скрипт.ps1 в чиститьдиск.bat
                              Но остается необходимость запускать его опять от имени администратора — это не комильфо.

                              Вот суть моей проблемы. В остальном же совершал акт дефекации на вашу парадигму относительно моей профессиональной компетенции.
                                0
                                Для меня проблема ФрендлиЮзерИнтерфейса решается оберткой powershell -executionpolicy bypass -file скрипт.ps1 в чиститьдиск.bat

                                слуш ну хитееер, додумался ведь — засунул команду вызова скрипта в батник и запустил батник от админа чтобы он запустил пошик от админа и потом сам запустил скрипт ))))
                                  –1
                                  Это не всё еще)) Проблема окончательно разрешилась созданием ярлыка для батника и в его доп.настройках установкой «запуск от админа».
                                  Вот теперь всё — простой двойной клик лкм ))))… но в дистрибутиве три файла
                                  Завтра упакую все в один экзешник.)
                                    0

                                    "В один экзешник" достаточно положить всего один файл. Сам скрипт.


                                    Параметры для powershell и сам экзешник передать сможет. И запуск от админа в его манифесте прописать можно.


                                    Кстати, если делать его на C# — то можно и вовсе обойтись без распаковки и запуска дочернего процесса.


                                    Но вы, конечно же, упаковывайте три файла. Два скрипта на разных языках и ярлык. И все это — для того чтобы запустить один раз и забыть на пять лет.

                                      +1
                                      да пусть пишет. Поближе познакомится с пошиком, тулзы погуглит, уровень знания по любому вырастет.

                                      Я в свое время тоже написал очередной psexec чтобы запускать файлы без показа окошек, из принципа хотел разобраться как это делать, ну и что, по итогу подсел на пошик, перестал сомневаться в его преимуществах перед bat и vba файлами, перестал пытаться запихать скрипты в exe и даже стал писать кой какие статейки
                                        0
                                        Да нет, пошик я посмотрел, применять мне его особо негде, хотя было забавно.
                                        Экзешник забирайте, уверен, пригодится всем, кто хотел просто почистить дрова, без приключений, политики безопасности UAC и прочих бубнов.
                                        Версия 32х разрядная, без создания контрольной точки (очень долго создает уж).
                                        Запустится у всех, у кого сам скрипт не выдавал ошибок и нет проблем с версией PS.
                                        Ну а тем, кто не дошел таки до запуска, не победили UAC, и не в силах далее внимать солнцеликим гуру — бог в помощь! Юзайте на здоровье, полезный продукт готов к употреблению)))

                                        ЗЫ если антивирь ругнется, пошлите на))
                                        ЗЫЗЫ автору скрипта респект, хотя ты и сноб))
                                  –2

                                  Видите ли в чем дело. У вас — винда со включенным UAC. На ней любые действия по администрированию компьютера требуют запуска хоть какой-нибудь программы с правами, сюрприз, админа!


                                  Если вы не умеете запускать программы из-под админа — это ваша проблема. Не скрипта.

                                    0
                                    Если вдруг возникнет желание вернуться к PowerShell и чтобы сразу «от админа» советую глянуть в сторону вот этого замечательного скрипта по преобразованию *.ps1 в *.exe.
                                    По функционалу прилично порезан (в смысле, что не все возможности PS поддерживает), но в целом очень даже рабочий инструмент.

                                    Помимо вашей проблемы позволяет также обойти и другую: запрет на запуск скриптов через GPO. Т.к. выполняется в итоге не скрипт, а его «скомпилированный» (в каком-то смысле) вариант.

                                    Правда, есть и минус: иногда при использовании некоторых «приёмов» PS на готовый exe срабатывает эвристика антивирусов (того же каспера, в моём случае).
                                      –1
                                      Полагаю, последний минус решается какой-нибудь упаковкой со смещением. На 99.99% полученный exe не будет содержать явно выраженных типовых jmp-пов для эврестического анализа, а вот явное выполнение сценария уже будет скрыто.
                            0
                            Но то же самое выдает по команде powershell -executionpolicy bypass -file, просто текст без цифр

                            Попробуйте запустить cmd от имени администратора. У меня win10 x64 — все чудесно работает.
                            Вставил такую строку в скрипт (чтобы показать свою ОС и разрядность):

                            Write-Host (Get-WmiObject -Class Win32_OperatingSystem).Caption (Get-WmiObject -Class Win32_OperatingSystem).OSArchitecture


                            Вот результат:

                            PS C:\WINDOWS\system32> D:\PowerShell\RemoveDr.ps1
                            Майкрософт Windows 10 Pro (Registered Trademark) 64-разрядная
                            все драйверы
                            -------------------

                            FileName Vendor Date Name ClassName Version Vhod
                            -------- ------ ---- ---- --------- ------- ----
                            bcmwlhigh6.inf ASUS 2013.02.28 oem27.inf Net 6.30.145.30 ЌҐв
                            bcmwlhigh63.inf NETGEAR,Inc. 2013.04.03 oem44.inf Net 6.30.145.30 ЌҐв
                            benq gw2260.inf BenQ 2012.08.15 oem40.inf Monitor 2.0.0.0 ЌҐв


                            … ну и т.д.
                              –3
                              и для Light_Metal, нет, друзья…
                              не влияет никак запуск PowerShell от имени администратора, выдает тоже самое о невозможности запускать сценарии, хотя я админ и других админов нет:

                              PS C:\WINDOWS\system32> C:\2OldDrvClear.ps1
                              Невозможно загрузить файл C:\2OldDrvClear.ps1, так как выполнение сценариев отключено в этой системе. Для получения дополнит
                              ельных сведений см. about_Execution_Policies по адресу http://go.microsoft.com/fwlink/?LinkID=135170.
                                  + CategoryInfo          : Ошибка безопасности: (:) [], ParentContainsErrorRecordException
                                  + FullyQualifiedErrorId : UnauthorizedAccess
                              
                              PS C:\WINDOWS\system32> 
                              
                                +1
                                В описании ошибки дан ответ — «так как выполнение сценариев отключено в этой системе.» Можно сходить по ссылке, приведенной в ошибке и почитать про политики выполнения скриптов Powershell — очень толково все расписано. Если коротко, то PoSh мало того, что Вы администратор — ему еще надо четко указать, что Вы разрешаете делать со скриптами и в каком контексте.

                                Удачи!
                                0
                                Запустилось только из под CMD запущенного от имени администратора. Нашел 8 дубликатов.
                                Почему из под админского PowerShell сценарий не выполняется, не понимаю…
                                  +1
                                  запустите powershell ISE, откройте в ней и запустите из нее нажав F5
                                  из консоли не запускает скорее всего из за безопасности — чтобы избежать запуска вирусных скриптов posh имеет защиту в виде политики посмотреть ее можно выполнив команду get-executionpolicy если вернет Restricted то значит выполнение скриптов запрещено. чтобы разрешить выполнение скриптов нужно выполнить команду set-executionpolicy unrestricted

                                  блин, кажется нужно по модели безопасности пошика статью написать…
                                  кароче это сделано чтобы не было штук как в VBA когда можно запустить что угодно, или подменить широко применяемый exe файл, например мы имеет доступ в папку где лежит word.exe мы берем пишем VBA файл и ложим тудаже, и из него после отработки запускаем word.exe который перед этим переименовали в word1.exe и таким образом мы можем атаковать админа когда он запустит ворд если мы на терминальном сервере, не говоря о том что можно играть на порядке поиска файлов, и на изменении тела самих скриптов. Таким образом система безопасности должна не давать по умолчанию запускать что попало. если вы попробуете на свежеустановленной системе открыть ps1 файл у вас откроется вообще блокнот, ну и т.д. есть хорошая статья на 2 страницы по безопасности, наверное пришло время ее перевести
                                    0

                                    Почему скрипт нельзя запустить двойным кликом по нему — совершенно понятно.


                                    Но каким боком к защите от случайного запуска относится запрет ввода в консоли powershell -file ...?

                                      0
                                      дополните указанием полтики исполнения и заработает
                                0
                                скрипт только на 10-ке работать должен? на 7-ке кучу ошибок красным цветом выводит…
                                  0
                                  должен работать, напишите в личку что показывает
                                  0
                                  DISM /online /get-drivers
                                  =========
                                  Obtaining list of 3rd party drivers from the driver store…

                                  Driver packages listing:

                                  (No drivers found in the image matching the criteria)
                                  =========

                                  7x64 ultimate, если запустить с /all в нагрузку, находит с десяток драйверов непойми откуда и всё. или у меня какой-то сервис пришиблен за ненадобностью, или не все винды одинаково полезны…
                                    0
                                    не получилось воспроизвести такую же ошибку, у меня есть тестовая машина win7 x64 на ней работает

                                    какая версия dism`а?
                                      0
                                      Deployment Image Servicing and Management tool
                                      Version: 6.1.7600.16385
                                    0
                                    Через Windows PowerShell ISE сработало.
                                    Спасибо!
                                      0
                                      Какую команду нужно использовать, что бы не удалять, а перемещать в нужный каталог?
                                        0
                                        боюсь что это совсем другая задача — перемещать нужно не только inf файл, а все файлы на которые указывает inf файл, а их может быть очень много.

                                        можно предварительно скопировать содержимое папки C:\windows\system32\DriverStore\FileRepository куданибудь, и после этого играть со скриптом

                                        в данном случае целью ставилось посмотреть какие версии драйверов хранятся в системе и автоматизировать процедуру удаления старых. т.к. при нажимании 122 раза вверх — поменять цифры — ввод можно допустить ошибку

                                        может быть можно скопировать папку в которой лежит inf файл со своим барахлишком и после этого делать деинсталяцию, это я не проверял
                                        0
                                        for /l %%i in (0,1,256) do pnputil -d oem%%i.inf
                                        просто удаление ненужных сторонних драйверов
                                          0
                                          а рабочие драйвера при таком способе он просто не удалит?
                                            0
                                            Не удалит. pnputil выдаст вот это на используемые драйвера (на Win7):
                                            Не удалось удалить пакет драйвера: С помощью указанного INF-файла сейчас было установлено одно или несколько устройств.
                                          0
                                          Падает на Win7x64sp1, многочисленные одинаковые ошибки, в цикле:
                                          Посмотреть
                                          Невозможно найти тип [ordered]: убедитесь в том, что сборка, содержащая этот тип, загружена.
                                          C:\TEMP\deldrivers.ps1:61 знак:44
                                          +                         $params = [ordered] <<<< @{ 'FileName' = $FileName
                                              + CategoryInfo          : InvalidOperation: (ordered:String) [], RuntimeException
                                          New-Object : Не удается проверить аргумент для параметра "Property". Аргумент пустой или имеет значение NULL. Укажите не пустой аргумент, не имеющий значение NULL, после чего повторите выполнение команды.
                                          C:\TEMP\deldrivers.ps1:70 знак:71
                                          +                         $obj = New-Object -TypeName PSObject -Property <<<<  $params
                                              + CategoryInfo          : InvalidData: (:) [New-Object], ParameterBindingValidationException
                                              + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.NewObjectCommand
                                          



                                          Дальнейший вывод такой:
                                          Посмотреть
                                          все драйверы
                                          -------------------
                                          несколько версий драйверов
                                          -------------------
                                          устаревшие версии драйверов
                                          -------------------
                                          найден дубликат
                                          драйвера на удаление
                                          -------------------
                                          будте осторожны, любые автоматические действия опасны
                                          Нельзя вызвать метод для выражения со значением NULL.
                                          C:\TEMP\deldrivers.ps1:128 знак:31
                                          +     $Name = $($item.Name).Trim <<<< ()
                                              + CategoryInfo          : InvalidOperation: (Trim:String) [], R
                                              + FullyQualifiedErrorId : InvokeMethodOnNull
                                          
                                          
                                          удаляем п
                                          Служебная программа PnP Майкрософт
                                          
                                          Не удалось удалить пакет драйвера:Не удается найти указанный файл.
                                          

                                            0
                                            ошибка из за того что у вас пошик старый, скорее всего 2й

                                            удалите [ordered] должно быть так и заработает
                                                                    $params = @{ 'FileName' = $FileName
                                                                                          'Vendor' = $Vendor
                                                                                          'Date' = $Date
                                                                                          'Name' = $Name
                                                                                          'ClassName' = $ClassName
                                                                                          'Version' = $Version
                                                                                          'Vhod' = $Vhod
                                                                                        }
                                            


                                            покажите если не сложно версию пошика сделать для этого введите в порвешелле $psversiontable

                                            если захотите обновить пошик то скачайте WMF5.1 или хотя бы WMF4
                                              0
                                              и удалите trim должно быть вот так
                                                      'ItIsName' { $Name = $text
                                                                   $Operation = 'ItIsFileName'
                                                                   break
                                                                 }
                                              

                                              это особенность старого пошика, в нем не хватает некоторых конструкций, в данном случае для работы скрипта они не существенны
                                                0
                                                Да, вторая версия
                                                Name Value
                                                — — CLRVersion 2.0.50727.5420
                                                BuildVersion 6.1.7601.17514
                                                PSVersion 2.0
                                                WSManStackVersion 2.0
                                                PSCompatibleVersions {1.0, 2.0}
                                                SerializationVersion 1.1.0.1
                                                PSRemotingProtocolVersion 2.1

                                                Спасибо, после удаления [ordered] скрипт отработал. Trim я не удалял, кстати.

                                                Скачал WMF5.1 (Win7AndW2K8R2-KB3156424-x64.msu) — Обновление неприменимо к этому компьютеру. DotNet 4.6.1 присутствует, если что. Возможно, требуется ещё что-то, о чём явно не сказано.
                                                А вот WMF4 (Windows6.1-KB2819745-x64-MultiPkg.msu) установился, и скрипт отработал в исходном виде с [ordered].

                                                Вот отчасти из-за таких ситуаций я недоверяю ps, несмотря на его очевидную прогрессивность. Неизвестно, что может удалитьсяупасть из-за несоответствия версии.
                                                  +1
                                                  плюсы перевешивают минусы на самом деле.
                                                  это мой недочет что я не прогнал скрипт на 7ке, хотя когда писал я знал что ордеред был введен начиная с 3го пошика.
                                                  но я написал его так чтобы это не повлияло на его работу (не убило ничего) а вставил эти конструкции из за привычки писать код таким стилем.

                                                  кстати код VBA куда более опасен, хотя если сделать делит папки windows ничего конечно не спасет
                                                    +2

                                                    Напишите в начале скрипта


                                                    #requires -version 3.0

                                                    и будьте спокойны, он просто не запустится на младших версиях

                                                    0
                                                    ЕМНИП, WMF5.1 ставится только поверх 3-ей или 4й версии.
                                                    В принципе, в скрипте нет ничего особенного. 3й версии уже с головой хватит.
                                                      0
                                                      Я уже пробовал. Даже WMF 5.0 установилась поверх 4-й, установил SHA-2 Security Update, что было в требованиях, но нет, 5.1 Preview не хочет устанавливаться.
                                                        0
                                                        Почитайте: https://msdn.microsoft.com/en-us/powershell/wmf/5.1/install-configure
                                                        Там немножко подробнее о том, что нужно поставить. Прям со ссылками.

                                                        У меня на 10ку встало без проблем (что неудивительно тащемто).

                                                        Неизвестно, что может удалитьсяупасть из-за несоответствия версии.
                                                        Кстати, практически ничего. В 99% случаев скрипт просто споткнётся на неподдерживаемом методе.
                                                        А вообще да — это немного раздражает. Приходится постоянно писать скрипты на PS5, а потом их отлаживать и заставлять работать на PS2.
                                                          0
                                                          эт из за исторического развития пошика так произошло, когда балмер принял решение что главное это девелоперы начали резко пилить пошик, это видно прям по версиям, фактически первым полноценным стал powershell 3 но в 7 винду успели зарелизить только версию 2. мне приходится при установке 2008 или 7ки всегда делать установку WMF4 чтобы получить SkipLast, создание объектов без добавление методов и командлеты, и то при установке на 2008R2 нет оснасток например из модуля storage и модулей работы с AD что сильно ограничивает функционал, нужно юзать WMI
                                                          в первом пошике вообще 128 командлетов всего, в 5.1 более 1500, но весь функционал вы получите только сделав ап самой винды
                                                          по мне так 5.0 и 5.1 самые нормальные версии из за функций по работе с сервисами, этого действительно не хватает, нормальная поддержка PSEdit — редактирование на удаленных машинах, в 5.1 встроен psreadline ну и т.д.
                                                          Минимальной является WMF4 в нем уже все есть особенно биндинг и нормальный дебаг (можно нормально парсить ошибки, не до конца перебирает списки объектов что ускоряет работу в разы), работа с сетью

                                                          встречал баг только на терминальном сервере когда после установки WMF4 перестал работать мап принтеров либо глючил с чем связано не знаю
                                                          в exchange приходится тестить с пристрастием скрипты сильно от версии различаются, но это ерунда, по сравнению с той мощью которую можно достигнуть за счет автоматики
                                                            0
                                                            Если вы заметили, я эту же ссылку и приводил, и да, я конечно читал про требования. Все компоненты (EMF4, SHA2 Update, .NET 4.6.1, WinRM Dependency — WinRM был запущен) есть, а результата нет.
                                                              0
                                                              у меня тоже есть такой баг на одной машине в инфраструктуре, win 8.1 пош 5 поставился а 5.1 нет. глубоко не копал но подтверждаю, баг такой имеется
                                                                0
                                                                Добавлю ещё: пришёл домой и установил на домашний комп сразу 5.1 поверх 2.0 (sha2+dot net уже были). Получается, то, что в ссылке, ещё и не совсем верно.
                                                                0
                                                                Не заметил, простите.
                                                    0
                                                    Полезный скрипт, прямо вчера о нём думал, собирался писать. Спасибо!

                                                    Есть нюансы: например, 1С версии 7.7 на Win 7 x32 с локальным ключом безопасности работает, только если в системе присутствует старый драйвер HASP из комплекта поставки самой 1С 7.7. При этом основным (отображаемым в диспетчере устройств как установленный для устройства) может быть и другой драйвер HASP.
                                                    Подозреваю, что нюанс не единичный. Так что имеет смысл добавить в начало скрипта создание точки восстановления.
                                                      0
                                                      дополнил сценарий одной закомментированной строкой создания контрольной точки

                                                      # чтобы создать контрольную точку
                                                      Checkpoint-Computer -Description "Driversdelete"
                                                      # чтобы просмотреть контрольные точки
                                                      Get-ComputerRestorePoint 
                                                      
                                                      0
                                                      Уберите, пожалуйста, код скрипта в спойлер.
                                                      И вопрос на засыпку: почему такой странный парсер со свитчами..? Почему выбран именно такой вариант?
                                                        0
                                                        убрал в спойлер

                                                        прост стиль мой такой
                                                        • во первых в нем описан точный порядок переключений,
                                                        • во вторых его можно дополнить
                                                        • в третьих можно дописать default и тогда автомат не сможет принять никаких состояний кроме описанных, т.е. мы получим точный автомат, не дописал только из за того что тогда надо дописывать проверку на содержимое и потому что и так получилось очень robust даже с ошибками отрабатывает нормально
                                                        • Четвертой причиной является то что в разных системах может быть написано на русском а может на английском, или еще каком языке. Поэтому парсить по сравнению содержимого до двоеточия опасно
                                                        • Пятое — потому что в автомате реализуемом через switch я могу дополнять в последующем действия не загромождая код и без страха сломать нижестоящий код, хоть конструкция и пространсвенно большая, она очень понятная и детерминируемая штоли,
                                                        • Шестое — если я буду рефакторить то я скопирую конструкцию и выкину только входные строки каждого блока, при этом сохранив логику внутри такого блока, этот автомат мал чтобы это увидеть, но логика такова, именно поэтому я использую присвоение переменной вначале и потом работу с этой переменной внутри каждого блока

                                                        например: как можно было заметить вывод даты утилитой DISM происходит в последовательности DD.MM.YYYY а мне нужно отсортировать по дате драйвера и выбрать самый новый, я мог бы парсить строку в дату и потом делать сравнение, вместо этого я при парсинге переворачиваю строку в европейский формат — YYYY.MM.DD и тогда при строковой сортировке у меня будет правильный порядок дат. Так вот парсинг этот я дописывал после создания блока, и труда это не составило и если бы мне понадобилось обрабатывать имена файлов то я бы это делал внутри подблока конструкции switch, плюс я могу быстро дополнить состояния автомата если нужно, а если нужно то просто перенаправить алгоритм по другому пути просто заменой состояние на которое будет переключаться в следующей итерации (это нужно если ваш автомат отрабатывает у многих пользователей через время, и чтобы ничего не сломать, приходится делать такие переключения в другие промежуточные состояния).

                                                        Есть еще скрытый смысл — при компиляции подобных конструкций в ассемблере получается очень короткий переход — сравнение по таблице и прыжок, а при других конструкциях код запутаннее и больше. Наверное это привычка оттуда…

                                                        Сорри, многабукф
                                                        +1
                                                        парсить по сравнению содержимого до двоеточия опасно
                                                        в разных системах может быть написано на русском а может на английском, или еще каком языке
                                                        Можно добавить к команде /format:table и парсить таблицу, в качестве Headers используем заголовок получившейся таблицы, который можно предварительно распарсить по разделителю.

                                                        вывод даты утилитой DISM происходит в последовательности DD.MM.YYYY а мне нужно отсортировать по дате драйвера
                                                        Вы не поверите, но PoSH объектно-ориентирован. Конвертируем богомерзкий объект класса «String» в православный объект класса «DateTime» через [DateTime]::Parse($Date). И этот объект уже будет сортироваться как надо — PoSH знает, как правильно сортировать дату.

                                                        Впрочем, ваша фраза про ассемблер всё объясняет… :) Я к программированию пришёл недавно и пошло оно уже после увлечения PoSH (его стало не хватать), так что у меня мозг слишком сильно испорчен ООП. На низкоуровневые языки смотреть не могу Т__Т

                                                        Попробовал сваять свой парсер без привязки к локали.
                                                        Получилось нечто такое:
                                                        # Получаем данные от Dism
                                                        $data = & dism /online /get-drivers /format:table | select -Skip 12 # Первые 12 строк - стандартный мусор
                                                        
                                                        # Получаем заголовок таблицы и разбиваем на составные
                                                        $Headers = @( ($data | select -First 1).ToString().Split('|') | %{$_.Trim() <# обрезаем лишние пробелы #>} )
                                                        
                                                        # оформляем в хэш-таблицу
                                                        $HashTable = $data | select -Skip 2 | 
                                                            ConvertFrom-Csv -Delimiter '|' -Header $Headers | 
                                                                select @{n='FileName';e={$_."$($Headers[1])"}},
                                                                       @{n='Class';e={$_."$($Headers[3])"}},
                                                                       @{n='Vendor';e={$_."$($Headers[4])"}},
                                                                       @{n='Date';e={[datetime]::Parse($_."$($Headers[5])")}},
                                                                       @{n='Version';e={$_."$($Headers[6])"}}
                                                        


                                                        На выходе в переменной $HashTable у вас есть, собственно, HashTable, с которым дальше можно делать всё, что захотите. Причём, уже с правильным Date, который будет правильно сортироваться. Можно из него сделать PSObject через Foreach, можно оставить как есть — тут уже по вкусу.
                                                        Не самое интиутивно простое и элегантное решение, зато уже почти совсем «PowerShell-way» ;)

                                                        P.S. пишу с 10-ки. Если у вас PoSH 5.0 — должно всё завестись. Адаптировать под PoSH 2.0 тоже несложно, если сильно надо.
                                                          0
                                                          ваш способ православнее и в русле идеологии пошика

                                                          скорее всего на меня влияет «материнский язык»

                                                          P/S/ кстати последний объект выпал как пустой, из за двух пустых строк в конце. автомат такое бы не пропустил. нужна одна проверка или принудительно удалить последний объект
                                                            0
                                                            Упс, промахнулся мимо ответа, получилась новая ветка...

                                                            ваш способ православнее и в русле идеологии пошика
                                                            И, надеюсь, нагляднее. Ваш парсер нужно вдумчиво разбирать, чтобы понять, что происходит. Ну мне пришлось, по крайней мере %)

                                                            кстати последний объект выпал как пустой, из за двух пустых строк в конце. автомат такое бы не пропустил. нужна одна проверка или принудительно удалить последний объект
                                                            И правда. Упустил этот момент. Всё из-за последних строк в конце вывода:
                                                            
                                                            The operation completed successfully.
                                                            
                                                            
                                                            (это 3 строки, 2 пустые)
                                                            Ну, никто не мешает, действительно, проверять на IsNullOrEmpty.
                                                            0

                                                            Делать PSObject в таких случаях — обязательно. Потому что Hashtable — это последовательность, а последовательность последовательностей в PoSh выводится ужасно. Работать с ней еще можно, а вот в отладке разобраться что там да как — уже тяжело :)

                                                              0
                                                              Ну это уже вкусовщина. Сам я тоже предпочитаю PSObject, да. Он крайне удобен как для работы с ним, так и для последующей выгрузки в CSV/XLSX.

                                                              Кстати, тов. pak-nikolai (чтоб 2 коммента не писать), можно ещё и версию распарсить на объект класса Version и сортировать дрова даже хоть по версии.
                                                            0
                                                            Для драйверов есть DISM.
                                                            А есть что-то для установленных обновлений, точнее той свалки, что скапливается в %systemroot%\Installer?
                                                              0
                                                              С некоторыми устаревшими хвостами обновлений может помочь cleanmgr.
                                                                0
                                                                С помощью Dism++ можно почистить \Installer\$PatchCache$\ (и вообще, много чего почистить: устаревшие и замененные компоненты WinSxS, устаревшие драйверы).
                                                                  0
                                                                  уххх. 5.5Г на одной машинке и 20 (видимо от неудавшейся попытки апгрейда до 10) на другой, обе с семеркой… интересно где эта утилита была раньше…
                                                                0
                                                                спасибо, сработало.
                                                                win7 x64 prof. была проблема с ordered — решилось обновлением PS
                                                                  0
                                                                  ordered можно выкинуть вообще, это команда чтобы не перемешивались свойства при создании объекта а создавались именно в этой последовательности. она в принципе на работу никак не влияет

                                                                  удалил ordered из скрипта чтобы не смущать людей
                                                                  –1
                                                                  Бояре, скрипт скомпилирован в exe, брать здесь, архив 7z.
                                                                  Версия 32х разрядная, без создания контрольной точки (очень долго создает уж).
                                                                  Запустится у всех, у кого сам скрипт не выдавал ошибок и нет проблем с версией PS. Запустится сам от админа, без бубнов.
                                                                  Юзайте на здоровье, полезный продукт готов к употреблению, автору скрипта респект)))

                                                                  ЗЫ если антивирь ругнется, пошлите на))
                                                                    +2
                                                                      0
                                                                      GUI для pnputil когда надо убить старый драйвер NVIDIA засевший в системе. Спасибо что поделились

                                                                    Only users with full accounts can post comments. Log in, please.