...

четверг, 6 ноября 2014 г.

[Из песочницы] Автоматическое подключение сетевых МФУ с возможностью сканирования [Часть 1]



Я думаю, многим системным администраторам известны описанные в заголовке мфу, отличаются они, в первую очередь, не очень удобной установкой и от этого имеют дурную славу. Однажды, копируя на очередной компьютер сквозь узкий канал пакет fullsolution для мфу весом около 300 мегабайт, идея разобрать этот инсталлятор и автоматизировать установку вылезла попапом на глаза — работу пришлось приостановить.

Разбором драйвера я занимался уже около полутора лет назад, в то время интернет на эту тему был совершенно пуст. Сейчас быстро погуглил по теперь уже известным мне ключевым словам утилит и нашел немного разрозненной информации. Несмотря на это, я решил. что собранная в одно место информация все равно не помешает, при том, что в этом посте она более полная.



Настроим печать




Первым на запрос по snmp показался мфу HP LaserJet 1536, с него и решил начать. Для начала нужно понять. как его подключать как принтер под Windows 7; пожилую XP отбросил сразу, свежую Windows 8 в домене, есть мнение, мне не увидеть никогда. Вот и повод познакомиться с новым для себя PowerShell, подумал я, который в итоге был чуть ли не основной мотивацией в разборе драйвера. Подключение ip-принтера в Windows 7 состоит из трех этапов (в Windows 8 всё сильно упрощается встроенными командлетами, но про нее я уже говорил — не судьба), сначала создаем ip-порт, потом добавляем драйвер и подключаем, собственно, принтер. Для всех этих этапов в Windows есть уже готовые VBS скрипты, многим, я думаю, знакомые, в Windows 7 путь к ним: С:\Windows\System32\Printing_Admin_Scripts\

Начну с создания порта, этот этап самый простой, имя присвоим такое же как ip:

cscript C:\Windows\System32\Printing_Admin_Scripts\ru-RU\prnport.vbs -a -r "192.168.0.30" -h "192.168.0.30" -o RAW -n 9100


Добавление драйвера:

cscript C:\Windows\System32\Printing_Admin_Scripts\ru-RU\prndrvr.vbs -a -m "HP LaserJet M1530 MFP Series PCL 6" -e "Windows NT x86" -h "C:\drivers\1536\"-i "C:\drivers\1536\hpc1530c.inf"



Тут стоит отметить одну важную особенность: имя принтера должно указываться точно так же как оно прописано в inf файле драйвера, ради примера уберите часть имени, скрипт выдаст ошибку: «Не удалось добавить драйвер принтера HP LaserJet Код ошибки Win32 87».


Отрывок файла драйвера с полным именем принтера:



Теперь осталось подключить принтер, для этого я остановился на замечательной программе printui, советую посмотреть на нее поближе, у нее есть интересные ключи.

&rundll32 printui.dll,PrintUIEntry /if /b "HP LaserJet M1530 MFP Series PCL 6" /r "192.168.0.30" /m "HP LaserJet M1530 MFP Series PCL 6" /u /K /q /Gw


Пришло время оформить все это в примерно следующего вида скрипт на PowerShell:



function Add-PrinterPort ($printersource) {
cscript C:\Windows\System32\Printing_Admin_Scripts\ru-RU\prnport.vbs `
-a -r $printersource -h $printersource -o RAW -n 9100 | Out-Null
}

function Add-PrinterDriver ($printername, $driverpath) {
$folder = Split-Path $driverPath
cscript C:\Windows\System32\Printing_Admin_Scripts\ru-RU\prndrvr.vbs `
-a -m $printername -e Get-Platform -h $folder -i $driverpath
}

function Get-Platform {
if ([System.Environment]::Is64BitOperatingSystem) {
"Windows x64"
} else {
"Windows NT x86"
}
}

Add-Type -As Microsoft.VisualBasic
$printerSource = [Microsoft.VisualBasic.Interaction]::InputBox("Укажите IP адрес принтера.")

if ($printerSource -match "^192\.168\.0\.[0-9]{1,3}$") {
$printername = "HP LaserJet M1530 MFP Series PCL 6"
$driverpath = "C:\drivers\1536\hpc1530c.inf"

Add-PrinterPort $printersource
Add-PrinterDriver $printername $driverpath

# знак & перед командой переключит режим и паремтры не сломаются
&rundll32 printui.dll,PrintUIEntry /if /b $printername /r $printersource /m $printername /u /K /q /Gw
Start-Sleep -Seconds 10
}



Сканирование




Копаясь в inf файлах драйвера, для поиска правильного имени принтера и попутно вообще разбираясь в структуре драйвера HP, глаз зацепился за следующие строки (выделил жирным):

;Windows Vista

[HP.NT.6.0]

«HP LJ M1530 MFP Series Scan»= WIA_1530_Inst.NT.6.0, USB\vid_03f0&pid_012a&mi_00

«HP LJ M1530 MFP Series Scan»= WIA_1530_NW.NT.6.0,vid_03f0&pid_012a&IP_SCAN


