Solved

How do I find and pass dynamic data to other parts of a VBScript?

Posted on 2011-03-15
14
648 Views
Last Modified: 2012-08-14
Hello scripters!

        I am attempting to do the following via VBScript in a TS/RDS Farm:
At logon, find the currently logged on user.
Find the current default printer for that Remote Desktop session.
Pass those variables to other lines later in the VBScript to use a SetACL process.
SetACL line(s):
Set objScriptExec = objShell.Exec("C:\Support\SetACL\x64\SetACL.exe -on ""<Discovered TS/RDS session default printer>"" -ot prn -actn ace -ace ""n:<domainnamehere>\<discoveredusernamehere>;p:man_printer""")

Thanks!
0
Comment
Question by:NetManaged
  • 8
  • 6
14 Comments
 
LVL 65

Expert Comment

by:RobSampson
Comment Utility
Hi, this should work when run as the currently logged on user.

Regards,

Rob.
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20

Set objScriptExec = CreateObject("WScript.Shell")
Set objNetwork = CreateObject("WScript.Network")
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT Name FROM Win32_Printer WHERE Default=True", "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems
	strPrinter = objItem.Name
Next

Set objScriptExec = objShell.Exec("C:\Support\SetACL\x64\SetACL.exe -on """ & strPrinter & """ -ot prn -actn ace -ace ""n:" & objNetwork.UserDomain & "\" & objNetwork.UserName & ";p:man_printer""")

Open in new window

0
 

Author Comment

by:NetManaged
Comment Utility
Oh my Rob...that looks like what I need!
I never noticed you could use the objNetwork.<something> like that.
What does the "WQL" signify? I'm not familiar with that.
I hope to be able to test this tomorrow, both, as a standalone and to incorporate into the script I am developing.
Thanks!
Greg
0
 
LVL 65

Expert Comment

by:RobSampson
Comment Utility
WQL stands for Windows Query Language.  It's the language of the queries used for WMI.  It must be specified when the parameters at the end are used.

http://msdn.microsoft.com/en-us/library/aa393866(v=vs.85).aspx

Regards,

Rob.
0
 

Author Comment

by:NetManaged
Comment Utility
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20

Set objScriptExec = CreateObject("WScript.Shell")
Set objNetwork = CreateObject("WScript.Network")
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT Name FROM Win32_Printer WHERE Default=True", "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems
      strPrinter = objItem.Name

For Each objPrinter in colItems
if inStr(objPrinter.Name,"IMC-FDPtr1") <> 0 Then Call SetIMCFDPTR1
Sub SetIMCFDPTR1
Set objShell = CreateObject("WScript.Shell")
Set objScriptExec = objShell.Exec("C:\Support\SetACL\x64\SetACL.exe -on """ & strPrinter & """ -ot prn -actn setowner -ownr ""n:" & objNetwork.UserDomain & "\" &

objNetwork.UserName &";""")
strPrnConfig = objScriptExec.StdOut.ReadAll
'WScript.Echo strPrnConfig
Set objShell = CreateObject("WScript.Shell")
Set objScriptExec = objShell.Exec("C:\Support\SetACL\x64\SetACL.exe -on """ & strPrinter & """ -ot prn -actn ace -ace ""n:" & objNetwork.UserDomain & "\" & objNetwork.UserName &

";p:man_printer""")
strPrnConfig = objScriptExec.StdOut.ReadAll
'WScript.Echo strPrnConfig
     objPrinter.RenamePrinter("IMCFDPTR1 (2)")
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" _
    & strComputer & "\root\cimv2")
Set colInstalledPrinters =  objWMIService.ExecQuery _
    ("Select * from Win32_Printer Where Name = 'IMCFDPTR1 (2)'")
For Each objPrinter in colInstalledPrinters
    objPrinter.SetDefaultPrinter()
Next
end sub
0
 

Author Comment

by:NetManaged
Comment Utility
Ahh nuts! Messed up!
The code you supplied works great! I added a line above it to take ownership first then add the manage printers permission.
How do I pass the strings to a Sub later in the script?
I want to pass the printer in the sub.
When I get to Sub SetIMCFDPTR1 I get a general syntax error.
When I run my original script with known values it works.
What am I doing wrong?
Thanks!
Greg
0
 
