Если такая заявка в вашей системе сервис-деска вызывает дергающийся глаз и падение тонуса ? у вас наверняка еще не настроено удобное централизованное управление принтерами. Пора исправлять эту неувязочку.


Статья скорее для тех, у кого нет этого сферического корпорейта в вакууме, с виртуальными принтерами, прикладыванием пропуска для печати на HP M8xx, а то и даже Ricoh Pro 8ххх. Как обычно, запасаемся скриптами, GPO и еще раз скриптами.


Собираем принтеры в одну точку подключения


В качестве первой меры, облегчающей жизнь, рекомендую завести сервер печати, где можно развернуть все принтеры организации. В идеале это отдельная виртуальная машина, где все принтеры являются сетевыми и выведены в отдельный VLAN с доступом только с сервера печати. Если невозможно использовать сетевой принтер, то в крайнем случае можно превратить компьютер с USB\LPT принтером в принт-сервер. Например, при помощи утилиты rawprintserver.


Помимо удобства обслуживания конфигурация с единым сервером печати позволит запросто реализовать и «наколеночные» отчеты печати, разбирая журнал Microsoft-Windows-PrintService/Operational. Надеюсь, что с решением этой задачи поможет наш материал «Вертим логи как хотим ? анализ журналов в системах Windows», а в качестве примера предложу следующий скрипт PowerShell:


$events = Get-WinEvent -FilterHashtable @{LogName = "Microsoft-Windows-PrintService/Operational"; ID = 307} | foreach{
New-Object PSobject -Property @{
Time_Created = $_.TimeCreated
Document_Number = $_.Properties[0].value
Document_Name = $_.Properties[1].value
UserID = $_.Properties[2].value
Printer = $_.Properties[4].value
PagesCount = $_.Properties[7].value
}
} 
$events  | select userid, printer ,pagescount


Результат работы скрипта.


Вдобавок, можно как следует заняться оптимизацией быстродействия единого сервера печати, объединять принтеры в кластер. В общем, развлекаться как угодно ? хотя бы мониторить принтеры по SNMP и заранее уведомлять сотрудников о заканчивающихся картриджах.


Перейдем к подключению принтеров пользователям: вариантам затейливым и не очень.


Подключаем принтеры при входе


Использование логон-скриптов ? это старое и проверенное средство, работает всегда и везде. При входе пользователя в систему срабатывает скрипт, который подключает нужный принтер и устанавливает его по умолчанию ? все просто и стабильно. На cmd скрипт будет вида:


rundll32 printui.dll,PrintUIEntry /in /n\\servername\printername /y

Подробнее про работу команды cmd для работы с принтерами можно почитать в документации Microsoft.


Любителям vbs придется уже использовать объекты, и подключение принтера будет выглядеть так:


On Error Resume Next
Set WshNetwork = CreateObject("WScript.Network")
WshNetwork.AddWindowsPrinterConnection "\\servername\printername"
WshNetwork.SetDefaultPrinter "\\servername\printername"

Аналогичным образом задача решается на PowerShell:


$net = new-object -com wscript.network
$net.AddWindowsPrinterConnection("\\servername\printername")
$net.SetDefaultPrinter("\\servername\printername")

Почитать про возможности ком-интерфейса Wscript.Network можно в материале TechNet WshNetwork Object, а про управление принтерами при помощи PowerShell ? в разделе документации PowerShell Working with Printers.


Если непосредственно с подключением принтера все просто ? лишь бы драйвер стоял на компьютере, ? то выборочное подключение принтеров потребует архитектурной смекалки. Приведу пару вариантов, которые встречались на просторах админской деятельности.


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



Нужно больше групповых политик.


Вариант неплохой, но при добавлении нового принтера приходится создавать новую группу безопасности, новую групповую политику и новый скрипт для подключения. Конечно же, это можно автоматизировать не без помощи нашего материала «Погружение в шаблоны и приручение GPO Windows», но решение все равно выглядит далеко не самым изящным.


Другой вариант таков ? создается единый скрипт, который проверяет какой-либо атрибут пользователя или компьютера и в зависимости от него подключает нужный принтер. В качестве атрибута может выступать расположение, описание или вовсе членство в группе безопасности.


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


