Лучший отвечающий
Создание и удаление подключения к сетевому принтеру (VBS)

Вопрос
-
В некотором домене на некотором сервере жил да был принтер. И решил великий директор заменить этот принтер на новый. И кинул он клич немалый: "Ой вы админы мои дорогие, замените у пользователей старую очередь печати на новую!" И поручили эту работу младшему админу. Он заглянул в Script Center Gallery и написал скриптик.
А теперь сказка заканчивается и начинается горькая правда.
При тестировании выяснилось, что скрипт замечательно отрабатывает, если у пользователя есть права админа. Если же таких прав нет, то ничего не происходит. При этом пользователь может самостоятельно подключить себе принтер просто набрав в адресной строке проводника \\server\printername.
Собственно вопрос: как сделать так, чтобы этот скрипт работал у всех пользователей? Предполагается навешивать его через ГП как logon script.
Текст скрипта:
-----
'============================== '=== Replace printer '=== Ver.1 '=== Language: VBScript (.vbs) '============================== on error resume next '########## printer configuration ########## OldPrnName = "\\server\printershare" NewPrnName = "\\server\printershare" '############################## PrnIsInstalled = false PrnIsDefault = false set WmiService = GetObject("winmgmts:{impersonationlevel=impersonate}!\\.\root\cimv2") set WshNetwork = CreateObject("wscript.network") '##### получаем версию ОС set ColOs = WmiService.ExecQuery("select * from win32_operatingsystem") for each ObjOs in ColOs OsVersion = ObjOs.Version next '##### если ОС не XP и не Vista, скрипт завершает работу if not (OsVersion = "5.1.2600" or OsVersion = "6.0.6000") then wscript.quit end if '##### получаем список сетевых принтеров и выставляем флаги set ColPrinters = WmiService.ExecQuery("select * from win32_printer where network = true") for each ObjPrinter in ColPrinters if ObjPrinter.Name = OldPrnName then PrnIsInstalled = true if ObjPrinter.Default then PrnIsDefault = true end if end if next '##### если старый принтер был установлен, добавляем новый и удаляем старый '##### если старый принтер был по умолчанию, делаем новый по умолчанию if PrnIsInstalled then WshNetwork.AddWindowsPrinterConnection NewPrnName if PrnIsDefault then WshNetwork.SetDefaultPrinter NewPrnName end if WshNetwork.RemovePrinterConnection OldPrnName end if wscript.quit
MCP | scriptoholic | PowerShell | SCCM 2007 | SMS 2003- Изменено Алекс Пашковский 29 сентября 2009 г. 8:48
8 сентября 2009 г. 12:28
Ответы
-
Переписал скрипт используя только методы WMI. Работает без прав админа.
-----
'============================== '=== Replace printer '=== Ver.2 '=== Language: VBScript (.vbs) '============================== on error resume next '########## printer configuration ########## OldPrnName = "\\server\printershare" NewPrnName = "\\server\printershare" '############################## PrnIsInstalled = false PrnIsDefault = false set WmiService = GetObject("winmgmts:{impersonationlevel=impersonate,(loaddriver)}!\\.\root\cimv2") set WmiPrinterClass = WmiService.Get("win32_printer") '=== получаем версию ОС set ColOs = WmiService.ExecQuery("select * from win32_operatingsystem") for each ObjOs in ColOs OsVersion = ObjOs.Version next '=== если ОС не XP и не Vista, скрипт завершает работу if not (OsVersion = "5.1.2600" or OsVersion = "6.0.6000") then Wscript.Quit end if '=== получаем список сетевых принтеров и выставляем флаги set ColPrinters = WmiService.ExecQuery("select * from win32_printer where network = true") for each ObjPrinter in ColPrinters if ObjPrinter.Name = OldPrnName then PrnIsInstalled = true if ObjPrinter.Default then PrnIsDefault = true end if end if next '=== если старый принтер был установлен, добавляем новый и удаляем старый '=== если старый принтер был по умолчанию, делаем новый по умолчанию if PrnIsInstalled then Result = WmiPrinterClass.AddPrinterConnection(NewPrnName) if not Result = 0 then Wscript.Quit 1 end if if PrnIsDefault then NewPrnName = Replace(NewPrnName,"\","\\") set ColPrinters = WmiService.ExecQuery("select * from win32_printer where name = '" & NewPrnName & "'") for each ObjPrinter in ColPrinters ObjPrinter.SetDefaultPrinter() next end if OldPrnName = Replace(OldPrnName,"\","\\") set ColPrinters = WmiService.ExecQuery("select * from win32_printer where name = '" & OldPrnName & "'") for each ObjPrinter in ColPrinters ObjPrinter.Delete_ next end if Wscript.Quit
MCP | scriptoholic | PowerShell | SCCM 2007 | SMS 2003- Помечено в качестве ответа ILYA [ sie ] SazonovModerator 25 сентября 2009 г. 10:45
25 сентября 2009 г. 9:24
Все ответы
-
Скажите, а чем вам GPP не подходит? там как раз есть все необходимое для решения данной задачи
Так же вы наверно просто пробуете под юзверем его запустить? Если так то когда он будет через GPO работать у него будут повышенные привилегии достаточные для поставленной задачи.9 сентября 2009 г. 11:05 -
По видимому, нет прав на
WshNetwork.AddWindowsPrinterConnection
Почему, почему - пока не понял....
WshNetwork.RemovePrinterConnection OldPrnName
А чем не нравится вариант с prnmngr от MS?
prnmngr -d -p "\\server\pr-share-01"
prnmngr -ac -p "\\server\pr-share-02"
или с net use:
net use \\server\pr-share-01 /delete
net use \\server\pr-share-02
та же задача - но решается проше. С правами пользователя - работает....
Если ответ Вам помог, нажмите на изображение зеленой галочки - «пометить как ответ». Если ответ был для Вас полезен, Вы можете пометить это сообщение как «полезное», нажав на ссылку "проголосовать за полезное сообщение" в правом верхнем углу сообщения.9 сентября 2009 г. 11:11 -
Насколько я понял GPP есть начиная с 2008 сервера, а у нас 2003.
Тестировалось просто запуском скрипта под пользователем без прав админа. Вопрос как раз в том и состоит, будут ли у пользователя достаточные права, если этот скрипт будет запускаться через GPO? Если да, то отлично.
То, что у простого пользователя не хватает прав для использования объекта WshNetwork я как раз догадался, а вот про prnmngr - это вы мне хорошо напомнили. Я про него совсем забыл, а ведь это просто vbs скрипт, поэтому я его просмотрел и выяснил, что в нём все операции производятся через WMI.
Как удалять или делать дефолтным принтер используя WMI я и раньше знал. Но я нигде не мог найти, как создавать соединение с принтером. Именно поэтому пришлось использовать WshNetwork. Завтра перепишу скрипт используя только WMI.
MCP | scriptoholic | PowerShell | SCCM 2007 | SMS 20039 сентября 2009 г. 16:11 -
GPP есть и на 2003 для этого надо установить обновление KB943729 на сервер и на клиентов. А дальше открыть политику с vista/2008/windows 7 и будет доступно GPP :)
Скрипт из GPO выполняется с повышенными привилегиями на сколько я знаю чуть ли не под админом. Хотя я могу путать.10 сентября 2009 г. 7:44 -
Уж если в скрипте используете on error resume next, то хорошо было бы анализировать возможные ошибки хотя бы таким бы обазом:
WshNetwork.AddWindowsPrinterConnection NewPrnName
If Err.Number <> 0 Then
WScript.Echo "Ошибка !!!" & Err.Description
WScript.Quit(1)
End If
Может и увидите в чем проблема. Кстати, на этапе отладки on error resume next лучше отключать.
PS: я обычно подобные скрипты снабжаю возможностью писать в небольшой лог-файл, чтобы знать где в случае чего собака зарыта.
Andrew Mishechkin10 сентября 2009 г. 10:50 -
GPP есть и на 2003 для этого надо установить обновление KB943729 на сервер и на клиентов. А дальше открыть политику с vista/2008/windows 7 и будет доступно GPP :)
Скрипт из GPO выполняется с повышенными привилегиями на сколько я знаю чуть ли не под админом. Хотя я могу путать.
GPP создается в двух разделах: Computer и User - соответственно контекст исполнения будет тот или иной.
Сазонов Илья http://www.itcommunity.ru/blogs/sie-wl/11 сентября 2009 г. 5:35Модератор -
Переписал скрипт используя только методы WMI. Работает без прав админа.
-----
'============================== '=== Replace printer '=== Ver.2 '=== Language: VBScript (.vbs) '============================== on error resume next '########## printer configuration ########## OldPrnName = "\\server\printershare" NewPrnName = "\\server\printershare" '############################## PrnIsInstalled = false PrnIsDefault = false set WmiService = GetObject("winmgmts:{impersonationlevel=impersonate,(loaddriver)}!\\.\root\cimv2") set WmiPrinterClass = WmiService.Get("win32_printer") '=== получаем версию ОС set ColOs = WmiService.ExecQuery("select * from win32_operatingsystem") for each ObjOs in ColOs OsVersion = ObjOs.Version next '=== если ОС не XP и не Vista, скрипт завершает работу if not (OsVersion = "5.1.2600" or OsVersion = "6.0.6000") then Wscript.Quit end if '=== получаем список сетевых принтеров и выставляем флаги set ColPrinters = WmiService.ExecQuery("select * from win32_printer where network = true") for each ObjPrinter in ColPrinters if ObjPrinter.Name = OldPrnName then PrnIsInstalled = true if ObjPrinter.Default then PrnIsDefault = true end if end if next '=== если старый принтер был установлен, добавляем новый и удаляем старый '=== если старый принтер был по умолчанию, делаем новый по умолчанию if PrnIsInstalled then Result = WmiPrinterClass.AddPrinterConnection(NewPrnName) if not Result = 0 then Wscript.Quit 1 end if if PrnIsDefault then NewPrnName = Replace(NewPrnName,"\","\\") set ColPrinters = WmiService.ExecQuery("select * from win32_printer where name = '" & NewPrnName & "'") for each ObjPrinter in ColPrinters ObjPrinter.SetDefaultPrinter() next end if OldPrnName = Replace(OldPrnName,"\","\\") set ColPrinters = WmiService.ExecQuery("select * from win32_printer where name = '" & OldPrnName & "'") for each ObjPrinter in ColPrinters ObjPrinter.Delete_ next end if Wscript.Quit
MCP | scriptoholic | PowerShell | SCCM 2007 | SMS 2003- Помечено в качестве ответа ILYA [ sie ] SazonovModerator 25 сентября 2009 г. 10:45
25 сентября 2009 г. 9:24