Pull to refresh

Информатизация вуза. Удаленная установка принтеров на rdsh с помощью Powershell

Level of difficultyMedium
Reading time6 min
Views3.6K

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

Итак начнем. Задача, которую пытались решить — это установка принтеров на терминальные серверы (нынче серверы узла сеансов) фермы. Было несколько путей:

  • установка с помощью групповых политик

  • установка скриптом

  • установка вручную

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

Выбрал установку на компьютер, потому что AD, которое мне досталось по сути не имело структуры — все пользователи размещались в одном OU. Чтобы навести порядок в AD и распределить пользователей на OU, которые соответствуют либо структуре здания либо штатному расписанию потребуется много времени.

В результате использования GPO выявил следующие нюансы:

  • драйверы принтеров не устанавливаются автоматически или это происходит долго;

  • даже если установить драйверы принтера на rdsh, то установка принтера через gpo происходит только после перезагрузки сервера;

  • после входа пользователя на сервер — список принтеров пуст примерно минут пять бывает больше;

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

  • При удалении принтера из групповой политики принтер частенько не удаляется сразу, даже после gpupdate force.

Самое критичное — это установка принтера только после перезагрузки — довольно неприятная ситуация, когда необходимо выкинуть с терминала 50 пользователей. Поэтому начал смотреть в сторону скрипта на Powershell.

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

Удаленная установка принтера
Удаленная установка принтера

В результате сбора информации нашел хорошую статью про PrintBRM - Отказоустойчивый сервер печати на базе Windows, благодарю автора - информация была полезна. Испытал, метод рабочий, но хотелось больше контроля над алгоритмом установки, поэтому использовал Powershell.

Алгоритм скрипта
Алгоритм скрипта

Сам скрипт:

$driversFile= "\\storage\printDrivers\drivers.txt"
$printersFile= "\\storage\printDrivers\printers.txt"
$ACLfolder = "\\storage\printDrivers\acl\"
$csvfile= "\\storage\printDrivers\printers.csv"
$folderDrivers= "\\storage\printDrivers\drivers\"
$terminals = @("tspd-01", "tspd-02", "its-01", "its-02")


$exportFlag=0
#удаляем файл списка названий драйверов
if(Test-Path $ACLfolder){Remove-Item -Path $ACLfolder -Recurse}
if(Test-Path $driversFile){Remove-Item -Path $driversFile}
if(Test-Path $printersFile){Remove-Item -Path $printersFile}
if(Test-Path $csvfile){Remove-Item -Path $csvfile}

Start-Sleep -Seconds 5
#формируем список названий драйверов
$drivers=Get-PrinterDriver | select Name | where {$_.Name -notlike "*Microsoft*" -and  $_.Name -notlike "Remote*"}
foreach ($driver in $drivers) {
write $driver.Name | out-file $driversFile -Append
}

#формируем список принтеров
$printers = get-printer | where {$_.Name -notlike "*Microsoft*" -and  $_.Name -notlike "Remote*"}
#создаем директорию для ACL
Mkdir $ACLfolder
foreach($printer in $printers){
Write $printer.Name | out-file $printersFile -Append
#экспортируем ACL принтера в текстовый файл
$aclfile=$ACLfolder+$printer.Name+".txt"
(Get-Printer $printer.Name -Full).PermissionSDDL | Out-File $aclfile
}

#формируем csv файл с информацией о принтере
get-printer | where {$_.Name -notlike "*Microsoft*" -and  $_.Name -notlike "Remote*"} |Export-CSV $csvfile -NoTypeInformation -Encoding UTF8


#функция экспорта драйверов
function ExportDrivers($folderDrivers){
    #очищаем папку с драйверами
    if(Test-Path $folderDrivers){Remove-Item -Path $folderDrivers -Recurse}
    #получаем список драйверов принтеров
    $PrintDriver = Get-WindowsDriver -Online | where {($_.ClassName -like "Printer")}
    foreach ($print in $PrintDriver){
        write $print
        #Записываем название драйверов НЕ от микрософта
        if($print.ProviderName -ne "Microsoft"){
            #Создаем имя папки
            $folderName=($folderDrivers + $print.Driver).replace('.inf','')
            write $folderName
            #Создаем папку
            Mkdir $folderName
            #экспортируем драйвера принтеров в папку
            pnputil.exe /export-driver $print.Driver $folderName
        }
    }
}

#Запуск экспорта
if($exportFlag -eq 1){ExportDrivers -folderDrivers $folderDrivers}