Под спойлером приведу вариант подобного скрипта на vbs.
Set WshShell = WScript.CreateObject("WScript.Shell") 
 Set objSysInfo = CreateObject("ADSystemInfo") 
 strComputer = "." 
 Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv") 
 strUserDN = objSysInfo.userName 
 Set UserObj = GetObject("LDAP://" & strUserDN) 

 'начинаем создавать массив групп безопасности текущего пользователя' 
 iGroup = 0 

 For Each GroupObj In UserObj.Groups 
     iGroup = iGroup + 1 
     Redim Preserve strArrayUserGroups(iGroup) 
     strArrayUserGroups(iGroup) = Replace(GroupObj.Name, "CN=", "") 
 Next 

 'начинаем проверку и подключение принтеров'
 For i = 1 To iGroup 
     AddPrintersByGroup strArrayUserGroups(i) 
 Next

Function AddPrintersByGroup (strGroup) 
  Set WshNetwork = CreateObject("WScript.Network")
  Select Case strGroup 

    Case "Add Printer HP2055BUH2" 
      WshNetwork.AddWindowsPrinterConnection "\\servername\HP2055BUH2"
      WshNetwork.SetDefaultPrinter "\\servername\HP2055BUH2"

    Case "Add Printer HP2055HR"
      WshNetwork.AddWindowsPrinterConnection "\\servername\HP2055HR"
      WshNetwork.SetDefaultPrinter "\\servername\HP2055HR"
...
   End Select
End Function 

Лучше политик для подключения принтеров могут быть только другие политики


С появлением Group Policy Preferences или предпочтений групповых политик стало возможным обходиться без скриптов вовсе. Действительно, подключение к принтерам можно настроить в разделе «Конфигурация пользователя ? Настройка ? Панель управления ? Принтеры».



Подключение к новому или старому принтеру.


При этом не обязательно настраивать политики по количеству принтеров в домене инструментом «Нацеливание» на вкладке «Общие параметры». По сути этот инструмент напоминает wmi-фильтры в групповой политике, только у него заранее создан готовый набор опций помимо фильтров.



Возможные варианты нацеливания.


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


При автоматизации добавления-изменения можно использовать тот факт, что сами настройки предпочтения групповых политик располагаются в папке групповой политики в подпапке Preference. В случае принтеров это будет xml-файл Printers.xml в подпапке Printers.



Физическое расположение настроек принтеров.


Если открыть его, можно увидеть, что структура xml достаточно проста:


<?xml version="1.0" encoding="utf-8"?>
<Printers clsid="{1F577D12-3D1B-471e-A1B7-060317597B9C}">
<SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="HP2055BUH2" status="HP2055BUH2" image="2" bypassErrors="1" changed="2018-03-21 13:47:25" uid="{9E6F08F9-1C6B-49EB-A985-25A722ADD9C1}">
<Properties action="U" comment="" path="\\servername\HP2055BUH2" location="" default="0" skipLocal="0" deleteAll="0" persistent="0" deleteMaps="0" port=""/>
<Filters>
<FilterGroup name="Domainname\Printer_Add_2055_Buh" localGroup="0" primaryGroup="0" userContext="1" sid="" not="0" bool="AND"/>
</Filters>
</SharedPrinter>
</Printers>

И при желании можно аккуратно добавлять\изменять параметры вручную или скриптами. Конечно же, изобретать велосипед и лезть немытыми руками в xml весело и занимательно, но совершенно не обязательно ? в галерее скриптов TechNet уже есть готовый скрипт Add-Printer-IN-GPO, который добавит принтеры к групповой политике с нацеливанием на группы безопасности.


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


В копилку странных способов подключения ? назначенные задания


От заказчика поступила задача ? создать инструмент для автоматического подключения принтеров пользователю. При этом время реакции должно быть минимально и никакие перелогины недопустимы, поэтому классические варианты вроде логон-скриптов и групповых политик сразу отмели.


Нюанс был и в том, что пользователи работали на терминальных серверах в ферме и без фермы. Голь на выдумки хитра, поэтому мне пришлось вспомнить возможные варианты запуска команд на удаленном компьютере под разными сессиями ? часть вариантов описана в нашей статье «1000++ способ запуска команд на удаленном компьютере». Лучшим оказался вариант с назначенными заданиями.