LVL 65

Expert Comment

by:RobSampson
Comment Utility
Hi, I don't see your sub in that code, but to pass the string, call
SetIMCFDPTR1 strPrinter

with
Sub SetIMCFDPTR1(strPrinterName)
   WScript.Echo "Printer: " & strPrinterName
End Sub


Regards,

Rob.
0
 

Author Comment

by:NetManaged
Comment Utility
Guess, I'm still not doing something right.
I still get a syntax error at the Sub.

Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20

Set objScriptExec = CreateObject("WScript.Shell")
Set objNetwork = CreateObject("WScript.Network")
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT Name FROM Win32_Printer WHERE Default=True", "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems
	strPrinter = objItem.Name

For Each objPrinter in colItems
  if inStr(objPrinter.Name,"IMC-FDPtr1") <> 0 Then Call SetIMCFDPTR1("strPrinter")

wscript.quit

Sub SetIMCFDPTR1(strPrinterName)
Set objShell = CreateObject("WScript.Shell")
Set objScriptExec = objShell.Exec("C:\Support\SetACL\x64\SetACL.exe -on """ & strPrinter & """ -ot prn -actn setowner -ownr ""n:" & objNetwork.UserDomain & "\" & 

objNetwork.UserName &";""")
strPrnConfig = objScriptExec.StdOut.ReadAll

Set objShell = CreateObject("WScript.Shell")
Set objScriptExec = objShell.Exec("C:\Support\SetACL\x64\SetACL.exe -on """ & strPrinter & """ -ot prn -actn ace -ace ""n:" & objNetwork.UserDomain & "\" & objNetwork.UserName & 

";p:man_printer""")
strPrnConfig = objScriptExec.StdOut.ReadAll

     objPrinter.RenamePrinter("IMCFDPTR1 (2)")
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" _
    & strComputer & "\root\cimv2")
Set colInstalledPrinters =  objWMIService.ExecQuery _
    ("Select * from Win32_Printer Where Name = 'IMCFDPTR1 (2)'")
For Each objPrinter in colInstalledPrinters
    objPrinter.SetDefaultPrinter()
Next
end sub

Open in new window

0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 65

Expert Comment

by:RobSampson
Comment Utility
Hi, very sorry for my delay.  It turns out I was being blind, as your Sub was in the original code. I was also being blind because you have one too many For loops, and no Next statements.  This should work now.

Regards,

Rob.
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20

Set objScriptExec = CreateObject("WScript.Shell")
Set objNetwork = CreateObject("WScript.Network")
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT Name FROM Win32_Printer WHERE Default=True", "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems
	If inStr(objItem.Name,"IMC-FDPtr1") <> 0 Then SetIMCFDPTR1 objItem.Name
Next
WScript.Quit

Sub SetIMCFDPTR1(strPrinterName)
	Set objShell = CreateObject("WScript.Shell")
	Set objScriptExec = objShell.Exec("C:\Support\SetACL\x64\SetACL.exe -on """ & strPrinterName & """ -ot prn -actn setowner -ownr ""n:" & objNetwork.UserDomain & "\" & objNetwork.UserName &";""")
	strPrnConfig = objScriptExec.StdOut.ReadAll

	Set objShell = CreateObject("WScript.Shell")
	Set objScriptExec = objShell.Exec("C:\Support\SetACL\x64\SetACL.exe -on """ & strPrinterName & """ -ot prn -actn ace -ace ""n:" & objNetwork.UserDomain & "\" & objNetwork.UserName & ";p:man_printer""")
	strPrnConfig = objScriptExec.StdOut.ReadAll

	objPrinter.RenamePrinter("IMCFDPTR1 (2)")
	strComputer = "."
	Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
	Set colInstalledPrinters =  objWMIService.ExecQuery("Select * from Win32_Printer Where Name = 'IMCFDPTR1 (2)'")
	For Each objPrinter In colInstalledPrinters
		objPrinter.SetDefaultPrinter()
	Next
End Sub

Open in new window

0
 

Author Comment

