Обёртки над текстовыми командами в PowerShell

Хотел поделиться опытом создания простой объектно-ориентированной обёртки над обыкновенной консольной утилитой для облегчения работы с ней. Для примера была выбрана pnputil для работы с хранилищем дистрибутивов драйверов в Windows.

Стандартная процедура

Меня в первую очередь данная утилита интересует как механизм удаления ненужных дистрибутивов драйверов (старые версии, более неиспользуемое оборудование и т.д.).

Итак, получение списка всех дистрибутивов:

C:\Windows\system32>pnputil -e
Microsoft PnP Utility

Published name :            oem0.inf
Driver package provider :   Microsoft
Class :                     Printers
Driver date and version :   06/21/2006 6.1.7600.16385
Signer name :               Microsoft Windows

Published name :            oem1.inf
Driver package provider :   Logitech
Class :                     Universal Serial Bus controllers
Driver date and version :   11/04/2010 1.0.2.11
Signer name :               Microsoft Windows Hardware Compatibility Publisher

Published name :            oem2.inf
Driver package provider :   Creative
Class :                     Sound, video and game controllers
Driver date and version :   07/15/2008 6.0.01.1361
Signer name :

...

Далее, нужно найти в этом списке интересующие нас пакеты и удалить их, один за другим:

C:\Windows\system32>pnputil -d oem21.inf
Microsoft PnP Utility

Driver package deleted successfully.

Не самый удобный способ, не правда ли?

Делаем обёртку

Для начала – получение списка:

function Get-Driver
{
  $driverListRaw = $(pnputil -e)
  if ($driverListRaw.Length % 6 -ne 2) {throw "Invalid output from 'pnputil -e'"}
  $driverListRaw = $driverListRaw[1..$($driverListRaw.Length-2)]
  $objectCount = $driverListRaw.Length / 6
  for ($i=0; $i -lt $objectCount; $i++)
  {
    Write-Output $(Create-CustomDriverObject $driverListRaw[$($i*6)..$($i*6+5)])
  }
}

Теперь из текста хочется получить массив объектов (или Как создать свой объект в PowerShell):

function Create-CustomDriverObject($arr)
{
  return New-Object System.Object | Select-Object -Property `
            @{Name='PublishedName'; Expression={$arr[1].Split(':')[1].Trim()}},
            @{Name='DriverPackageProvider'; Expression={$arr[2].Split(':')[1].Trim()}},
            @{Name='Class'; Expression={$arr[3].Split(':')[1].Trim()}},
            @{Name='DriverDateAndVersion'; Expression={$arr[4].Split(':')[1].Trim()}},
            @{Name='SignerName'; Expression={$arr[5].Split(':')[1].Trim()}}
}

Ну и напоследок простенькая функция, которая будет уметь удалять указанный пакет:

function Remove-Driver($driver)
{
  Write-Host $(pnputil -d $driver.PublishedName)
}

Вот и всё.

Результат

Теперь мы можем творить всякие интересные вещи:

PS C:\> Get-Driver | where { $_.DriverPackageProvider -like '*nvidia*' -and $_.Class -like '*display adapter*' } | Format-Table -AutoSize -Property PublishedName,DriverPackageProvider,DriverDateAndVersion

PublishedName DriverPackageProvider DriverDateAndVersion
------------- --------------------- --------------------
oem1.inf      NVIDIA                07/14/2009 8.15.11.9038
oem21.inf     NVIDIA                08/17/2009 8.16.11.9062
oem42.inf     NVIDIA                11/20/2009 8.17.11.9562
oem60.inf     NVIDIA                03/15/2010 8.17.11.9713
oem36.inf     NVIDIA                09/27/2009 8.16.11.9107
oem81.inf     NVIDIA                06/07/2010 8.17.12.5721
oem58.inf     NVIDIA                01/11/2010 8.17.11.9621
oem76.inf     NVIDIA                04/03/2010 8.17.11.9745

PS C:\Windows\system32> Get-Driver | where { $_.DriverPackageProvider -like '*ati tech*' -and $_.Class -like '*display
adapter*' } | Format-Table -AutoSize -Property PublishedName,DriverPackageProvider,DriverDateAndVersion

PublishedName DriverPackageProvider DriverDateAndVersion
------------- --------------------- --------------------
oem92.inf     ATI Technologies Inc. 08/03/2010 8.762.0.0000
oem75.inf     ATI Technologies Inc. 08/25/2010 8.771.0.0000
oem95.inf     ATI Technologies Inc. 09/28/2010 8.782.0.0000
oem79.inf     ATI Technologies Inc. 07/06/2010 8.753.0.0000

Например, одной строкой избавиться от всех (теперь уже ненужных) драйверов:

PS C:\Windows\system32> $driversToRemove = Get-Driver | where { $_.DriverPackageProvider -like '*nvidia*' -and $_.Class -like '*display adapter*' }
PS C:\Windows\system32> $driversToRemove | %{ Remove-Driver $_ }
Microsoft PnP Utility  Driver package deleted successfully.
Microsoft PnP Utility  Driver package deleted successfully.
Microsoft PnP Utility  Driver package deleted successfully.
Microsoft PnP Utility  Driver package deleted successfully.
Microsoft PnP Utility  Driver package deleted successfully.
Microsoft PnP Utility  Driver package deleted successfully.
Microsoft PnP Utility  Driver package deleted successfully.
Microsoft PnP Utility  Driver package deleted successfully.

Comments

2 комментария на ««Обёртки над текстовыми командами в PowerShell»»

  1. Аватар пользователя animert
    animert

    все это интересно, но то что написано в разделе делаем обертку не соответствует тому, что написано в разделе результат

  2. Каким именно образом? Всё, что здесь написано скопипастено из того кода и консоли, где всё писалось и тестировалось.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *