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

    Kyocera M2035dn, Xerox WorkCentre 3615 и 6505DN


    Как и обещал в первой части, за которую я успешно получил инвайт в песочнице, в этой заметке я покажу как подключить сетевые МФУ Kyocera M2035dn, Xerox WorkCentre 3615 и 6505DN, а в конце статьи добавлю небольшой бонус с которым любой скрипт связанный с сетью становится лучше.



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

    Kyocera M2035dn


    Приехал как всегда не в мое уютное админское логово, а сразу на объект и как и мфу от HP, в глаза его я, если честно, даже не видел.
    Первым делом качаем драйвер и смотрим содержимое… ба, знакомые все люди:



    Есть пометка о том, что подключение сетевое (network) и есть ID!
    Попробуем подключить сканер через devcon, подобно тому как мы подключали МФУ от HP в первой части:
    .\devcon.exe /r install C:\Drivers\Scanners\2035dnscan\kmwiadrv.inf "KM_WC_ECOSYS_M2035dn_N_WIA"

    Сканер подключился, прописываем в реестр адрес сканера параметром ScannerAddress и запускаем сканирование. Приложение сканирования показало отсканированный лист, все работает отлично. Казалось бы победа, но запуск второй, используемой у нас программы для сканирования, поубавил радости — сканер в ней не отображался.



    Оказывается разработчики Kyocera почему-то в драйвере реализовали сканирование только через WIA, для TWAIN надо ставить отдельный косты.. враппер, который пробрасывает TWAIN интерфейс в WIA и возвращает обратно результат. Выглядит гуй этого TWAIN драйвера следующим образом:



    При этом, по WIA мы можем подключить несколько сканеров Kyocera, в то время как TWAIN интерфейс у нас будет всегда только один. Либо пользуйтесь WIA, либо каждый раз запускайте нашу утилиту и переключайте сканер. Придется смириться, а пока посмотрим как нам обойти запуск этой утилиты на машине пользователя.
    Утилита хранит настройки в ini-файлах, по одному файлу KM_TWAIN*.ini на каждый сетевой сканер и один результирующий файл с описанием сканеров и файлов их настроек.
    Скрин обоих файлов, для одного подключенного сканера:



    Теперь установка видится следующей:
    — подключаем сканер через devcon
    — если утилита TWAIN не установлена, ставим её
    — добавляем адрес сканера в реестр
    — проходимся по реестру в поиске подключенных сканеров Kyocera и на основе данных в реестре генерируем ini-файлы

    Расширим функцию подключения сканера из предыдущей заметки следующим кодом, который я постарался по-максимуму прокомментировать:

    # знакомый нам участок кода с подключением через devcon
    "M2035dn" {
        Push-Location 'C:\Drivers\Scanners\ip\2035dnscan\'
        if ($(Get-Platform) -eq "Windows x64") {
            .\devconx64.exe /r install $dest\kmwiadrv.inf "KM_WC_ECOSYS_M2035dn_N_WIA"
        } else {
            .\devcon.exe /r install $dest\kmwiadrv.inf "KM_WC_ECOSYS_M2035dn_N_WIA"
        }
        Pop-Location
    
        # проверяем стоит ли костыль kyocera, если нет ставим в тихом режиме
        $twain = Get-WMIObject -Class Win32_Product -Filter 'Name = "Kyocera TWAIN Driver"'
        if (!($twain)) {
            Push-Location 'C:\Drivers\Scanners\2035dnscan\TWAIN'
            .\setup.exe /S /v /qn
            Pop-Location
        }
    
        # получаем содержимое ветки реестра в которой хранятся настройки сканеров и камер
        $scanclass = 'HKLM:\SYSTEM\CurrentControlSet\Control\Class\{6BDD1FC6-810F-11D0-BEC7-08002BE2092F}'
    
        # так как мы только что поставили новый сканер, то его номер будет последним среди сканеров
        $item = (Get-ChildItem $scanclass | Where-Object Name -match "\d{4}$" | Select -Last 1).PSChildName
    
        # добавляем адрес сканера
        New-ItemProperty "$scanclass\$item\DeviceData" -Name "ScannerAddress" -Value $ipaddress | Out-Null
    
        # тут применил расширенный синтаксис Foreach-Object, состоящий из трех частей
        # первая и последняя выполняются по одному разу, при запуске цикла и его окончании соответственно;
        # код в секции process выполняется для каждого элемента цикла
        Get-ChildItem  $scanclass | Foreach-Object -Begin {
            $count = 0
            Add-Type -As System.Web
            # стандартный пароль, который задает утилита
            $pass = '43srWkUjR/8='
            $scanitem = @{}
            $filelist = @()
        } -Process {
            $path = $_.Name -replace 'HKEY_LOCAL_MACHINE', 'HKLM:'
            $prop = Get-ItemProperty $path
            if ($prop.Vendor -eq 'Kyocera') {
                $count ++
                $twfilename = "KM_TWAIN$count`.INI"
                $devicedata = Get-ItemProperty "$path\DeviceData"
                $cont = @{'Unit'='0';'ScannerAddress'=$devicedata.ScannerAddress; 'SSL'='0'}
                $auth = @{'Auth'='0';'UserName'=''; 'Account'='0'; 'ID'='';'Password'=$pass}
                $twcont = @{'Contents'=$cont; 'Authentication'=$auth}
                Out-IniFile -inputobject $twcont -FilePath "$env:temp\$twfilename"
                $filelist += , "$env:temp\$twfilename"
    
                $devicename = $devicedata.'Model Name' + " #$count"
                $modelname = $devicedata.'Model Name'
                $scanreg = @{'Name'=$devicename;'Model'=$modelname;'DefFile'=$twfilename;'LastScan'='';'ScanList'='';'Pos'=($count-1)}
                $scanitem.Add("Scanner$count", $scanreg)
            }
        } -End {
            $regfilename = 'RegList.ini'
            $settings = @{'Type'='4'; 'DefaultUse'=$count;'RegNum'=$count;}
            $reglist = @{'Setting'=$settings}
            $reglist += $scanitem
            Out-IniFile -inputobject $reglist -FilePath "$env:temp\$regfilename"
            $filelist += , "$env:temp\$regfilename"
        }
    
        # удаляем предыдущие ini-файлы и подкладываем сгенерированные выше с новым сканером
        Get-ChildItem $env:systemdrive\users -Directory -Recurse -Include 'appdata' -Force | ForEach-Object {
            $kyodir = $_.FullName + "\Roaming\Kyocera\KM_TWAIN"
            If (!(Test-Path $kyodir)) {
                New-Item -Type Directory -Path $kyodir
            } else {
                Remove-Item "$kyodir\*" -Recurse
            }
            $filelist | ForEach-Object {
                Copy-Item $_ $kyodir -Force | Out-Null
            }
        }
    }
    

    В скрипте я использовал функцию вывода хэш-таблицы в ini-файл, вот её код:

    function Out-IniFile($inputobject, $filepath) {
        # .Example
        # $Category1 = @{'Key1'='Value1';'Key2'='Value2'}
        # $Category2 = @{'Key1'='Value1';'Key2'='Value2'}
        # $NewINIContent = @{'Category1'=$Category1;'Category2'=$Category2}
        # Out-IniFile -inputobject $NewINIContent -FilePath 'C:\MyNewFile.INI'
    
        $outfile = New-Item -ItemType File -Path $filepath -Force
        foreach ($i in $inputobject.keys) {
            Add-Content -Path $outfile -Value "[$i]"
            Foreach ($j in ($inputobject[$i].keys | Sort-Object)) {
                Add-Content -Path $outfile -Value "$j=$($inputobject[$i][$j])"
            }
            Add-Content -Path $outfile -Value ''
        }
    }
    


    Xerox WorkCentre 3615 и 6505DN


    Код этот успешно работал и проблем с ним не возникало, наверное, на протяжении полугода пока ветер опять не подул в другую сторону. В сторону Xerox.
    В аутлук упало письмо с ip-адресами двух новых мфу, WorkCentre 3615 и WorkCentre 6505DN. Дорога хода мыслей при знакомстве с новым мфу уже проторена, открываем драйвер и видим знакомое:



    И настроение мое улучшилось©

    Распаковываем драйвер, запускаем консоль, выполняем:
    .\devcon.exe /r install C:\Drivers\Scanners\xx3615\xrszdim.inf "NON_PNP&WorkCentre3615"

    Сканер подключился и на экран выскочил новый, как это принято говорить, воркэраунд, только уже от разработчиков Xerox:



    Очередная странная утилита от авторов драйвера для прописывания IP, причем запускается она из драйвера при установке. Значит, для того что бы спрятать ее от пользователя, будем прибивать ее в скрипте, в общем-то не беда.

    Сейчас покажу на примере 3615, как расширить функцию подключения сканера. От 6506DN она практически не отличается, разве что другое имя файла драйвера и ID:

    "3615" {
        Push-Location 'C:\Drivers\Scanners\xx3615\'
        if ($(Get-Platform) -eq "Windows x64") {
            .\devconx64.exe /r install C:\Drivers\Scanners\xx3615\xrszdim.inf "NON_PNP&WorkCentre3615"
        } else {
            .\devcon.exe /r install C:\Drivers\Scanners\xx3615\xrszdim.inf "NON_PNP&WorkCentre3615"
        }
        Pop-Location
        
        Get-Process "AIOScanSettings" | Stop-Process -Force
    
        # не могу вразумительно ответить почему я тут применил reg add,
        # спишем на ностальгию по cmd, а замену на New-ItemProperty оставим домашкою читателю
        &rеg.exe add "hklm\SOFTWARE\Xerox\WorkCentre 3615\TwainDriver" /v "EnableEnhancedBW" /t REG_DWORD /d 1 /f
        &rеg.exe add "hklm\SOFTWARE\Xerox\WorkCentre 3615\TwainDriver" /v "ISO_B_Series" /t REG_DWORD /d 1 /f
        &rеg.exe add "hklm\SOFTWARE\Xerox\WorkCentre 3615\TwainDriver" /v "IP Address" /t REG_SZ /d $ipAddress /f
     
    }
    


    Теперь мы умеем подключать целый зоопарк сетевых мфу и совершенно ничего не боимся, осталось добавить какой-нибудь магии… магии snmp!

    Ищем МФУ в сети по snmp


    SNMP (англ. Simple Network Management Protocol — простой протокол сетевого управления) — стандартный интернет-протокол для управления устройствами в IP-сетях на основе архитектур TCP/UDP.
    ru.wikipedia.org/wiki/SNMP


    Для работы с snmp из powershell я в скрипте использовал открытую библиотеку sharpsnmp, подробнее о ее использовании можно почитать по адресу: vwiki.co.uk/SNMP_and_PowerShell
    После подключения библиотеки получение информации сводится к вызову функции Invoke-SNMPget с указанием Ip и uid, последний из которых легко гуглится.
    Пример из кода:
    Invoke-SNMPget $ip .1.3.6.1.2.1.25.3.2.1.3.1

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



    Остается выделить нужный принтер и нажать OK, кстати множественное выделение так же возможно, в этом случае подключатся все выделенные принтеры.
    Эту удобную гуёвую магию обеспечивает командлет Out-GridView, отображающий любые переданные в него объекты. При вызове с параметром PassThru, после нажатия OK он передаст дальше по конвейеру выбранные объекты, нам остается только по очереди вызвать наши функции установки драйверов с параметрами пришедшими в объекте из конвейера.

    В упрощенном виде скрипт примет вид:
    $hosts | Out-GridView -Title "Выберите принтеры для установки" -PassThru | Foreach-Object {
            $printername = $_.Name
            $printersource = $_.Source
    
            switch -regex ($printername) {
                "xerox.+3615" {
                    $modelname = "Xerox WorkCentre 6505DN PCL 6"
                    $driverpath = 'C:\Drivers\Scanners\xx6505\xrxmozi.inf'
                }
            }
    
            Write-Host "Добавляется порт IP принтера $printerName"
            Add-PrinterPort $modelname $printersource
    
            Write-Host "Добавляется драйвер принтера $printername"
            Add-PrinterDriver $modelname $driverpath
    
            Write-Host "Добавляется сканер принтера $printername"
            Add-Scanner $printersource $modelname 
        }
    


    В процессе изучения откликов принтеров, столкнулся с тем, что принтеры отдают порой имя отличающееся от имени прописанного в драйвере, для обхода этой особенности добавил в скрипт простой свитч с регулярками, которые никогда не промахиваются и как мы знаем полны по Тьюрингу ;-)

    switch -regex ($printername) {
        "hp.+305\d" {
            $modelName = "HP LaserJet 3050 Series PCL 6"
        }
        "hp.+3390" {
            $modelName = "HP LaserJet 3390 Series PCL 6"
        }
        "xerox.+3615" {
            $modelName = "Xerox WorkCentre 3615 PCL6"
        }
        "xerox.+650[0,5]DN" {
            $modelName = "Xerox WorkCentre 6505DN PCL 6"
        }
    }
    


    Полный код готового скрипта поиска и подключения сетевого принтера
    $ErrorActionPreference = "silentlycontinue"
    
    function Main {
    
    	# путь к драйверам
    	$driversdistrib = 'C:\Drivers\'
    
    	# загружаем snmp либу
    	$snmplibpath = Join-Path (Get-Location).path "\SharpSnmpLib.dll"
    	if (Test-Path $snmplibpath) {
    		[reflection.assembly]::LoadFrom((Resolve-Path $snmplibpath))
    	} else {
    		Write-Host "Не удалось найти SharpSnmpLib"
    		Exit
    	}
    
    	# вычисляем подсеть, без хитрой математики, в лоб и только /24
    	$network = (Get-IPaddress).ToString() -replace "\.[0-9]{1,3}$"
    
    	# в диапазоне закрепленном за принтерами ищем устройства
    	$hosts = 10..40 | ForEach-Object {
    		$ip = "$network.$_"
    		$snmpanswer= $null
    		$snmpanswer = Invoke-SNMPget $ip .1.3.6.1.2.1.25.3.2.1.3.1
    		if ($snmpanswer) {
    			# формируем объект с двумя свойствами который улетит в переменную $hosts
    			[pscustomobject]@{
    				Name = $snmpanswer.Data;
    				Source = $ip;
    			}
    		}
    	}
    
    	# выводим объекты в гуй с параметром PassThru, который передаст выбранные дальше по конвейеру
    	$hosts | Out-GridView -Title "Выберите принтеры для установки" -PassThru | Foreach-Object {
    		$printername = $_.Name
    		$printersource = $_.Source
    
    		switch -regex ($printername) {
    			"hp.+305\d" {
    				$printername = "HP LaserJet 3050 Series PCL 6"
    				$driverpath = Join-Path $driversdistrib 'Printers\3050\hppcp601.inf'
    			}
    			"hp.+3390" {
    				$printername = "HP LaserJet 3390 Series PCL 6"
    				$driverpath = Join-Path $driversdistrib 'Printers\3050\hppcp601.inf'
    			}
    			"hp.+153[0,6]" {
    				$printername = "HP LaserJet M1530 MFP Series PCL 6"
    				$driverpath = Join-Path $driversdistrib 'Printers\1530\hpc1530c.inf'
    			}
    			"hp.+1522" {
    				$printername = "HP LaserJet M1522 MFP Series PCL 6"
    				$driverpath = Join-Path $driversdistrib 'Printers\1522\hppcp608.inf'
    			}
    			"M2035dn" {
    				$printername = "Kyocera ECOSYS M2035dn KX"
    				$driverpath = Join-Path $driversdistrib 'Printers\2035dn\OEMSETUP.INF'
    			}			
    			"xerox.+3615" {
    				$printername = "Xerox WorkCentre 3615 PCL6"
    				$driverpath = Join-Path $driversdistrib 'Scanners\xx3615\x2GPROX.inf'
    			}
    			"xerox.+650[0,5]DN" {
    				$printername = "Xerox WorkCentre 6505DN PCL 6"
    				$driverpath = Join-Path $driversdistrib 'Scanners\xx6505\xrxmozi.inf'
    			}
    		}
    
    		Write-Host "Добавляется порт IP принтера $printerName"
    		Add-PrinterPort $printername $printersource
    
    		Write-Host "Добавляется драйвер принтера $printername"
    		Add-PrinterDriver $printername  $driverpath
    
    		Write-Host "Добавляется сканер принтера $printername"
    		Add-Scanner $printersource $printername
    	}
    }
    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 Add-Scanner ($ipaddress, $printername) {
    	switch -regex ($printername) {
    		"1530" {
    			Push-Location (Join-Path $driversdistrib 'Scanners\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 (Join-Path $driversdistrib 'Scanners\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
    		}
    		"1522" {
    			Push-Location (Join-Path $driversdistrib 'Scanners\1522scan\')
    			if ($(Get-Platform) -eq "Windows x64") {
    				.\hppniscan64.exe -f "hppasc08.inf" -m "vid_03f0&pid_4517&IP_SCAN" -a $ipAddress -n 1
    			} else {
    				.\hppniscan01.exe -f "hppasc08.inf" -m "vid_03f0&pid_4517&IP_SCAN" -a $ipAddress -n 1
    			}
    			Pop-Location
    		}
    		"M2035dn" {
    			Push-Location (Join-Path $driversdistrib 'Scanners\2035dnscan\')
    			if ($(Get-Platform) -eq "Windows x64") {
    				.\devconx64.exe /r install $dest\kmwiadrv.inf "KM_WC_ECOSYS_M2035dn_N_WIA"
    			} else {
    				.\devcon.exe /r install $dest\kmwiadrv.inf "KM_WC_ECOSYS_M2035dn_N_WIA"
    			}
    			Pop-Location
    
    			$twain = Get-WMIObject -Class Win32_Product -Filter 'Name = "Kyocera TWAIN Driver"'
    			if (!($twain)) {
    				Push-Location (Join-Path $driversdistrib 'Scanners\2035dnscan\TWAIN')
    				.\setup.exe /S /v /qn
    				Pop-Location
    			}
    
    			$scanclass = 'HKLM:\SYSTEM\CurrentControlSet\Control\Class\{6BDD1FC6-810F-11D0-BEC7-08002BE2092F}'
    			$item = (Get-ChildItem $scanclass | Where-Object Name -match "\d{4}$" | Select -Last 1).PSChildName
    			New-ItemProperty "$scanclass\$item\DeviceData" -Name "ScannerAddress" -Value $ipAddress | Out-Null
    			Get-ChildItem  $scanclass | ForEach-Object -Begin {
    				$count = 0
    				Add-Type -As System.Web
    				$pass = [System.Web.Security.Membership]::GeneratePassword(12,2)
    				$scanitem = @{}
    				$filelist = @()
    			} -Process {
    				$path = $_.Name -replace 'HKEY_LOCAL_MACHINE', 'HKLM:'
    				$prop = Get-ItemProperty $path
    				if ($prop.Vendor -eq 'Kyocera') {
    					$count ++
    					$twfilename = "KM_TWAIN$count`.INI"
    					$devicedata = Get-ItemProperty "$path\DeviceData"
    					$cont = @{'Unit'='0';'ScannerAddress'=$devicedata.ScannerAddress; 'SSL'='0'}
    					$auth = @{'Auth'='0';'UserName'=''; 'Account'='0'; 'ID'='';'Password'=$pass}
    					$twcont = @{'Contents'=$cont; 'Authentication'=$auth}
    					Out-IniFile -inputobject $twcont -FilePath "$env:temp\$twfilename"
    					$filelist += , "$env:temp\$twfilename"
    
    					$devicename = $devicedata.'Model Name' + " #$count"
    					$modelname = $devicedata.'Model Name'
    					$scanreg = @{'Name'=$devicename;'Model'=$modelname;'DefFile'=$twfilename;'LastScan'='';'ScanList'='';'Pos'=($count-1)}
    					$scanitem.Add("Scanner$count", $scanreg)
    				}
    			} -End {
    				$regfilename = 'RegList.ini'
    				$settings = @{'Type'='4'; 'DefaultUse'=$count;'RegNum'=$count;}
    				$reglist = @{'Setting'=$settings}
    				$reglist += $scanitem
    				Out-IniFile -inputobject $reglist -FilePath "$env:temp\$regfilename"
    				$filelist += , "$env:temp\$regfilename"
    			}
    			Get-ChildItem $env:systemdrive\users -Directory -Recurse -Include 'appdata' -Force | ForEach-Object {
    				$kyodir = $_.FullName + "\Roaming\Kyocera\KM_TWAIN"
    				If (!(Test-Path $kyodir)) {
    					New-Item -Type Directory -Path $kyodir
    				} else {
    					Remove-Item "$kyodir\*" -Recurse
    				}
    				$filelist | ForEach-Object {
    					Copy-Item $_ $kyodir -Force | Out-Null
    				}
    			}
    		}
    		"6505" {
    			Push-Location (Join-Path $driversdistrib 'Scanners\xx6505\')
    			if ($(Get-Platform) -eq "Windows x64") {
    				.\devconx64.exe /r install $dest\xrsmoim.inf "NON_PNP&WorkCentre6505"
    			} else {
    				.\devcon.exe /r install $dest\xrsmoim.inf "NON_PNP&WorkCentre6505"
    			}
    			Pop-Location
    
    			Get-Process "AIOScanSettings" | Stop-Process -Force
    
    			&rеg.exe add "hklm\SOFTWARE\Xerox\WorkCentre 6505\TwainDriver" /v "EnableEnhancedBW" /t REG_DWORD /d 1 /f
    			&rеg.exe add "hklm\SOFTWARE\Xerox\WorkCentre 6505\TwainDriver" /v "IP Address" /t REG_SZ /d $ipAddress /f
    		}
    		"3615" {
    			Push-Location (Join-Path $driversdistrib 'Scanners\xx3615\')
    			if ($(Get-Platform) -eq "Windows x64") {
    				.\devconx64.exe /r install $dest\xrszdim.inf "NON_PNP&WorkCentre3615"
    			} else {
    				.\devcon.exe /r install $dest\xrszdim.inf "NON_PNP&WorkCentre3615"
    			}
    			Pop-Location
    
    			Get-Process "AIOScanSettings" | Stop-Process -Force
                # тут в слове rеg, средняя буква русская, дабы не превращался в ®
    			&rеg.exe add "hklm\SOFTWARE\Xerox\WorkCentre 3615\TwainDriver" /v "EnableEnhancedBW" /t REG_DWORD /d 1 /f
    			&rеg.exe add "hklm\SOFTWARE\Xerox\WorkCentre 3615\TwainDriver" /v "ISO_B_Series" /t REG_DWORD /d 1 /f
    			&rеg.exe add "hklm\SOFTWARE\Xerox\WorkCentre 3615\TwainDriver" /v "IP Address" /t REG_SZ /d $ipAddress /f
    		}
    	}
    }
    function Get-IPaddress {
    	$ipWmiObject = Get-WmiObject Win32_NetworkAdapterConfiguration -filter "IPEnabled = 'True'"
    	$ipWmiObject.IPAddress -match "^192\.([0-9]{1,3}\.){2}[0-9]{1,3}$"
    }
    function Get-Platform {
    	if ([System.Environment]::Is64BitOperatingSystem) {
    		"Windows x64"
    	} else {
    		"Windows NT x86"
    	}
    }
    function Out-IniFile($inputobject, $filepath) {
    	# .Example
    	# $Category1 = @{'Key1'='Value1';'Key2'='Value2'}
    	# $Category2 = @{'Key1'='Value1';'Key2'='Value2'}
    	# $NewINIContent = @{'Category1'=$Category1;'Category2'=$Category2}
    	# Out-IniFile -inputobject $NewINIContent -FilePath 'C:\MyNewFile.INI'
    
    	$outfile = New-Item -ItemType File -Path $filepath -Force
    	foreach ($i in $inputobject.keys) {
    		Add-Content -Path $outfile -Value "[$i]"
    		Foreach ($j in ($inputobject[$i].keys | Sort-Object)) {
    			Add-Content -Path $outfile -Value "$j=$($inputobject[$i][$j])"
    		}
    		Add-Content -Path $outfile -Value ''
    	}
    }
    function Invoke-SNMPget {
    	param (
    		[string]$sIP,
    		$sOIDs,
    		[string]$Community = "public",
    		[int]$UDPport = 161,
    		[int]$TimeOut=30
    		)
    	$vList = New-Object 'System.Collections.Generic.List[Lextm.SharpSnmpLib.Variable]'
    	foreach ($sOID in $sOIDs) {
    		$oid = New-Object Lextm.SharpSnmpLib.ObjectIdentifier ($sOID)
    		$vList.Add($oid)
    	}
    	$ip = [System.Net.IPAddress]::Parse($sIP)
    	$svr = New-Object System.Net.IpEndPoint ($ip, 161)
    	$ver = [Lextm.SharpSnmpLib.VersionCode]::V1
    
    	try {
    		$msg = [Lextm.SharpSnmpLib.Messaging.Messenger]::Get($ver, $svr, $Community, $vList, $TimeOut)
    	} catch {
    		return $null
    	}
    
    	$res = @()
    	foreach ($var in $msg) {
    		$line = "" | Select OID, Data
    		$line.OID = $var.Id.ToString()
    		$line.Data = $var.Data.ToString()
    		$res += $line
    	}
    	$res
    }
    
    . Main
    



    На этом на сегодня всё, надеюсь мои заметки помогут вам забыть о проблемах с сетевыми принтерами и освободят время для изучения PowerShell.
    Спасибо за внимание тем, кто дочитал до этого момента ;-)
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 10

      0
      Большое человеческое спасибо за Kyocera M2035dn, у нас такой же стоит и мне удалось куда более тягомотную схему сканирования настроить только. Пойду пробовать ваш вариант.
        0
        А что не так со сканированием в Киосере? У меня на работе двумя кнопками сканирование запускается, в сетевую папку. Никаких проблем.
        0
        Использую утилиту NAPS2 (Not Another PDF Scanner 2) для сканирования через TWAIN.
        А конкретно на M2035dn, пользователи сканируют с аппарата себе в шару. Так даже удобней.
          0
          Спасибо за наводку, симпатичная программа.
          Не понравилось только то, что сканеры надо добавлять руками, создавая профили сканирования. Это конечно логично, с точки зрения гика, но для конечного пользователя, по-моему опыту, нужен быстрый старт, а там уж по возникшим вопросам в профили.
            0

            а как вам такое удалось? :)
            у меня есть один НР 1536 на толпу народа.
            Нужно научить МФУ сканить в сетевые папки — по одной на каждого юзера т.е. пришел к МФУ, загрузил стопку листов в автоподатчик, выбрал папку, а МФУ в нее сложил все сканы или же выслал на почту)
            Такое реально??

            0
            rbobot а вы еще принимаете «заказы» на МФУ? :)
            Если да, то запишите в очередь НР М2727
              0
              А я принимал? :-)
              По аналогии сделать не получается?
                0
                Скачал фуллсолюшен, распаковал архиватором, в папке setup лежит знакомые файлы hppniscan01.exe и hppniscan64.exe
                Так что проблем нет, вернитесь к первому посту и немного отредактируйте скрипт под ваше имя и id мфу.
                  +1
                  id сканера — vid_03f0&pid_4D17&IP_SCAN, inf файла сканера — hppasc07.inf
                  Полное имя принтера для установки драйвера — «HP LaserJet M2727 MFP Series PCL 6», имя файла драйвера — hppcp607.inf
                    0
                    последние 3 сообщения правильно было… а нет, последний вопрос правильно было задавать в 1-й статье. а теперь хорошо бы ссылку там сделать на него сюда.

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

                Самое читаемое