by:NetManaged
Comment Utility
Hm...getting an error at Line 22, Object required: 'objPrinter'
0
 

Author Comment

by:NetManaged
Comment Utility
Wups! Never mind. I figured out what was wrong.
In the code window is the working script. : )
Please look it over for any optimization/clean up you recommend.
If it is good as-is, I will go ahead and award you the points.
ALSO, I have one more aspect to this script I need help on, but I will open another question for it.

Thanks!
Greg
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20

Set objScriptExec = CreateObject("WScript.Shell")
Set objNetwork = CreateObject("WScript.Network")
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT Name FROM Win32_Printer WHERE Default=True", "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems
	If inStr(objItem.Name,"IMC-FDPtr1") <> 0 Then SetIMCFDPTR1 objItem.Name
Next
WScript.Quit

Sub SetIMCFDPTR1(strPrinterName)
	Set objShell = CreateObject("WScript.Shell")
	Set objScriptExec = objShell.Exec("C:\Support\SetACL\x64\SetACL.exe -on """ & strPrinterName & """ -ot prn -actn setowner -ownr ""n:" & objNetwork.UserDomain & "\" & objNetwork.UserName &";""")
	strPrnConfig = objScriptExec.StdOut.ReadAll

	Set objShell = CreateObject("WScript.Shell")
	Set objScriptExec = objShell.Exec("C:\Support\SetACL\x64\SetACL.exe -on """ & strPrinterName & """ -ot prn -actn ace -ace ""n:" & objNetwork.UserDomain & "\" & objNetwork.UserName & ";p:man_printer""")
	strPrnConfig = objScriptExec.StdOut.ReadAll

	Set colItems = objWMIService.ExecQuery("SELECT Name FROM Win32_Printer WHERE Default=True", "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
	For Each objPrinter In colItems
	objPrinter.RenamePrinter("IMCFDPTR1 (2)")

	Next

	strComputer = "."
	Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
	Set colInstalledPrinters =  objWMIService.ExecQuery("Select * from Win32_Printer Where Name = 'IMCFDPTR1 (2)'")
	For Each objPrinter In colInstalledPrinters
		objPrinter.SetDefaultPrinter()
	Next
End Sub

Open in new window

0
 
LVL 65

Accepted Solution

by:
RobSampson earned 500 total points
Comment Utility
Hi, OK, a few things that I've rejigged a bit.

1) You're not needing to use objShell.Exec because you don't need to do anything with the output, so we can use objShell.Run and make it run hidden instead.
2) Your original query on line 7 only queried the default printer.  If the printer exists but is not the default, then it won't be actioned, but maybe that was by design.  In any case, I have made it locate any printer with the specified string in it's name, and then in the Sub, you pass it the old name, and the new name, and the Sub will determine whether it was the default or not, and only set the new one default if it was.
3) To identify the printer's old and new names, I've added a dictionary object, so you can easily add and remove extra printers as required

I think that's it.

Try it out and see how it goes.

Regards,

Rob.
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20

Set objDictionary = CreateObject("Scripting.Dictionary")
objDictionary.Add "IMC-FDPtr1", "IMCFDPTR1 (2)"

Set objScriptExec = CreateObject("WScript.Shell")
Set objNetwork = CreateObject("WScript.Network")
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT Name FROM Win32_Printer WHERE Default=True", "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems
	For Each strOldName In objDictionary
		If InStr(objItem.Name,strOldName) <> 0 Then SetIMCFDPTR1 objItem.Name, objDictionary(strOldName)
	Next
Next
WScript.Quit