Поскольку я люблю батники и использую их, когда можно обойтись без применения PowerShell, то для решения задачи я использовал исключительно cmd.


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


schtasks /create /S computername /SC ONCE /ST 00:00 /RU domain\username /TN taskname /tr "rundll32 printui.dll,PrintUIEntry /in /nPrintername" 

Второй проблемой было найти компьютер, на котором пользователь работает в момент обращения. Я использовал утилиту qwinsta и список возможных компьютеров в текстовом файле. Разумеется, есть и другие способы ? например, брать имя компьютера из атрибута Active Directory или из текстового файла. Но эта процедура потребует дополнительных Logon-скриптов. В качестве примера реализации могу посоветовать материал How to: Show User's Logged On Computer Name In Active Directory.


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


Полный листинг скрипта под спойлером.
@echo off 
rem На каждом сервере из списка...
for /F  %%i in (servers.txt) do ( 
rem Ищем нужного пользователя
qwinsta /SERVER %%i | find "%1" && call :subroutine %%i %1 %2 
) 

GOTO :EOF 
:subroutine 
rem Cоздаем назначенное задание
schtasks /create /S %1 /SC ONCE /ST 00:00 /RU domain\%2 /TN printer_%2 /tr "rundll32 printui.dll,PrintUIEntry /in /n%3" 
rem Запускаем задание
schtasks /run /S %1 /TN printer_%2 
rem Удаляем задание
schtasks /delete /S %1 /TN printer_%2 /F 

GOTO :EOF 

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


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