;Windows Vista 64

[HP.NTAMD64.6.0]

«HP LJ M1530 MFP Series Scan»= WIA_1530_Inst_Vista64, USB\vid_03f0&pid_012a&mi_00

«HP LJ M1530 MFP Series Scan»= WIA_1530_NW_Vista64,vid_03f0&pid_012a&IP_SCAN



Настройки сканера в реестре хранятся по следующим путям:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{6BDD1FC6-810F-11D0-BEC7-08002BE2092F}

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root\IMAGE


Опытным путём определяем необходимые нам ключи реестра:




Тут бы хотелось лирики (казалось бы, при чем тут 1С? если вы понимаете о чём я), но опущусь до сухой констатации: попробуем devcon.exe.



DevCon — это программа с интерфейсом командной строки, которая используется в качестве альтернативы диспетчеру устройств С ее помощью можно включать, выключать, перезапускать, обновлять, удалять и опрашивать отдельные устройства или группы устройств. Программа DevCon также предоставляет необходимые разработчику драйвера сведения, которые недоступны с помощью диспетчера устройств.


http://ift.tt/1u36xdj





Добавляем устройство по ID указав драйвер:

.\devcon.exe /r install C:\drivers\1536scan\hppasc16.inf "vid_03f0&pid_012a&IP_SCAN"


Добавляем в реестр необходимые параметры, запускаем сканирование и… Бинго!

Сканер отлично работает, осталось все это оформить.


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



Windows Registry Editor Version 5.00


[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{6BDD1FC6-810F-11D0-BEC7-08002BE2092F}\_ITEM_\DeviceData]

«NetworkDeviceID»="\\hostname:_NETWORK_NAME_.domain.local\\ipaddr:_IP_ADDRESS_\\guid:\\macaddr:_MAC_ADDRESS_\\port:1"

«PortID»="_IP_ADDRESS_"

«NetworkHostName»="_NETWORK_NAME_.domain.local"

«TulipIOType»=dword:00000005


[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root\IMAGE\_ITEM_\Device Parameters]

«NetworkDeviceID»="\\hostname:_NETWORK_NAME_.domain.local\\ipaddr:_IP_ADDRESS_\\guid:\\macaddr:_MAC_ADDRESS_\\port:1"

«PortID»="_IP_ADDRESS_"

«NetworkHostName»="_NETWORK_NAME_.domain.local"

«MAC»="_MAC_ADDRESS_"

«PortNumber»=«1»

«Index»="_ITEM_"



Готовый скрипт установки сканера примет следующий вид:



$IP_ADDRESS = "192.168.0.30"
$MAC_ADDRESS = "001b00b2cc00"
$NETWORK_NAME = "NPI3CPOF7"

$source = "C:\drivers\1536scan"
$dest = Join-Path (Get-Location).path "\temporary"

Copy-Item $source $dest -Recurse -Force
$dest = Join-Path $dest "\hppasc16.inf"

# devcon лежит в одной директории со скриптом
& .\devcon.exe /r install $dest "vid_03f0&pid_012a&IP_SCAN"

$item = Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Control\Class\"{6BDD1FC6-810F-11D0-BEC7-08002BE2092F}" |
Select-Object -Last 1
$item = $item.Substring($item.Length-4, 4)

$pattern = ".\temporary\1536.reg"
$result = ".\temporary\res.reg"
Get-Content $pattern | ForEach-Object {
$_ -replace "_IP_ADDRESS_", $IP_ADDRESS `
-replace "_MAC_ADDRESS_", $MAC_ADDRESS `
-replace "_NETWORK_NAME_", $NETWORK_NAME `
-replace "_ITEM_", $item
} | Set-Content $result

& regedit /s .\temporary\res.reg


Потираем руки, проверяем — работает, модифицируем под 1522 — работает, победно правим под 3055 — облом…

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



Серьезный разговор с 3055 или, Чувак ты поднял на гору не тот камень



Вот он, LaserJet 3055/3052 — самый вредный парень, на удивление вижу я его чаще всех. На самом деле — скажу по секрету — я начал заниматься им первым — пошел через дебри фильтрации вывода procmon при установке драйвера для поиска чего-нибудь интересного и утонул где-то посередине. Когда очередной раз procmon упал из-за нехватки памяти, я решил отложить эту затею до более дружелюбного и спокойного состояния.


Второй набег на разбор установщика МФУ дал результат: спустя часа полтора разбора логов в недрах вывода установщика была найдена жемчужина — hppniscan01.exe

Запуск с необходимыми параметрами моментально установил сканер в устройства и прописал необходимые ветки реестра:

hppniscan01.exe -f "hppasc16.inf" -m "vid_03f0&pid_012a&IP_SCAN" -a "192.168.0.30" -n 1



В дистрибутивах драйверов других принтеров HP есть ее шестидесяти четырех разрядная версия, драйвер 3055 же поддерживает только x86 операционные системы.


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



C:\Drivers\Scanners\ip\3055scan\hpgtpusd.dll

C:\Drivers\Scanners\ip\3055scan\hppasc01.cat

C:\Drivers\Scanners\ip\3055scan\hppasc01.dll

C:\Drivers\Scanners\ip\3055scan\hppasc01.inf

C:\Drivers\Scanners\ip\3055scan\hppniscan01.exe

C:\Drivers\Scanners\ip\3055scan\hpptpml3.dll

C:\Drivers\Scanners\ip\3055scan\hpxp3390.dll

C:\Drivers\Scanners\ip\3055scan\Drivers\dot4

C:\Drivers\Scanners\ip\3055scan\Drivers\dot4\Win2000\hpzidr12.dll

C:\Drivers\Scanners\ip\3055scan\Drivers\dot4\Win2000\hpzipm12.dll

C:\Drivers\Scanners\ip\3055scan\Drivers\dot4\Win2000\hpzipr12.dll

C:\Drivers\Scanners\ip\3055scan\Drivers\dot4\Win2000\hpzipr12.sys



Функция установки сканера теперь стала совсем простой, хоть и с зависимостью от внешней компоненты.

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



function Add-PrinterPort ($printerSource) {
cscript C:\Windows\System32\Printing_Admin_Scripts\ru-RU\prnport.vbs `
-a -r $printerSource -h $printerSource -o RAW -n 9100 | Out-Null
}

