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

в 12:50, , рубрики: laserjet, powershell, МФУ, системное администрирование, сканирование

HP LaserJet 1522, 1536, 3052/3055, 300/400 Color...

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

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

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

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

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

cscript C:WindowsSystem32Printing_Admin_Scriptsru-RUprnport.vbs -a -r "192.168.0.30" -h "192.168.0.30" -o RAW -n 9100

Добавление драйвера:
cscript C:WindowsSystem32Printing_Admin_Scriptsru-RUprndrvr.vbs -a -m "HP LaserJet M1530 MFP Series PCL 6" -e "Windows NT x86" -h "C:drivers1536"-i "C:drivers1536hpc1530c.inf"

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

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

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

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

Теперь осталось подключить принтер, для этого я остановился на замечательной программе 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:WindowsSystem32Printing_Admin_Scriptsru-RUprnport.vbs `
	-a -r $printersource -h $printersource -o RAW -n 9100 | Out-Null
}

function Add-PrinterDriver ($printername, $driverpath) {
	$folder = Split-Path $driverPath
	cscript C:WindowsSystem32Printing_Admin_Scriptsru-RUprndrvr.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:drivers1536hpc1530c.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
}

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

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

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

;Windows Vista
[HP.NT.6.0]
«HP LJ M1530 MFP Series Scan»= WIA_1530_Inst.NT.6.0, USBvid_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, USBvid_03f0&pid_012a&mi_00
«HP LJ M1530 MFP Series Scan»= WIA_1530_NW_Vista64,vid_03f0&pid_012a&IP_SCAN

Настройки сканера в реестре хранятся по следующим путям:
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlClass{6BDD1FC6-810F-11D0-BEC7-08002BE2092F}
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetEnumRootIMAGE

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

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

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

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

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

support.microsoft.com/kb/311272/ru

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

.devcon.exe /r install C:drivers1536scanhppasc16.inf "vid_03f0&pid_012a&IP_SCAN"

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

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

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlClass{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_MACHINESYSTEMCurrentControlSetEnumRootIMAGE_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:drivers1536scan"
$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:SYSTEMCurrentControlSetControlClass"{6BDD1FC6-810F-11D0-BEC7-08002BE2092F}" |
	Select-Object -Last 1
$item = $item.Substring($item.Length-4, 4)

$pattern = ".temporary1536.reg"
$result = ".temporaryres.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 .temporaryres.reg

Потираем руки, проверяем — работает, модифицируем под 1522 — работает, победно правим под 3055 — облом…
Сканер не дает выбрать планшет, в меню сканирования доступен только податчик, да и тот отказывается сканировать.

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

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

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

Вот он, 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

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

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

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

C:DriversScannersip3055scanhpgtpusd.dll
C:DriversScannersip3055scanhppasc01.cat
C:DriversScannersip3055scanhppasc01.dll
C:DriversScannersip3055scanhppasc01.inf
C:DriversScannersip3055scanhppniscan01.exe
C:DriversScannersip3055scanhpptpml3.dll
C:DriversScannersip3055scanhpxp3390.dll
C:DriversScannersip3055scanDriversdot4
C:DriversScannersip3055scanDriversdot4Win2000hpzidr12.dll
C:DriversScannersip3055scanDriversdot4Win2000hpzipm12.dll
C:DriversScannersip3055scanDriversdot4Win2000hpzipr12.dll
C:DriversScannersip3055scanDriversdot4Win2000hpzipr12.sys

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

function Add-PrinterPort ($printerSource) {
    cscript C:WindowsSystem32Printing_Admin_Scriptsru-RUprnport.vbs `
    -a -r $printerSource -h $printerSource -o RAW -n 9100 | Out-Null
}

function Add-PrinterDriver ($printerName, $driverPath) {
    $folder = Split-Path $driverPath
    cscript C:WindowsSystem32Printing_Admin_Scriptsru-RUprndrvr.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:DriversScannersip1536scan'
            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
        }        
        "(305d)|(3390)" {
            Push-Location 'C:DriversScannersip3055scan'
            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:drivers1536hpc1530c.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, для наглядности:

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

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

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

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

Автор: rbobot

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js