Solved

Powershell to Install Network Printer

Posted on 2014-11-05
14
604 Views
Last Modified: 2014-11-07
Found this Powersell script on the internet for installing printers.  I'm running Powershell version 3 on Windows7 x64.   I get the attached error when attempting to run.  I thought it had something to do with the 64bit driver so I pointed the UNC path to the x64 directory, same error.  I also pointed the script to a local directory containing drivers, still same error.

####################################################
# Change these values to the appropriate values in your environment

$PrinterIP = "172.29.15.10"
$PrinterPort = "9100"
$PrinterPortName = "IP_" + $PrinterIP
$DriverName = "Lexmark 654de"
$DriverPath = "\\UNC Path\apps\Printers\Lexmark\654de\Admin\drivers\Print\Win_2kXP"
$DriverInf = "\\UNC Path\apps\Printers\Lexmark\654de\Admin\drivers\Print\Win_2kXP\LMACM540.inf"
$PrinterCaption = "Lexmark 654de"
####################################################

### ComputerList Option 1 ###
$ComputerList = @("ISH3LP")

### ComputerList Option 2 ###
# $ComputerList = @()
# Import-Csv "C:\Temp\ComputersThatNeedPrinters.csv" | `
# % {$ComputerList += $_.Computer}

Function CreatePrinterPort {
param ($PrinterIP, $PrinterPort, $PrinterPortName, $ComputerName)
$wmi = [wmiclass]"\\$ComputerName\root\cimv2:win32_tcpipPrinterPort"
$wmi.psbase.scope.options.enablePrivileges = $true
$Port = $wmi.createInstance()
$Port.name = $PrinterPortName
$Port.hostAddress = $PrinterIP
$Port.portNumber = $PrinterPort
$Port.SNMPEnabled = $false
$Port.Protocol = 1
$Port.put()
}

Function InstallPrinterDriver {
Param ($DriverName, $DriverPath, $DriverInf, $ComputerName)
$wmi = [wmiclass]"\\$ComputerName\Root\cimv2:Win32_PrinterDriver"
$wmi.psbase.scope.options.enablePrivileges = $true
$wmi.psbase.Scope.Options.Impersonation = `
[System.Management.ImpersonationLevel]::Impersonate
$Driver = $wmi.CreateInstance()
$Driver.Name = $DriverName
$Driver.DriverPath = $DriverPath
$Driver.InfName = $DriverInf
$wmi.AddPrinterDriver($Driver)
$wmi.Put()
}

Function CreatePrinter {
param ($PrinterCaption, $PrinterPortName, $DriverName, $ComputerName)
$wmi = ([WMIClass]"\\$ComputerName\Root\cimv2:Win32_Printer")
$Printer = $wmi.CreateInstance()
$Printer.Caption = $PrinterCaption
$Printer.DriverName = $DriverName
$Printer.PortName = $PrinterPortName
$Printer.DeviceID = $PrinterCaption
$Printer.Put()
}

foreach ($computer in $ComputerList) {
CreatePrinterPort -PrinterIP $PrinterIP -PrinterPort $PrinterPort `
-PrinterPortName $PrinterPortName -ComputerName $computer
InstallPrinterDriver -DriverName $DriverName -DriverPath `
$DriverPath -DriverInf $DriverInf -ComputerName $computer
CreatePrinter -PrinterPortName $PrinterPortName -DriverName `
$DriverName -PrinterCaption $PrinterCaption -ComputerName $computer
}

Powershell-Error.JPG
0
Comment
Question by:ats2012
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 7
14 Comments
 
LVL 16

Expert Comment

by:Joshua Grantom
ID: 40426652
You are running this script with administrative privileges correct?
0
 

Author Comment

by:ats2012
ID: 40426662
Yes, I am.  I'm already a domain admin but I am running Powershell as administrator.  I keep thinking it has something to do with how the printer driver is handled.  The UNC Path to the driver is specified but the printer I'm trying to install is an enterprise level Lexmark machine that requires you to run the setup program.  Not sure I can do this with this script.  