Комментарии (21)


  1. journeym
    27.03.2018 23:39

    Что-то сложно. Какие-то логон скрипты, куча политик.
    Одна политика, в ней куча entry в preference / printers, c фильтрами по группам AD с названиями кабинетов + принт сервер с проинсталеными сетевыми принтерами. Профит. Никаких логин скриптов и другой дряни, все нативно чудесно пашет. Если не пашет — причина в 90% случаев в драйвере / политике системы, и логон скрипт не спасет.


  1. Naves
    27.03.2018 23:39

    Ситуация: пользователи работают на терминальном сервере с разных рабочих мест в разное время. С утра юзер сидел на втором этаже, а после обеда на третьем этаже. Сессии на сервере не завершаются, просто отключаются, из-за этого logon-скрипты не работают.
    Пробовал через Планировщик добавить задание с триггерами «при подключении к сеансу» и «при входе в систему», но задание запускается не от имени подключенного пользователя.
    В гугле ничего конкретного не нашел, как повесить определенный скрипт на событие подключения пользователя.
    Из вариантов в цикле смотреть лог событий, но и тогда задание запускается не в сеансе пользователя.


    1. avelor
      28.03.2018 00:13

      Ну можно в цикле смотреть лог событий, и при появлении соьытия входа вытаскивать оттуда имя пользователя и создавать назначенное задание а-ля как в статье…
      А как вы определяете с какого этажа зашёл пользователь? Не проще ли подключать принтеры к рабочим станциям, а на терминальник тупо их «прокидывать» средствами rdp?


      1. Naves
        28.03.2018 09:00

        Переменная окружения %clientname%
        Принтеры сетевые, иногда вообще стоят в коридоре, тонкие клиенты raspberry
        Как вариант, в задании планировщика, которое срабатывает по триггеру подключения, запускать батник, как в статье, который будет создавать и запускать задание от имени пользователя, но в этот скрипт нужно ещё как-то передать параметры, кто подключился и откуда.
        Видимо остаётся только парсинг событий с созданием и запуском заданий пользователю.


        1. avelor
          28.03.2018 09:11

          Есть всегда варианты.
          Например как уже предложили — завершать сессии принудительно (или научить завершать сессии).
          Альтернативно — научить сотрудников подключать себе нужный принтер самим — руками или запуском «вот этого ярлычка».
          И совсем альтернативно — логон-скрипт держать в памяти в бесконечном цикле, проверять переменную среды — и если что переподключать принтер


          1. Naves
            28.03.2018 09:26

            Некоторые пользователи умеют переключать принтеры, но есть определенная текучка персонала, которые необучаемы, так как инструкции не читают от слова совсем. Повезёт, если научатся по телефону в техподдержку звонить вместо того, чтобы ножками придти.


            1. journeym
              28.03.2018 12:18

              Как насчет фильтра Terminal Session Client/IP в GPO Preferences на принтере? В зависимости от клиента получите принтер.
              Scheduled tasks — это рак, не надо их использвать.
              Group Policy refresh interval лучше уменьшить.
              msdn.microsoft.com/en-us/library/ms812018.aspx


    1. sbh
      28.03.2018 07:34

      В настройках терминального сервера сделайте завершение сеанса при простое n-ое количество минут.


      1. Naves
        28.03.2018 09:10

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


        1. sbh
          29.03.2018 01:51

          Не может такого быть как я вышла покурить. Например можно настроить отключение сессии через 6 часов простоя. Если человек отходит покурить на 6 часов, может ему пора увольняться и искать новую работу?


          1. Naves
            29.03.2018 09:53

            С утра юзер сидел на втором этаже, а после обеда на третьем этаже.

            Один пользователь может несколько раз менять своё рабочее место за день. Бизнес-процесс такой.
            И давайте не будем обсуждать, кого можно и нужно увольнять. У всех в резюме написано «опытный пользователь пк интернет»


  1. PbIXTOP
    28.03.2018 03:43

    Поскольку чаще всего принтер привязывается к местоположению компьютера, а не пользователя, то использую подключение к сетевым принтерам через DNS имена с коротким временем жизни записи. При смене принтера или его поломки достаточно просто переписать имя на сервере не ходя к пользователям.
    Из минусов — приходится использовать однородный парк принтеров. Хотя тестировал чей-то универсальный драйвер, кажется это был xerox, печать на kyocera и hp прошла без проблем с поддержкой духсторонней печати.


  1. sbh
    28.03.2018 07:32

    Непонятно для чего такие скрипты хитрые.
    Вполне достаточно GP правильно настроенной.


  1. l0ser140
    28.03.2018 09:34

    А как быть с возможностью сканировать (на МФУ) в таком случае?


    1. avelor
      28.03.2018 11:29

      мы клиентам как правило советуем МФУ с поддержкой сканирования в папку\почту\фтп.
      дальше сотрудники подходят к МФУ, выбирают в адресной книге куда сканировать — и сканируют.
      вот если у вас какая-то софтина в которую нужно сканировать через twain\wia — тут уже начинаются головняки.


  1. bombardier
    28.03.2018 10:00

    У нас тот самый сферически-вакуумный энтерпрайз. Система управления печатью. В схеме AD добавлены атрибуты к пользователям для магнитной полосы и MIFARE чипа с пропуска, Печать идет на виртуальный принтер, а пользователи уже подходят к любому удобному принтеру на территории кампуса и печатают. Задания хранятся неделю на сервере в случае если их распечатали, так что печать всегда можно повторить и 3 дня, если печатать не стали (например передумали, такое тоже бывает. после внедрения системы объем снизился примерно на миллион листов А4 в год). Сканирование и копирование так же, с любого MFU в здании, главное чтобы железка имела FIH интерфейс для сопряжения с терминалом. Если кому интересно — подробнее опишу


    1. Fanta
      28.03.2018 11:23

      +1
      юзаем связку Xerox + SafeQ


      1. bombardier
        28.03.2018 12:12

        У нас связка HP + SafeQ ) сервис у хапешников сильно продвинутее )


  1. qwertEHOK
    28.03.2018 11:29

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

    тут не надо быть продвинутым — создаете DFS папку со ссылками на принтеры, причем с правильно названными ссылками. Кабинет 1111 и Кабинет 1111 (цветной). И все.

    Если может кто — подскажите как собирать инфу по SNMP с принтеров. А точнее где брать OID которые не знаешь. Вот например на веб-странице МФУ есть серийник картриджа — хочу получить его через SNMP, но не могу найти UID(


    1. Tabletko
      28.03.2018 15:35

      OID узнавать у производителя железки или опытным путём выяснять через snmpwalk | grep


    1. I_Rusakov
      29.03.2018 09:59

      Я иногда пользуюсь MIB Browser.