
Automatic connection of network MFPs with the ability to scan [Part 1]
HP LaserJet 1522, 1536, 3052/3055, 300/400 Color ...
I think many system administrators know the MFIs described in the header, they differ, first of all, in a not very convenient installation and are notorious for this. Once, copying a fullsolution package for an MFP weighing about 300 megabytes onto a next computer through a narrow channel, the idea to disassemble this installer and automate the installation popped up in my eyes - I had to suspend work.

I was already analyzing the driver about a year and a half ago, while the Internet on this topic was completely empty. Now I quickly googled using the utilities keywords now known to me and found a bit of scattered information. Despite this, I decided. that the information gathered in one place will still not hurt, despite the fact that in this post it is more complete.
Set up printing
The HP LaserJet 1536 MFP was the first to ask for snmp, and decided to start with it. First you need to understand. how to connect it as a printer under Windows 7; I threw away old XP right away, fresh Windows 8 in the domain, there is an opinion, I will never see. That's the reason to get acquainted with the new PowerShell for myself, I thought, which in the end was almost the main motivation in parsing the driver. Connecting an ip-printer in Windows 7 consists of three stages (in Windows 8, everything is greatly simplified by the built-in cmdlets, but I already spoke about it - it’s not fate), first create an ip-port, then add the driver and connect the printer itself. For all these stages, Windows has ready-made VBS scripts, many, I think, familiar, have a way to them in Windows 7: C: \ Windows \ System32 \ Printing_Admin_Scripts \
I’ll start by creating a port, this step is the easiest, we’ll assign the same name as ip: Adding a driver: One important feature is worth mentioning here: the printer name should be indicated exactly as it is written in the driver inf file, for example, remove part of the name, the script will print error: "Failed to add the HP LaserJet printer driver Win32 error code 87". An excerpt of the driver file with the full name of the printer: Now it remains to connect the printer, for this I settled on the wonderful printui program, I advise you to look at it closely, it has interesting keys. The time has come to put all this into something like the following PowerShell script:
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"


&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
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
}

Scanning
Digging into the driver inf files to find the correct printer name and incidentally even understanding the HP driver structure, the eye caught on to the following lines (highlighted in bold):
; The Windows Vista
[HP.NT.6.0]
«the HP LJ the M1530 the MFP the Series the Scan» = WIA_1530_Inst.NT.6.0, the USB \ vid_03f0 & pid_012a & MI_00
«the HP LJ the M1530 the MFP the Series the Scan» = WIA_1530_NW.NT.6.0, vid_03f0 & pid_012a & IP_SCAN
; the 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
Here I would like lyrics (it would seem, what does 1C have to do with it? If you know what I mean), but I will go down to a dry statement: let's try devcon.exe.
DevCon is a command-line program that is used as an alternative to device manager. It can be used to turn on, turn off, restart, update, delete and query individual devices or groups of devices. DevCon also provides the driver-specific information that is not available through the device manager.
support.microsoft.com/kb/311272/en
We add the device by ID indicating the driver:
.\devcon.exe /r install C:\drivers\1536scan\hppasc16.inf "vid_03f0&pid_012a&IP_SCAN"
Add the necessary parameters to the registry, start the scan and ... Bingo!
The scanner works fine, it remains to arrange all this.
The scanner settings in the registry are stored in the following ways:
HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ Class \ {6BDD1FC6-810F-11D0-BEC7-08002BE2092F}
HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Enum \ Root \ IMAGE
We use the following keys:


For experienced Users : In order to conveniently add registry settings, create the file quoted below, which will serve us as a template for modification inside the script.
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ Class \ {6BDD1FC6-810F-11D0-BEC7-08002BE2092F} \ _ ITEM_ \ DeviceData]
"NetworkDeviceID" = "\\ hostname: _NETWORK_NAME_\domainocal _IP_ADDRESS _ \\ guid: \\ macaddr: _MAC_ADDRESS _ \\ port: 1 "
" PortID "=" _ IP_ADDRESS_ "
" NetworkHostName "=" _ NETWORK_NAME_.domain.local "
" TulipIOType "= dword: 00000005
[HKEY_LOCALMACH Current 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_"
The finished script for installing the scanner will take the following form:
$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
We rub our hands, check - it works, we modify it under 1522 - it works, we triumph right under 3055 - a bummer ... The
scanner does not allow you to select a tablet, only the feeder is available in the scan menu, and even it refuses to scan.

Serious conversation with 3055 or, Dude, you raised the wrong stone to the mountain

Here he is, LaserJet 3055/3052 - the most harmful guy, surprisingly I see him most often. In fact - I will tell you a secret - I started to deal with it first - went through the jungle of filtering procmon output when installing the driver to find something interesting and drowned somewhere in the middle. When procmon fell again due to lack of memory, I decided to postpone this venture to a more friendly and calm state.
The second raid on parsing the MFP installer yielded the result: after an hour and a half parsing of logs in the bowels of the installer's output, a pearl was found - hppniscan01.exe
Starting with the necessary parameters instantly installed the scanner in the device and registered the necessary registry branches:
hppniscan01.exe -f "hppasc16.inf" -m "vid_03f0&pid_012a&IP_SCAN" -a "192.168.0.30" -n 1

The driver distributions of other HP printers have its sixty-four bit version, while the 3055 driver only supports x86 operating systems.
I decided to pull out the scanner drivers from the shared drivers folder and put them separately, the necessary files are easily read from the driver inf-file. The tree turned out as follows:
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
The scanner installation function has now become quite simple, albeit with a dependence on the external component.
The final form of the script, with some hard-coded simplifications, will take the following form:
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
}
The same method is great for all HP MFPs that came around me, for which I created separate folders with drivers and options for choosing the scanner installation function in the switch.
The list of driver files can be found in the sections of the inf-file with the names [SourceDisksFiles], [RegisterDlls], [WIA_CopyFiles] and then on the file. Screenshot for drivers 3055 and 1536, for clarity:

From the code snippets described in this note, you can compile a full-fledged script for automatic installation of MFPs, and if you add a little buzz and snmp to it, you can completely close the topic of installing MFPs on new machines forever.
That's all for today, thanks for your attention. If in the comments they tell you what the 3055 MFP is missing for working during the first installation using devcon, I will be very grateful. Maybe someone did the same job as me, but achieved great success.
In the next part,