Thoughts?
0
 
LVL 16

Expert Comment

by:Joshua Grantom
ID: 40426675
From the naming of the driver, you may be trying to install an incompatible driver. If your installing on a 64-bit Win7 the driver should not be Win_2kXP.

Do you have the 64bit drivers for it?
0
Best Practices: Disaster Recovery Testing

Besides backup, any IT division should have a disaster recovery plan. You will find a few tips below relating to the development of such a plan and to what issues one should pay special attention in the course of backup planning.

 

Author Comment

by:ats2012
ID: 40426738
I should have specified that I tested that.  The UNC directory path for the 64bit driver was tested  as in:

$DriverPath = ...\drivers\Print\Win_2kXP\x64
$DriverInf = ...\drivers\Print\Win_2kXP\x64\ntprint.inf

I tested this on a 32bit machine as well (with the 32bit instructions) and still get the exact same error.

Would the remote machines need to be running the latest .Net Framework?
0
 
LVL 16

Expert Comment

by:Joshua Grantom
ID: 40426795
that could be a possibility...

Whats strange is that it doesnt seem to have any issue with the PrinterPort and PrinterDriver, it only throws an error when trying to "Put" the printer. Maybe it needs an updated WMI framework? try updating one of the workstations to WMF 4.0 and see if it succeeds after that?
0
 

Author Comment

by:ats2012
ID: 40426923
It's doesn't appear to be a WMF issue after all.  I updated the 32bit machine to WMF 4.5 and reran the script and still same issue.  In fact I tested this on my machine earlier and I'm running 4.5 as well and it didn't work either.
0
 
LVL 16

Expert Comment

by:Joshua Grantom
ID: 40426934
do you have another printer to try? That would definitely narrow it down to whether you have to run the setup application for the Lexmark printer.
0
 

Author Comment

by:ats2012
ID: 40427228
I tried this with the most basic HP universal driver for a simple laserjet printer and it still didn't work.  It continues to fail with the same error.  Examining the error and researching via google it looks like one of key strings aren't getting passed into the function, hence the "Exception calling 'Put' with '0' argument(s)."    

That said I don't know what I should modify regarding $PrinterPort, $DriverPath, $DriverInf
0
 
LVL 16

Expert Comment

by:Joshua Grantom
ID: 40428357
Since you have spaces in the DriverName and PrinterCaption, try this below. I wrapped the variables in parentheses so it will read them as a single string. Let me know

####################################################
# Change these values to the appropriate values in your environment

$PrinterIP = "172.29.15.10"
$PrinterPort = "9100"
$PrinterPortName = "IP_" + $PrinterIP
$DriverName = "Lexmark 654de"
$DriverPath = "\\UNC Path\apps\Printers\Lexmark\654de\Admin\drivers\Print\Win_2kXP"
$DriverInf = "\\UNC Path\apps\Printers\Lexmark\654de\Admin\drivers\Print\Win_2kXP\LMACM540.inf"
$PrinterCaption = "Lexmark 654de"
####################################################

### ComputerList Option 1 ###
$ComputerList = @("ISH3LP")

### ComputerList Option 2 ###
# $ComputerList = @()
# Import-Csv "C:\Temp\ComputersThatNeedPrinters.csv" | `
# % {$ComputerList += $_.Computer}

Function CreatePrinterPort {
param ($PrinterIP, $PrinterPort, $PrinterPortName, $ComputerName)
$wmi = [wmiclass]"\\$ComputerName\root\cimv2:win32_tcpipPrinterPort"
$wmi.psbase.scope.options.enablePrivileges = $true
$Port = $wmi.createInstance()
$Port.name = $PrinterPortName
$Port.hostAddress = $PrinterIP
$Port.portNumber = $PrinterPort
$Port.SNMPEnabled = $false
$Port.Protocol = 1
$Port.put()
}

