How to parse WMIC printer list full - windows

When I use the following command, it outputs a text file with a computer's printer information: wmic printer list full >> c:\computer_printers.txt
However, the list is very long, and I only want to see the fields for DriverName, Name, and Portname in the output. Is there a way to modify the command I am using to get this result?
I researched the adverbs associated with the verb List, but the way I am interpreting the document here (https://msdn.microsoft.com/en-us/library/aa394531(v=vs.85).aspx), it does not seem like what I am trying to do is possible. Is there anyone with more experience with WMIC that can confirm this?

I only want to see the fields for DriverName, Name, and Portname in the output
Use the following command:
wmic printer get DriverName, Name, Portname >> c:\computer_printers.txt
Example output:
> type c:\computer_printers.txt
DriverName Name PortName
Microsoft XPS Document Writer Microsoft XPS Document Writer XPSPort:
Microsoft Shared Fax Driver Fax SHRFAX:
EPSON Stylus Photo RX560 Series EPSON Stylus Photo RX560 Series USB001
CutePDF Writer CutePDF Writer CPW2:
Further Reading
An A-Z Index of the Windows CMD command line | SS64.com
Windows CMD Commands (categorized) - Windows CMD - SS64.com
WMIC - Windows Management - Windows CMD - SS64.com

Related

How to query and add (if not listed) a location to Windows 10 Search Index using PowerShell

I have to re-mount removable drives (which require authentication) each time I boot the computer and Windows Indexing keeps removing the removable drives (perhaps because the removable drives are not available when the computer boots). In an ideal world Windows Indexing would keep these locations and just list them as 'Unavailable' (which it sometimes does). However because it doesn't I am interested in executing a script that queries the Windows Indexing locations and if it does not list the removable drives then add them. At the bottom of this thread I pasted the Batch script that I setup to run at boot (via Start Up folder) to search for a specific folder that is available thereafter mounting one of the removable drives.
I have found several examples of how to do this on Windows 7 (links pasted below) but I can't figure out how to do it in Windows 10. The links provided to the DLL (Microsoft.Search.Interop.dll) no longer resolve.
When searching for the latest Windows Search SDK for Windows 10 I was lead to the Windows SDK here:
https://learn.microsoft.com/en-us/windows/win32/search/-search-developers-guide-entry-page
I installed the C++ related portion of the Windows SDK then searched for Microsoft.Search.Interop.dll but I couldn't find it. Perhaps the DLL has changed?
From How to rebuild Windows Search Index by using PowerShell?
Load DLL containing classes & interfaces
Add-Type -path "C:\Temp\SearchIndexSdk\Microsoft.Search.Interop.dll"
#Provides methods for controlling the Search service. This
interface manages settings and objects that affect the search engine
across catalogs.
https://msdn.microsoft.com/en-us/library/bb231485(v=vs.85).aspx
$sm = New-Object Microsoft.Search.Interop.CSearchManagerClass
#Retrieves a catalog by name and creates a new ISearchCatalogManager
object for that catalog.
$catalog = $sm.GetCatalog("SystemIndex")
#Resets the underlying catalog by rebuilding the databases and performing a full indexing.
#https://msdn.microsoft.com/en-us/library/bb266414(v=vs.85).aspx
$catalog.Reset()
From How to add a location to windows 7/8 search index using batch or vbscript?
#Code copied from "Powershell Tackles Windows Desktop Search" http://powertoe.wordpress.com/2010/05/17/powershell-tackles-windows-desktop-search/
#Microsoft.Search.Interop.dll is needed, download from http://www.microsoft.com/en-us/download/details.aspx?id=7388
#Load the dll
Add-Type -path "D:\Unattend\UserFiles\Tools\Microsoft.Search.Interop.dll"
#Create an instance of CSearchManagerClass
$sm = New-Object Microsoft.Search.Interop.CSearchManagerClass
#Next we connect to the SystemIndex catalog
$catalog = $sm.GetCatalog("SystemIndex")
#Get the interface to the scope rule manager
$crawlman = $catalog.GetCrawlScopeManager()
#add scope
$crawlman.AddUserScopeRule("file:///D:*",$true,$false,$null)
$crawlman.SaveAll()
I would add a comment to the existing threads but I am not able to because I don't have reputation of 50 (dumb rule IMO).
Last... I found this site which lists the DLL along with some code but it hasn't been updated in a long time.
https://github.com/FileMeta/WindowsSearchSample
Thanks in advance!
Batch script that runs at boot:
#echo off
echo Windows Search is being restarted to recognize the Z drive
:while
if EXIST Z:\Watch (
I WANT TO CALL POWERSHELL SCRIPT TO ADD THE LOCATION TO THE INDEX IF NEEDED HERE
sc stop WMPNetworkSvc
ping 127.0.0.1 -n 5 > nul
sc stop WSearch
ping 127.0.0.1 -n 5 > nul
sc start WSearch
ping 127.0.0.1 -n 5 > nul
sc start WMPNetworkSvc
echo Exiting this script in 5 seconds
ping 127.0.0.1 -n 5 > nul
exit
) else (
echo Waiting 60 seconds to check if Z drive is available
ping 127.0.0.1 -n 60 > nul
goto :while
)
When I do a search for Searchdll in what I believe to be the folder where the Windows SDK installed to (C:\Program Files (x86)\Windows Kits\10) I find the following. If I had to guess which DLL is the Windows 10 equivalent of Windows 7's Microsoft.Search.Interop.dll I would guess that it's the 1st one i.e. interop.searchapi.dll.
Add-Type -Path "C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\interop.searchapi.dll" does return without error... however $sm = New-Object Microsoft.Search.Interop.CSearchManagerClass returns with error that it cannot find the class in the assembly.
When I cd to "C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64" and enter ([appdomain]::currentdomain.GetAssemblies() | Where-Object Location -Match 'interop.searchapi').gettypes() I get the following
When I enter (([appdomain]::currentdomain.GetAssemblies() | Where-Object location -match 'interop.searchapi.dll').gettypes() | Where-Object name -eq 'CSearchManagerClass').getmembers() | Format-Table name, membertype I get
From the list of commands in the previous threads I do see GetCatalog and I presume that the members GetCrawlScopeManager, AddUserScopeRule, Reset, and SaveAll exist.
I don't know how to find the fully qualified class name or I'm doing something else wrong (unknowingly).
When I enter ([appdomain]::currentdomain.GetAssemblies() | Where-Object Location -Match 'interop.searchapi').fullname I get the following
Interop.SearchAPI, Version=10.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
But when I enter $sm = New-Object Interop.SearchAPI.CSearchManagerClass I get an error that it can't find the type Interop.SearchAPI.CSearchManagerClass.

Trying to search for a string within command output

I'm writing a script to run PSinfo (from the Sysinternals suite) against a list of machines, then I want to search the output for a specific string before doing other things. The basic code is as follows:
with open ("specific-pcs.txt") as machines:
line = []
for machineName in machines:
machineName = machineName.strip()
ps_Info = subprocess.Popen("location of PsInfo \\" + machineName + " -s").communicate()[0]
if ("Silverlight" in ps_Info):
subprocess.Popen("wmic product where caption='Microsoft Silverlight' call uninstall")
print "Uninstalling Silverlight"
else:
pass
The output of PsInfo looks something like this:
Microsoft Office Word MUI (English) 2010 14.0.7015.1000
Microsoft ReportViewer 2010 Redistributable 10.0.30319
Microsoft Silverlight 5.1.10411.0
Microsoft Visual C++ 2008 Redistributable - x86 9.0.30729.4148 9.0.30729.4148
Realtek High Definition Audio Driver 6.0.1.7004
But running the code as is, it complains that "'Nonetype' is not iterable".
All I need it to do is say if Silverlight (in this case) exists in the output or not.
What do I need to change?
Thanks, Chris.
communicate returns None for a stream if it is not redirected to a pipe, which means in your case:
subprocess.Popen("location of PsInfo \\" + machineName + " -s").communicate()
will return (None, None), and when using the in operator on None you get the argument of type 'NoneType' is not iterable error.
Also, you should use a list of arguments when calling Popen instead of a single string, so this should work:
ps_Info = subprocess.Popen([r"C:\Path\To\PsInfo", r"\\" + machineName, "-s"],
stdout=subprocess.PIPE).communicate()[0]

VBS - Error opening connection using ADODB

I'm having problems trying to connect in my oracle database using an ADODB object in VBScript, the code is working on a Win7 machine but not on WinXP, I tried to search for the error code, downloaded the sdk with the help file to look for something but I didn't found nothing useful.
Here is the code sample:
ConnectionString = "DSN=(Oracle in OraClient11g_home1);UID=username ;PWD=password ;DBQ=myDatabase"
Set objCon = CreateObject("ADODB.Connection")
objCon.Open ConnectionString 'the error occurs in this line
I don't know if the connection string must be different for winXP machines... I really don't know how to solve this, can someone help me?
The error trace information:
"Error #-2147024770:
Error reported by: ADODB.Connection
Help File:
Topic ID: 1240640"
-2147024770 = FFFFFFFF8007007E
To Decode 0x8007nnnn Errors
HResults with facility code 7 means the HResult contains a Windows' error code. You have to look up the Windows' error code not the HResult.
To decode 0x8007007e. The 0x means it's a hexadecimal number, the 8 means error, the first 7 means it a windows error, and the rest of the number, 7e, is the actual Windows error.
To look up the error we need it in decimal format. Start Calculator (Start - All Programs - Accessories - Calculator) and choose View menu - Scientific, then View menu - Hex. Enter 7e. Then View menu - Decimal. It will say 126.
Start a Command Prompt (Start - All Programs - Accessories - Command Prompt) and type
net helpmsg 126
and it will say
The specified module could not be found.
or look it up in winerror.h
//
// MessageId: ERROR_MOD_NOT_FOUND
//
// MessageText:
//
// The specified module could not be found.
//
#define ERROR_MOD_NOT_FOUND 126L
To see what is happening start your program in ntsd.
Start a command prompt.
Type
md c:\symbols
set _NT_SYMBOL_PATH=srv*C:\tmp*http://msdl.microsoft.com/download/symbols;c:\symbols
then (changing it to your program from notepad)
ntsd -g -o c:\windows\notepad.exe
so something
ntsd -g -o wscript "c:\folder\script.vbs"
and wait for the error.

Install inf driver with VBScript on Windows 7

I am trying to write a VBS script that install an USB/Ethernet adapter on Windows 7.
I've got a .INF file for this device.
I first tried:
Dim WshShell, res
Set WshShell = WScript.CreateObject("WScript.Shell")
res = WshShell.Run(WshShell.ExpandEnvironmentStrings( "%SystemRoot%" ) & "\System32\InfDefaultInstall.exe "" C:\Users\Me\Driver.inf """, 1, True)
res equaled 2.
Then I searched another way to do that and I found:
Dim WshShell, res
Set WshShell = WScript.CreateObject("WScript.Shell")
res = WshShell.Run(WshShell.ExpandEnvironmentStrings( "%SystemRoot%" ) & "\System32\rundll32.exe SETUPAPI.DLL,InstallHinfSection DefaultInstall 132 ""Driver.inf""", 1, True)
res equals 0 but I've got an error popup Installation failed.
What's wrong with my code? For the record, the script is launched with administration rights.
EDIT
I've tried to execute the first command directly in prompt and got: The inf file you selected does not support this method of installation..
Nothing happens with second command in prompt.
This is very weird because I can install the driver "manually" when I launch the device manager and select the inf file (with a warning: Windows can't verify the publisher of this driver software.):
Once the driver is installed, the class installer property shows NetCfgx.dll,NetClassInstaller. Could it be used?
I also tried with devcon with no success (program returns devcon.exe failed).
How about this way:
1)If you're using "Windows 7", why not take advantage of the driver pre-staging utility that is built right into the OS? W7 ships with a driver utility called "PNPUTIL". Issuing a command as such will add the drivers:
PNPUTIL -a "X:\Path to Driver File\Driver.inf"
This will process the INF and copy the CAT/SYS/INF (and any DLL, EXE, etc) into the "DriverStore" folder... which is the same place Windows stores all the in-built drivers ready for auto plug-and-play instalaltion.
2)If that's not an option for you, look for "DPInst.exe" (or "DPInst64.exe" for 64-bit systems). These are available as part of the Windows PDK (available free from Microsoft) and will process all INFs in the location you put the file and attempt to pre-stage them. This method tries to copy files to the "Drivers", "CatRoot", and "INF" locations which are not as reliable... and it can occassionally fail to copy required DLLs to "System32" folders etc... but 99% of the time (for simple drivers) it just works. I can arrange to send them to you if you can't find them.
Since I found the option (1) above, that has been my best friend. I use option 2 to isntall Canon USB printers and scanners on our base images, etc... so I know that works too.
I had same problem and solved it by explicitly using ASCII version of InstallHinfSection entry point:
res = WshShell.Run("%Comspec% /C %SystemRoot%\System32\rundll32.exe SETUPAPI.DLL,InstallHinfSectionA DefaultInstall 132 ""Driver.inf""", 1, True)
There is probably a better solution, though (like hinting at the script engine which unicode/ASCII flavor to use).
Also I'm using EN-US system so this workaround may fail on more exotic locales.
Try this:
res = WshShell.Run("%Comspec% /C %SystemRoot%\System32\rundll32.exe SETUPAPI.DLL,InstallHinfSection DefaultInstall 132 ""Driver.inf""", 1, True)