function Add-PrinterDriver ($printerName, $driverPath) {
$folder = Split-Path $driverPath
cscript C:\Windows\System32\Printing_Admin_Scripts\ru-RU\prndrvr.vbs `
-a -m $printerName -e Get-Platform -h $folder -i $driverPath
}

function Get-Platform {
if ([System.Environment]::Is64BitOperatingSystem) {
"Windows x64"
} else {
"Windows NT x86"
}
}

function Add-Scanner ($ipaddress, $printername) {
switch -regex ($printername) {
# добавить других мфу по вкусу
"1530" {
Push-Location 'C:\Drivers\Scanners\ip\1536scan\'
if ($(Get-Platform) -eq "Windows x64") {
.\hppniscan64.exe -f "hppasc16.inf" -m "vid_03f0&pid_012a&IP_SCAN" -a $ipaddress -n 1
} else {
.\hppniscan01.exe -f "hppasc16.inf" -m "vid_03f0&pid_012a&IP_SCAN" -a $ipaddress -n 1
}
Pop-Location
}
"(305\d)|(3390)" {
Push-Location 'C:\Drivers\Scanners\ip\3055scan\'
switch -regex ($printername) {
"3050" {
.\hppniscan01.exe -f "hppasc01.inf" -m "vid_03f0&pid_3217&IP_SCAN" -a $ipaddress -n 1
}
"3052" {
.\hppniscan01.exe -f "hppasc01.inf" -m "vid_03f0&pid_3317&IP_SCAN" -a $ipaddress -n 1
}
"3055" {
.\hppniscan01.exe -f "hppasc01.inf" -m "vid_03f0&pid_3417&IP_SCAN" -a $ipaddress -n 1
}
"3390" {
.\hppniscan01.exe -f "hppasc01.inf" -m "vid_03f0&pid_3517&IP_SCAN" -a $ipaddress -n 1
}
}
Pop-Location
}
}
}

Add-Type -As Microsoft.VisualBasic
$printerSource = [Microsoft.VisualBasic.Interaction]::InputBox("Укажите IP адрес принтера.")

if ($printersource -match "^192\.168\.0\.[0-9]{1,3}$") {
$printername = "HP LaserJet M1530 MFP Series PCL 6"
$driverpath = "C:\drivers\1536\hpc1530c.inf"

Add-PrinterPort $printersource
Add-PrinterDriver $printername $driverPath
# знак & перед коммандой переключит режим и паремтры не сломаются
&rundll32 printui.dll,PrintUIEntry /if /b $printername /r $printersource /m $printername /u /K /q /Gw
Start-Sleep -Seconds 10

Add-Scanner $printersource $printername
}


Этот же способ отлично подходит для всех оказавшихся вокруг меня МФУ от HP, для которых я создал отдельные папки с драйверами и варианты выбора в свитче функции установки сканера.


Список файлов драйвера можно посмотреть в разделах inf-файла с именами [SourceDisksFiles], [RegisterDlls], [WIA_CopyFiles] и далее по файлу. Скриншот по драйверам 3055 и 1536, для наглядности:



Из описанных в этой заметке отрывков кода можно собрать полноценный скрипт автоматической установки МФУ, а если добавить в него немного гуя и snmp, то можно вообще навсегда закрыть для себя тему установки МФУ на новые машины.


На этом на сегодня всё, спасибо за внимание. Если в комментариях подскажут чего не хватает МФУ 3055 для работы при установке первым способом посредством devcon, буду сильно благодарен. Может быть кто-то проделал ту же работу, что и я, но добился больших успехов.


В следующей части, если кто-то кинет таки инвайт в песочницу, покажу как расширить наш сценарий для работы с МФУ Xerox и Kyocera.


This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий