Powershell v2 - Installing Printer - powershell

I'm trying to automate printer installation on windows 7 x64, by using Powershell script. So far I have a script that successfully creates TCP/IP port but gives me an error - The arguments are invalid, when it executes printer installation part of the code. Any ideas on how to fix the problem and successfully install a printer through the Powershell? The code is as follows:
$hostAddress = "172.16.2.24"
$portNumber = "9100"
$computer = $env:COMPUTERNAME
$wmi= [wmiclass]"\\$computer\root\cimv2:win32_tcpipPrinterPort"
#$wmi.psbase.scope.options.enablePrivileges = $true
$newPort = $wmi.createInstance()
$newPort.hostAddress = $hostAddress
$newPort.name = "IP_" + $hostAddress
$newPort.portNumber = $portNumber
$newPort.SNMPEnabled = $false
$newPort.Protocol = 1
$newPort.put()
CMD.EXE /C "printui.exe /if /b "Test Printer" /f C:\inetpub\wwwroot\ftp\Prdrivers\HP Universal Print Driver\pcl6-x64-5.7.0.16448\hpbuio100l.inf /r "IP_172.16.2.24" /m "HP Laser Jet P3015""
Question Update: This is the working CMD code, so how do I incorporate it into the Powershell code above ?
printui.exe /if /b "HP Universal Printing PCL 6" /f "C:\inetpub\wwwroot\ftp\Prdrivers\HP Universal Print Driver\pcl6-x64-5.7.0.16448\hpbuio100l.inf" /u /r "IP_172.16.2.24" /m "HP Universal Printing PCL 6"

To embed double-quotes within a double-quoted string you need to escape them. Since you are not using variables, it is easier to use a single quoted string e.g.:
CMD.EXE /C 'printui.exe /if /b "Test Printer" /f C:\inetpub\wwwroot\ftp\Prdrivers\HP Universal Print Driver\pcl6-x64-5.7.0.16448\hpbuio100l.inf /r "IP_172.16.2.24" /m "HP Laser Jet P3015"'
If you ever need to use PowerShell variables inside this string, then you will need to switch back to double quotes and escape the necessary DQ characters e.g:
CMD.EXE /C "printui.exe /if /b `"$PrinterName`" /f C:\inetpub\wwwroot\ftp\Prdrivers\HP Universal Print Driver\pcl6-x64-5.7.0.16448\hpbuio100l.inf /r `"IP_172.16.2.24`" /m `"HP Laser Jet P3015`""

Sorry, but im not sure why you are calling CMD /C #PARAMS. I am just calling the printui.exe directly and it is working, and I only double quote the Args
# Printer Info, I keep this in an SQL DB, and return these values with a query:
$printerID = "<PrinterNameOrID>"
$printerIP = "<PrinterIP>"
$printerPort = "IP_$printerIP"
$printerModel = "<PrinterModelFromINF>"
$driverINFPath = "<UNCPathToDriverINF>"
# Build a new Local TCP Printer Port, naming it with values unique to the Printer ID:
$newPort = ([wmiclass]"Win32_TcpIpPrinterPort").CreateInstance()
$newPort.HostAddress = $printerIP
$newPort.Name = $printerPort
$newPort.PortNumber = "9100"
$newPort.Protocol = 1
$newPort.Put()
# Add the printer
printui.exe /if /b "$printerID" /f "$driverINFPath" /u /r "$printerPort" /m "$printerModel"

I know this has already been answered but you could borrow the code I have in this Excel Workbook (there is a link in the article). I realize it uses VBS but these are built in scripts in Windows and cutting / pasting into Excel has saved me many times and I've installed thousands of printers this way
best-tool-for-printer-creation-excel-vs-print-management-console

Try this:
runas /user:Contoso.com\user1 "printui.exe /if /b \"Test Printer\" /f \"C:\inetpub\wwwroot\ftp\Prdrivers\HP Universal Print Driver\pcl6-x64-5.7.0.16448\hpbuio100l.inf\" /r \"IP_172.16.2.24\" /m \"HP Laser Jet P3015\""

Related

Getting a variable from a powershell script, in a batch file

