Добавление сетевых принтеров через Powershell

Вопрос или проблема

Итак, я пытаюсь добавить принтеры, используя PowerShell. Перед этим я рассматривал возможность использования групповых политик для развертывания принтеров, но постоянно сталкивался с ошибками. Мой предшественник создал скрипт на VBS для развертывания принтеров, но я в процессе их преобразования во все в PowerShell. Сначала я использовал командлет Add-Printer с параметром -ConnectionName. Это сработало сначала, но после нескольких попыток я снова получал ошибки, в которых говорилось, что принтер недоступен. Затем я подумал о COM-объектах, и это работает идеально. Однако я столкнулся с одной проблемой. Если принтеры уже добавлены, они просто исчезают, и затем я получаю ошибку “Значение не попадает в ожидаемый диапазон.”

Скрипт вызывается через вход в GPO. Причина, по которой я развертываю их таким образом, заключается в том, что все профили пользователей очищаются (с использованием объектов WMI), и каждая сессия входа должна быть новой для пользователя. Кроме того, у них нет административных привилегий. Тем не менее, у них есть доступ к серверу печати, и они могут добавлять принтеры. Я знаю это, потому что могу вручную запустить скрипт в контексте пользователя, и он выполняется нормально. Я также вижу, как принтеры добавляются, если их там еще нет. Просто если пользователь выходит из системы, а затем снова входит, принтеры присутствуют, но затем исчезают один за другим, хотя профиль создается в первый раз каждый раз. Поэтому я подумал, что мог бы удалить все принтеры (кроме принтера Microsoft PDF), но это тоже, похоже, не работает.

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

Start-Transcript -Path C:\Temp\PowerShellLog.txt

$printers = Get-Printer
Get-Printer | Where-Object Name -NotLike "*PDF*" | Remove-Printer

$var = New-Object -COM WScript.Network 
Start-Sleep -Seconds 5
if ($printers.name -notcontains "\\printerserver.company.com\LAB A P1") { $var.AddWindowsPrinterConnection("\\printerserver.company.com\LAB A P1") }
Start-Sleep -Seconds 5
if ($printers.name -notcontains "\\printerserver.company.com\LAB A P2") { $var.AddWindowsPrinterConnection("\\printerserver.company.com\LAB A P2") }
Start-Sleep -Seconds 5
if ($printers.name -notcontains "\\printerserver.company.com\LAB A Duplex") { $var.AddWindowsPrinterConnection("\\printerserver.company.com\LAB A Duplex") }
Start-Sleep -Seconds 5
if ($printers.name -notcontains "\\printerserver.company.com\LAB A Color") { $var.AddWindowsPrinterConnection("\\printerserver.company.com\LAB A Color") }

#Устанавливает принтер по умолчанию
$var.setdefaultprinter("\\printerserver.company.com\LAB A P1")

Вот ошибка, которую я получаю, если принтер уже установлен (но затем исчезает):

 Значение не попадает в ожидаемый диапазон. В
\\server\Hidden$\printer.ps1:12 символ:87
+ ...  Duplex") { $var.AddWindowsPrinterConnection("\\printerserver ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     + CategoryInfo          : OperationStopped: (:) [], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException

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

При этом у меня есть скрипт выхода, чтобы очистить корзину, так как это тоже в пространстве пользователя. Сразу под этим я добавил Get-WmiObject -Class Win32_Printer | Where-Object { $_.Network -eq 'true' } | ForEach-Object { $_.delete() }, который должен очищать сетевые принтеры во время выхода. Что касается скрипта, COM-объекты бы работали, но я подумал, что использование объектов WMI будет так же эффективно. Вот скрипт для добавления принтеров при входе в систему. Надеюсь, это поможет кому-то другому в будущем.

$printclass = [wmiclass]"win32_printer"
$printclass.AddPrinterConnection("\\printerserver.company.com\LAB A P1")
$printclass.AddPrinterConnection("\\printerserver.company.com\LAB A P2")
$printclass.AddPrinterConnection("\\printerserver.company.com\LAB A Color")
$printclass.AddPrinterConnection("\\printerserver.company.com\LAB A Duplex")

#Устанавливает принтер по умолчанию
$P1Printer = Get-WmiObject -Class Win32_Printer | Where-Object { $_.Network -eq 'true' -and $_.Name -like "*LAB A P1*" }
$P1Printer.SetDefaultPrinter()

Ответ или решение

Добавление сетевых принтеров с использованием PowerShell: полное руководство

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

Проблема и контекст

Как было упомянуто, ваш предыдущий подход с использованием скрипта на Visual Basic (VBS) вызывал сложности, и вы решили заменить его на PowerShell. Ваш сценарий, запускаемый через GPO (Group Policy Object) при входе в систему пользователя, имел успех при первом запуске, однако возникли ошибки при повторных входах в систему, когда ранее добавленные принтеры исчезали.

Ключевые проблемы, с которыми вы столкнулись:

  1. Ошибка доступа к принтеру: Появляется сообщение о том, что принтер недоступен после нескольких попыток добавления.
  2. Принтеры исчезают при повторном входе в систему: Принтеры, установленные во время предыдущего сеанса, исчезают, что вызывает путаницу.
  3. Конфликт в профилях пользователей: Очищение профилей пользователей может приводить к конфликту при добавлении принтеров.

Решение проблемы

Вместо использования COM объектов, рекомендуется использовать WMI (Windows Management Instrumentation) для добавления принтеров, что даст возможность более эффективно управлять сетевыми принтерами. Данный подход также поможет избежать некоторых ошибок, связанных с неверными параметрами, как Value does not fall within the expected range.

Вот улучшенная версия вашего скрипта для добавления принтеров:

$printclass = [wmiclass]"win32_printer"

# Добавляем принтеры
$printersToAdd = @(
    "\\printerserver.company.com\LAB A P1",
    "\\printerserver.company.com\LAB A P2",
    "\\printerserver.company.com\LAB A Color",
    "\\printerserver.company.com\LAB A Duplex"
)

foreach ($printer in $printersToAdd) {
    $existingPrinter = Get-WmiObject -Class Win32_Printer | Where-Object { $_.PortName -eq $printer }

    if (-not $existingPrinter) {
        $printclass.AddPrinterConnection($printer)
    }
}

# Установка принтера по умолчанию
$P1Printer = Get-WmiObject -Class Win32_Printer | Where-Object { $_.Name -like "*LAB A P1*" }
if ($P1Printer) {
    $P1Printer.SetDefaultPrinter()
}

Очистка принтеров при выходе

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

Get-WmiObject -Class Win32_Printer | Where-Object { $_.Network -eq 'true' } | ForEach-Object { $_.Delete() }

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

Заключение

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

Применяйте данные решения в своей практике и повышайте эффективность вашей работы с Active Directory и принтерами.

Оцените материал
Добавить комментарий

Капча загружается...