Function InstallPrinterDriver {
Param ($DriverName, $DriverPath, $DriverInf, $ComputerName)
$wmi = [wmiclass]"\\$ComputerName\Root\cimv2:Win32_PrinterDriver"
$wmi.psbase.scope.options.enablePrivileges = $true
$wmi.psbase.Scope.Options.Impersonation = `
[System.Management.ImpersonationLevel]::Impersonate
$Driver = $wmi.CreateInstance()
$Driver.Name = "$DriverName"
$Driver.DriverPath = $DriverPath
$Driver.InfName = $DriverInf
$wmi.AddPrinterDriver($Driver)
$wmi.Put()
}

Function CreatePrinter {
param ($PrinterCaption, $PrinterPortName, $DriverName, $ComputerName)
$wmi = ([WMIClass]"\\$ComputerName\Root\cimv2:Win32_Printer")
$Printer = $wmi.CreateInstance()
$Printer.Caption = "$PrinterCaption"
$Printer.DriverName = "$DriverName"
$Printer.PortName = $PrinterPortName
$Printer.DeviceID = $PrinterCaption
$Printer.Put()
}

foreach ($computer in $ComputerList) {
CreatePrinterPort -PrinterIP $PrinterIP -PrinterPort $PrinterPort `
-PrinterPortName $PrinterPortName -ComputerName $computer
InstallPrinterDriver -DriverName $DriverName -DriverPath `
$DriverPath -DriverInf $DriverInf -ComputerName $computer
CreatePrinter -PrinterPortName $PrinterPortName -DriverName `
"$DriverName" -PrinterCaption "$PrinterCaption" -ComputerName $computer
}

Open in new window

0
 

Author Comment

by:ats2012
ID: 40429038
Still fails with the same error.  Have you tested this script in your environment?  I still think that for some reason the string values (UNC Path to drivers) aren't being stored and passed to the function properly.  My only experience with this is simply setting those as constants, not calling a UNC path.  Seems pretty straight-forward though.  I've reached out to the author of the script but haven't heard anything.
0
 
LVL 16

Accepted Solution

by:
Joshua Grantom earned 500 total points
ID: 40429086
I actually think it is the driver name. When you open that INF file does it actually say "Lexmark 654de" or is it "Lexmark X654de" or another long name? It must match what is in the driver info not what you want it to be called.
0
 

Author Comment

by:ats2012
ID: 40429164
OK, it sorta works.  The driver name was the issue.  It is named "Lexmark X654de".  However, the script only works on my machine.  It still fails when trying to install the printer on a remote computer which is kinda the point of this whole exercise.  Thought is that it's because I'm running PS as administrator on my machine but remote machines the script wouldn't run with elevated permissions.  How would a person get this script to run with elevated permissions on remote systems?  Also the fact the I have enabled my machine to run unsigned scripts.
0
 
LVL 16

Assisted Solution

by:Joshua Grantom
Joshua Grantom earned 500 total points
ID: 40429169
If you run it with a Domain Admin account it should install. If it still does not let you, you may have to create a gpo to allow Remote Management and Remote access to WMI

http://www.briantist.com/how-to/powershell-remoting-group-policy/

http://community.spiceworks.com/how_to/show/17452-group-policy-to-allow-wmi-access-to-remote-machine
0
 

Author Closing Comment

by:ats2012
ID: 40429282
Thanks, this working now.  I indeed had to go in and allow remote management with WMI in group policy.  This script is saving us a ton of work having to remote to a machine and install a printer.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In previous parts of this Nano Server deployment series, we learned how to create, deploy and configure Nano Server as a Hyper-V host. In this part, we will look for a clustering option. We will create a Hyper-V cluster of 3 Nano Server host nodes w…
Recently we ran in to an issue while running some SQL jobs where we were trying to process the cubes.  We got an error saying failure stating 'NT SERVICE\SQLSERVERAGENT does not have access to Analysis Services. So this is a way to automate that wit…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…
This video Micro Tutorial shows how to password-protect PDF files with free software. Many software products can do this, such as Adobe Acrobat (but not Adobe Reader), Nuance PaperPort, and Nuance Power PDF, but they are not free products. This vide…

691 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question