I have seen some similar questions on this here on stack overflow, but I cannot get any of the answers to far to work.
I have this .ps1 file that mounts a drive and echos the drive letter (expected $driverLetter = "G" || "H" || "I"):
$mountDisk = Mount-DiskImage -ImagePath $args[0] -Passthru
$driveLetter = ($mountDisk | Get-Volume).DriveLetter
echo $driveLetter
I'm running it from this batch file:
FOR /F "usebackq delims=" %%i IN (`powershell -File ./mountDisk.ps1 "%1"`) DO SET "d=%%i"
Echo %d%
Each time I get an empty variable. I've tried setting environment variables, but yield same result.
Here's how I'd probably do it, assuming that the initial path passed to the batch file is double-quoted as necessary.
#Echo Off & SetLocal EnableExtensions & Set "ISODrv="
If /I Not "%~x1" == ".iso" (Exit /B 1) Else For %%G In ("%~1") Do If "%%~aG" GEq "d" Exit /B 2
For /F %%G In ('%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command "(Mount-DiskImage -ImagePath \"%~1\" -PassThru | Get-Volume).Driveletter" 2^>NUL') Do Set "ISODrv=%%G"
If Not Defined ISODrv (Exit /B 3) Else Echo %ISODrv%
Doing it this way eliminates the need for pre-creating a PowerShell script, and then any subsequent modifications to the execution policy. It only proceeds with the image mount if the received input value was an existing ISO file too. If you're running this batch file from a process which retrieves its exit code, 1 means that the input did not end with the case insensitive string .iso, 2 would mean that the input did end with the case insensitive string .iso, but it was a directory, not a file, and 3 would indicate that there was an error returning the mounted ISO image drive letter.
Try the following to run the cmd from the PowerShell and pathing their variables to it
# The command to pass to cmd.exe /cript
$var = "echo hello world & ping $ip & pause"
$ip = "192.168.1.1"
$var2 = "ping $ip & pause"
# Start the process asynchronously, in a new window,
# as the current user with elevation (administrative rights).
# Note the need to pass the arguments to cmd.exe as an *array*.
Start-Process -Verb RunAs cmd.exe -Args '/c', $var2, $var

Powershell - get console output into variable (not stdout, not stderror)