Sub SetIMCFDPTR1(strPrinterName, strNewName)
	Set objShell = CreateObject("WScript.Shell")
	objShell.Run "C:\Support\SetACL\x64\SetACL.exe -on """ & strPrinterName & """ -ot prn -actn setowner -ownr ""n:" & objNetwork.UserDomain & "\" & objNetwork.UserName &";""", 0, True
	objShell.Run "C:\Support\SetACL\x64\SetACL.exe -on """ & strPrinterName & """ -ot prn -actn ace -ace ""n:" & objNetwork.UserDomain & "\" & objNetwork.UserName & ";p:man_printer""", 0, True
	
	Set colItems = objWMIService.ExecQuery("SELECT Name,Default FROM Win32_Printer WHERE Name='" & strPrinterName & "'", "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
	For Each objPrinter In colItems
		blnDefault = objPrinter.Default
		objPrinter.RenamePrinter(strNewName)
	Next

	If blnDefault = True Then
		Set colItems = objWMIService.ExecQuery("SELECT Name FROM Win32_Printer WHERE Name='" & strNewName & "'", "WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
		For Each objPrinter In colInstalledPrinters
			objPrinter.SetDefaultPrinter()
		Next
	End If
End Sub

Open in new window

0
 

Assisted Solution

by:NetManaged
NetManaged earned 0 total points
Comment Utility
RobSampson,

           After a minor adjustment on line 31 to change colInstalledPrinters to coltems, it worked great!
Added additional lines for objDictionary.Add with old and new printer names as needed!
Attached is the modified code with an additional dictionary entry for displaying how to add more printers (I was erroneously adding them on the same line).

WOOT! Thanks RobSampson!

Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20

Set objDictionary = CreateObject("Scripting.Dictionary")
objDictionary.Add "IMC-FDPtr1", "GOBBLE (632)"
objDictionary.Add "P2055", "clearfork" 

Set objScriptExec = CreateObject("WScript.Shell")
Set objNetwork = CreateObject("WScript.Network")
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT Name FROM Win32_Printer WHERE Default=True", "WQL", wbemFlagReturnImmediately + 

wbemFlagForwardOnly)
For Each objItem In colItems
	For Each strOldName In objDictionary
		If InStr(objItem.Name,strOldName) <> 0 Then SetIMCFDPTR1 objItem.Name, objDictionary(strOldName)
	Next
Next
WScript.Quit

Sub SetIMCFDPTR1(strPrinterName, strNewName)
	Set objShell = CreateObject("WScript.Shell")
	objShell.Run "C:\Support\SetACL\x64\SetACL.exe -on """ & strPrinterName & """ -ot prn -actn setowner -ownr ""n:" & 

objNetwork.UserDomain & "\" & objNetwork.UserName &";""", 0, True
	objShell.Run "C:\Support\SetACL\x64\SetACL.exe -on """ & strPrinterName & """ -ot prn -actn ace -ace ""n:" & 

objNetwork.UserDomain & "\" & objNetwork.UserName & ";p:man_printer""", 0, True
	
	Set colItems = objWMIService.ExecQuery("SELECT Name,Default FROM Win32_Printer WHERE Name='" & strPrinterName & "'", "WQL", 

wbemFlagReturnImmediately + wbemFlagForwardOnly)
	For Each objPrinter In colItems
		blnDefault = objPrinter.Default
		objPrinter.RenamePrinter(strNewName)
	Next

	If blnDefault = True Then
		Set colItems = objWMIService.ExecQuery("SELECT Name FROM Win32_Printer WHERE Name='" & strNewName & "'", "WQL", 

wbemFlagReturnImmediately + wbemFlagForwardOnly)
		For Each objPrinter In colItems 
			objPrinter.SetDefaultPrinter()
		Next
	End If
End Sub

Open in new window

0
 
LVL 65

Expert Comment

by:RobSampson
Comment Utility
Great. No problem. Thanks for the grade.  I'm glad you were able to make sense of my modifications.

Regards,

Rob.
0
 

Author Closing Comment

by:NetManaged
Comment Utility
RobSampson really helped me!
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

My previous article  (http://www.experts-exchange.com/OS/Microsoft_Operating_Systems/Server/Windows_Server_2008/A_4466-A-beginners-guide-to-installing-SCCM2007-on-Windows-2008-R2-Server.html)detailed one possible method to get SCCM 2007 installed an…
This is my 3rd article on SCCM in recent weeks, the 1st (http://www.experts-exchange.com/OS/Microsoft_Operating_Systems/Server/Windows_Server_2008/A_4466-A-beginners-guide-to-installing-SCCM2007-on-Windows-2008-R2-Server.html) dealing with installat…
This video discusses moving either the default database or any database to a new volume.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

762 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

6 Experts available now in Live!

Get 1:1 Help Now