Solved

Powershell to Install Network Printer

Posted on 2014-11-05
14
501 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
  • 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
 

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
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 

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

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Join & Write a Comment

This article shows how a content item can be identified directly or through translation of a navigation type. It then shows how this information can be used to create a menu for further navigation.
Synchronize a new Active Directory domain with an existing Office 365 tenant
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

743 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

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now