I have the exe from Lenovo that only provides command line output when run from a cmd window but not from PowerShell. The output seems to come from a ghost source other than StdOut or StdErr.
https://download.lenovo.com/pccbbs/mobiles/n2hgc06w.exe (you have to run and click install but all that does is unzip to c:\drivers\win\touchpadfw). Be sure to cancel the install prompt after extract.
This command gives me output to the console
& cmd.exe /c c:\drivers\win\touchpadfw\touchpadfw_aug2019\synreflash.exe /v /S 2
This also gives me output the the console and nothing in the variable
$var = (& cmd.exe /c c:\drivers\win\touchpadfw\touchpadfw_aug2019\synreflash.exe /v /S 2) 2>&1
Same here
$var = (& cmd.exe /c c:\drivers\win\touchpadfw\touchpadfw_aug2019\synreflash.exe /v /S 2 2>&1)
I feel like this exe is outputting in some other way than StdOut and StdErr but I don't know what. Nothing I've tried can capture what it is outputting. Is there a third method of output?
This is where it gets weird. Using "start cmd" to open a cmd window from the admin PowerShell, I run the exe directly in the cmd window but the output goes to the parent powershell console. I cannot get any output if I start the cmd window as admin directly.
Look at the SynReflash usage below you will notice that you would need to pass the last arg as /S 3 explicitly, to print to Standard Output as opposed to /S 2 is a silent mode
$cmdOutput = cmd.exe /c "C:\DRIVERS\WIN\TouchpadFW\n2hgc06w\synreflash.exe" /v /S 3 '2>&1'
OR
proc = [System.Diagnostics.Process]::Start([System.Diagnostics.ProcessStartInfo]#
{
'FileName' = "cmd.exe"
'Arguments' = "/C " + """C:\DRIVERS\WIN\TouchpadFW\n2hgc06w\synreflash.exe"" /v /s 3"
'CreateNoWindow' = $true
'UseShellExecute' = $false
'RedirectStandardOutput' = $true # to get stdout to $proc.StandardOutput
'RedirectStandardError' = $true # to get stderr to $proc.StandardError
})
$output = $proc.StandardOutput
$error1 = $proc.StandardError
write-host $output.ReadToEnd()
Output
FW Version: 1.2

How to pass batch file variables to PowerShell script? [duplicate]

This question already has an answer here:
Displaying SET variable
(1 answer)
Closed 3 years ago.
I am attempting to pass a number of variables processed by my batch file to a Powershell script. The problem I face is that firstly the entire results from the batch file come up in command prompt and next to the variables I intend to pass are not passed to the Powershell Script. Additionally, the variable I have to output the contents of the log file in just send the command back to the screen.
I have tried the following links and these links got me as far as I am now:
Batch file to execute a Powershell script
Pass variable from batch to powershell
Pass parameter from a batch file to a PowerShell script
Pass batch variables with spaces in them to powershell script?
Batch File side
set LOG_FILE = "GDGAGnklasj;oks;fk;dkf lkl;"
set oName = Name
set oStart = "%YYYY%%MM%%DD% %TIME%"
set oStatus = 0
set oEnd = "%YYYY%%MM%%DD% %TIME%"
set oDateRan = %YYYY%%MM%%DD%
set oLog =for /f "delims=" %%i in (%LOG_FILE%) do set content=%content% %%i
echo Updating Database >> %LOG_FILE% 2>&1
cmd /S powershell.exe -ExecutionPolicy Bypass -File "C:\Reporting\updateTool.ps1" "%oName%" "%DateRan%" "%oStart%" "%oEnd%" "%oStatus "%oLog%
PowerShell Script
param (
[string]$oName
)
"This is $oName"
My intent is to set the variables within the batch file then send them to Powershell for processing.
Be very careful of spaces.
set oName=taco
PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "& '.\ScriptName.ps1' -oName '%oName%' "
Oh Easy-Peasy, I do this for my Power shells that we need CMD wrappers for quite a bit.
I have to run to the train so this is going to be a bit meh at the moment I will firm it up in a bit, right now just going to paste in some example code so I can make it your code
Okay, what, umm, what did you intend for this Particular code to.l do ? I can't seem to figure out what you were intending with this, is it just some dummy code?
set oLog =for /f "delims=" %%i in (%LOG_FILE%) do set content=%content% %%i
echo Updating Database >> %LOG_FILE% 2>&1
Okay on further review I think you want to read the log into a couple of sttring variables in CMD, then use one of them in your call of the script..... but, why?
The strings will append to each other and you will be limited to 8191 characters max, and PowerShell can easily read the content of the log file because you pass the name to Powershell.
That seems like a better plan, no?
All your code where you have YYYY MM DD those are variables you will need to define before using, not sure if that is understood if so all good.
.CMD Script:
#(
SETLOCAL ENABLEDELAYEDEXPANSION
ECHO OFF
SET "_PSScript=C:\Reporting\UpdateTool.ps1"
REM SET "_DebugPreference=Continue"
SET "_DebugPreference="SilentlyContinue"
SET "_LOG_FILE=GDGAGnklasj;oks;fk;dkf lkl;"
SET "_oName=Name."
SET "_oStart=%YYYY%%MM%%DD% %TIME: =0%"
SET /a "_Status=0"
SET "_oEnd=%YYYY%%MM%%DD% %TIME: =0%"
SET "_oDateRan=%YYYY%%MM%%DD%"
)
SET "_PSCMD=Powershell "%_PSScript%" -DebugPreference "%_DebugPreference%" -LOG_FILE "%_LOG_FILE%" -oName "%_oName%" -oStart "%_oStart%" -Status %_Status% -oEnd "%_oEnd%" -oDateRan "%_oDateRan%" "
%_PSCMD% 2>&1 >> "_LOG_FILE"
PS1:
## Script: UpdateTool.ps1
#
param(
[String]$LOG_FILE = 'c:\admin\default.log',
[String]$oName = 'default name'
[String]$oStart = $(Get-date -F "yyyyMMdd HH:mm:ss.ms"),
[Int]$oStatus = 0,
[String]$oEnd = $(Get-date -F "yyyyMMdd HH:mm:ss.ms"),
[String]$oDateRan = $(Get-date -F "yyyyMMdd"),
$DebugPreference = "SilentlyContinue"
)

PowerShell v2 Adding a Printer

I'm trying to create a PowerShell Script that allows me to add and configure a printer with 3 instances of the printer. This is what I have so far:
# Printer Info
$printerID = "HP Designjet Z3200 24in Photo"
$printerID1 = "HP Designjet Z3200 24in Photo - Canvas"
$printerID2 = "HP Designjet Z3200 24in Photo - Cover"
$printerIP = Read-Host 'What is the Poster Printer IP Address?'
$printerPort = "IP_$printerIP"
$printerModel = "HP Designjet Z3200 24in Photo"
# Speak with Ted about a specific place to put the poster driver pre-extracted
$driverINFPath = "C:\Velocity\HP WFP\Driver\hpdjz3200serieswx64pcl\hpi32pxs.inf"
# Build a new Local TCP Printer Port, naming it with values unique to the Printer ID:
$newPort = ([wmiclass]"Win32_TcpIpPrinterPort").CreateInstance()
$newPort.HostAddress = $printerIP
$newPort.Name = $printerPort
$newPort.Put()
# Add the printer
printui.exe /if /b "$printerID" /f "$driverINFPath" /u /r "$printerPort" /m "$printerModel"
printui.exe /if /b "$printerID1" /f "$driverINFPath" /u /r "$printerPort" /m "$printerModel"
printui.exe /if /b "$printerID2" /f "$driverINFPath" /u /r "$printerPort" /m "$printerModel"
I copied the part from an earlier post for the port part of the script. I'm trying to figure out what the .Put() is and I cannot find it anywhere. Any help would be much appreciated.
...Windows PowerShell accesses WMI through the .NET Framework and
System.Management class. Rather than using SWbemObject, Windows
PowerShell uses the System.Management.ManagementObject class. For
better or worse, this class uses a method named Put to save changes to
a read-write property.
From TechNet, which actually is comparing VBScript Put_ to PowerShell Put() calls.

teamcity command line interpretter : quotes are replaced

I need to run a simple command line within teamcity
FINDSTR /M /N /P /S /R /C:"goto end" D:\blabla\*
The double quote are replaced and somehow doubled when teamcity calls the command. The resulting command is
cmd.exe /c FINDSTR /M /N /P /S /R "/C:"goto end""
Which fails.
How can I prevent this from happening? The value for param /C requires a param with double quotes in my case. thanks
Put your command in a batch file and call that passing in whatever arguments (if any) you need.
Whenever you do anything like this on windows, always do this :)
Your example:
FINDSTR /M /N /P /S /R /C:"goto end" D:\blabla\*
Works as-is, in TeamCity 2018.1.3, using a Command Line runner with the above specified in the Custom Script section.