How to add a Local Printer using VBScript on Windows 7?

I have a Windows 7 64bit pc, I'm trying to add a Local Printer which automatically installs the driver and shares the printer once it is done.
The port is a Loopback IP Address (127.0.0.1) and it uses the Zebra (ZDesigner LP 2844) Driver. (Which you can get here: http://www.zebra.com/us/en/support-downloads/desktop/lp-2844.html )
My current script works great on XP but not so good on Windows 7. It comes up with the error
"Microsoft VBScript runtime error:ActiveX component can't create object: 'Port.Port.1' for my script AddPort.vbs
The following script is called AddPort.vbs
'ADDING:
dim oPort
dim oMaster
set oPort = CreateObject("Port.Port.1")
set oMaster = CreateObject("PrintMaster.PrintMaster.1")
wscript.echo "Adding port to local machine...."
'Indicate where to add the port. Double quotes ("" ) stand for the local computer, which is the default, or put "\\servername"
oPort.ServerName = ""
'The name of the port cannot be omitted.
oPort.PortName = "CustomPortName"
'The type of the port can be 1 (TCP RAW), 2 (TCP LPR), or 3 (standard local).
oPort.PortType = 3
'For TCP RAW ports. Default is 9100.
oPort.PortNumber = 9101
'Try adding the port.
oMaster.PortAdd oPort
'Test for the status.
If Err <> 0 then
wscript.echo "Error " & Err & " occurred while adding port"
End If
The Following script is called AddPrinter.vbs
This script shows the error "Microsoft VBScript runtime error:ActiveX component can't create object: PrintMaster.PrintMaster.1
' Adding a Printer
' The sample code in this section creates any required objects, adds a printer to a remote server, and configures some driver and port information.
dim oMaster
dim oPrinter
wscript.echo "Adding VirtualPrinter printer to local machine...."
'The following code creates the required PrintMaster and Printer objects.
set oMaster = CreateObject("PrintMaster.PrintMaster.1")
set oPrinter = CreateObject("Printer.Printer.1")
'The following code specifies the name of the computer where the printer will be added. To specify the local
'computer, either use empty quotes (“”) for the computer name, or do not use the following line of code. If
'ServerName is not set, the local computer is used. Always precede the name of a remote computer with two backslashes (\\).
oPrinter.ServerName = ""
'The following code assigns a name to the printer. The string is required and cannot be empty.
oPrinter.PrinterName = "VirtualPrinter"
'The following code specifies the printer driver to use. The string is required and cannot be empty.
oPrinter.DriverName = "ZDesigner LP 2844"
'The following code specifies the printer port to use. The string is required and cannot be empty.
oPrinter.PortName = "LoopBack"
'The following code specifies the location of the printer driver. This setting is optional, because by default
'the drivers are picked up from the driver cache directory.
'oPrinter.DriverPath = "c:\drivers"
'The following code specifies the location of the INF file. This setting is optional, because by default the INF
'file is picked up from the %windir%\inf\ntprint.inf directory.
'oPrinter.InfFile = "c:\winnt\inf\ntprint.inf"
oPrinter.PrintProcessor = "winprint"
'The following code adds the printer.
oMaster.PrinterAdd oPrinter
'The following code uses the Err object to determine whether the printer was added successfully.
if Err <> 0 then
wscript.echo "Error " & Err & " occurred while adding VirtualPrinter"
else
wscript.echo "Printer added successfully"
end if
' To configure other printer settings, such as comments, create a Printer object and then call PrintMaster's method PrinterSet.
wscript.echo "Configuring printer...."
oPrinter.Comment = "Virtual printer to capture labels"
oPrinter.ShareName = "VirtualPrinter"
oPrinter.Shared = true
oPrinter.Local = true
oMaster.PrinterSet oPrinter
if Err <> 0 then
wscript.echo "Error " & Err & " occurred while changing settings for VirtualPrinter"
end if
Is there any other way I can create a Local Printer, Set the Driver, Port Number and Port Name and Share Name and Print Processor using vbscript in Windows 7???
Thank you in advance, the best response will receive points.
This is just what you need, for Windows 7:
The seven printer utilities, shown later, are located in the C:\Windows\System32\Printing_Admin_Scripts\en-US folder, which is not listed in the path. Therefore, you must actually change to this folder in order to run the utilities. And, since these utilities are designed to be run from the command line, you need to launch them from a Command Prompt window and run them using Windows Script Host's command-line-based script host (Cscript.exe).
Windows 7's VBScript printing utilities
VBScript File | What it does
---------------------------------------------
Prncnfg.vbs | Printer configuration
Prndrvr.vbs | Printer driver configuration
Prnjobs.vbs | Print job monitoring
Prnmngr.vbs | Printer management
Prnport.vbs | Printer port management
Prnqctl.vbs | Printer queue management
Pubprn.vbs | Publish a printer to Active Directory
Hope this works for you
I found another way to automate adding the printer, first I created a batch file then I used the prnmngr.vbs which comes with Windows 7 to automatically add the printer for me. For this to work I already had the Zebra driver installed on the machine (but the concept would be the same for any other type of printer). Then I ran the batch file.
Following shows how I did it, I've added the batch file text here:
Name the file: AddPrinter.bat
rem first change the directory to the script location
cd %WINDIR%\System32\Printing_Admin_Scripts\en-US\
rem vbs script path: %WINDIR%\System32\Printing_Admin_Scripts\en-US\Prnmngr.vbs
rem first add the port, specify name of port, assign it an IP Address, specify the type and the Port.
cscript prnport.vbs -a -r "LoopBack" -h 127.0.0.1 -o raw -n 9100
cscript prnport.vbs -a -r "LoopBack_2" -h 127.0.0.1 -o raw -n 9101
pause
rem specify the name of the new printer, specify the driver, specify the port it will use.
cscript prnmngr.vbs -a -p "VirtualPrinter" -m "ZDesigner LP 2844" -r "LoopBack"
pause
cscript prnmngr.vbs -a -p "Zebra LP2844" -m "ZDesigner LP 2844" -r "USB0001"
rem cscript prnmngr.vbs -a -p "Zebra GK420d" -m "ZDesigner GK420d" -r "LPT1:"
rem cscript prnmngr.vbs -a -p "Zebra GC420d" -m "ZDesigner GC420d" -r "COM1:"
pause
NET STOP SPOOLER
NET START SPOOLER
pause
To customise this you can use these websites as a reference;
http://technet.microsoft.com/en-us/library/cc725868(v=ws.10).aspx
http://technet.microsoft.com/en-us/library/bb490974.aspx
http://blog.ogwatermelon.com/?p=3489
http://winadminnotes.wordpress.com/2010/02/19/how-to-manage-printers-and-printer-drivers-remotely-from-command-line/
http://technet.microsoft.com/en-us/library/cc754352(v=ws.10).aspx

Resources