Write "_____________________"
$pass = "Morkovka10"
$us="Domain\mylogin"
$password = ConvertTo-SecureString -String $pass -AsPlainText -Force
$cred= New-Object System.Management.Automation.PSCredential ($us, $password )
#Запуск удаленной сесии
foreach($server in $terminals){
$s = New-PSSession -computerName $server -authentication CredSSP -credential $cred
Invoke-Command -Session $s -Scriptblock {
             #проброс перемнных в сессию
             $csvfile=$using:csvfile 
             $ACLfolder= $using:ACLfolder
             $folderDrivers=$using:folderDrivers
             $driversFile=$using:driversFile
             $h = hostname
             write "____________________________________ $h ________________________________________________________________________"

             #устанавливаем драйвера в хранилище драйверов
             write "install drivers!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
             $folderDrivers=$folderDrivers+"*.inf"
             pnputil.exe /add-driver $folderDrivers /subdirs /install
             write "install drivers!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
             
             #добавляем отсутствующие драйвера 
             write "_______________________________"
             Write "добавляем отсутствующие драйвера принтеров из хранилища драйверов"
             $drivers = Get-Content -Path $driversFile 
             foreach ($driver in $drivers){
               if((Get-PrinterDriver -Name $driver).Count -eq 0){
                Add-PrinterDriver -Name $driver
               }
             }
               write "_______________________________"


             #Получаем массив объектов - список принтеров на принтсервере из csv
             $printers = $printers =Import-CSV -Path $csvfile

             #Получаем массив локальных принтеров
             $localPrinters = get-printer -Full | where {$_.Name -notlike "*Microsoft*" -and  $_.Name -notlike "Remote*"}

             #удаляем локальные принтеры которых нет на принтсервере

             foreach ($localP in $localPrinters){
                 $match = $printers -match $localP.Name
                 if($match.Count -eq 0){
                     $pname=$localP.Name
                     write "REMOVE $pname - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
                     Remove-Printer -Name $localP.Name
                 }
             }

             Foreach($p in $printers){
                write $p.Name
                write $p.DriverName
                write $p.PortName 
                $aclfile=$ACLfolder+$p.Name+".txt"
                $perms = Get-Content -Path $aclfile
                if((Get-Printer -Name $p.Name).Count -ne 0){
                #синхронизируем ACL
                Set-Printer $p.Name -PermissionSDDL $perms 
                
                #Получаем локальный принтер 
                $localprinter= Get-Printer -Name $p.Name
                
                #Проверяем порт
                if($localprinter.PortName -ne $p.PortName){
                    write "порт НЕ совпадает"
                    #Добавляем порт если его нет
                    if((Get-PrinterPort -Name $p.PortName).Count -eq 0){
                     Add-PrinterPort -Name $p.PortName -PrinterHostAddress $p.PortName
                    }
                    #Добавляем порт принтеру
                    Set-Printer -Name $p.Name -PortName $p.PortName
                }else{write "порт совпадает"}
                #Проверяем драйвер
                if($localprinter.DriverName -ne $p.DriverName){
                 Set-Printer -Name $p.Name -DriverName $p.DriverName
                }
                } else {
                    
                    #Добавляем порт
                    if((Get-PrinterPort -Name $p.Name).Count -eq 0){
                     Add-PrinterPort -Name $p.PortName -PrinterHostAddress $p.PortName
                    }
                    #Добавляем принтер
                    Add-Printer -Name $p.Name -DriverName $p.DriverName -PortName $p.PortName
                    #Добавляем ACL
                    Set-Printer $p.Name -PermissionSDDL $perms
                }
             }
             }
}
             
             

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

В результате мы получили:

  • удаленную установку принтеров на терминальные серверы без необходимости их перезагрузки;

  • единый сервер администрирования печати — сервер‑печати, который является эталонным — именно с него копируются все настройки устанавливаемых принтеров;

  • простой метод развертывания принтеров, поэтому его можно передать специалистам службы поддержки — установил принтер на сервер печати, настроил права и затем запустил скрипт — все просто!

  • Сервер печати — занимает мало места (в виде ВМ), поэтому можно быстро и легко его бекапить каждый день, поэтому не страшно, если техподдержка начудит — его быстро можно восстановить.

Задачка решена, способ конечно немного велосипедоизобретательный, но рабочий. Жду Ваших комментарий, делитесь опытом! Всем Добра!

Only registered users can participate in poll. Log in, please.
Как организована установка принтеров в вашей организации?
60.71% вручную17
25% gpo7
7.14% gpp2
17.86% скрипт5
7.14% стороннее ПО2
28 users voted. 4 users abstained.
Tags:
Hubs:
Total votes 5: ↑5 and ↓0+5
Comments12

Articles