by
Ron Oglesby
This article is the third in Ron Oglesby’s “Scripting for MetaFrame” series.
In this series of articles I focus on how you can use scripting in a Terminal Server or Citrix MetaFrame environment to automate common and recurring tasks. This article shows a script that uses MFCOM to bulk delete all of the printer mappings out of the MetaFrame data store.
This script is generally used when you’re trying to clean up your environment. It was originally written for a farm that had an enormous list of printer driver mappings (over 1000) that needed to all be deleted to start fresh with a new mapping file. Deleting each of these mappings one at a time via the Citrix Management Console was out of the question, so we created two scripts to do it for us. The first deletes all the mappings from the data store, and the second re-importes a list of mappings from a text file. This allowed us to create a “gold” list of mappings, clean out the old garbage, and import our new mappings—all in a few minutes.
In this article we’ll take a close look at the script that deletes the mappings. Later in the article I’ll provide you with both the DelMap and AddMap scripts, but since they’re so similar I’ll explain only one of them but give you both. (Hey! A two for one... How cool is that?). Let’s get started by looking at the first section of our script:
<package>
<job id="Print Driver Mappings">
<comment>
File: DelPMap.wsf
Description: Deletes all Print Driver Mappings from the MetaFrame
farm Data Store.
Requirements: WSH 5.5 or higher.
</comment>
<runtime>
<description>
Deletes all Print Driver Mappings from the MetaFrame farm Data Store.
on MetaFrame Servers in the farm. It will save current mappings
in the OutPutFile for later use.
</description>
<example> CScript //nologo DelPMap.wsf
</example>
</runtime>
<reference object="MetaFrameCOM.MetaFrameFarm"/>
<script language="VBScript">
As you can see this is a WSF script using basic VBS. You can execute the script by using the “cscript” interpreter. Now let’s declare our variables. Nothing out of the ordinary here.
Dim fso, f, ts, LogFileName, OutPutFileName
Dim theFarm, theMappings, Map, sDriver, sPlatform, cDriver
Once the variables are declared we create (or connect to) the FileSystemObject. This will be used later on for logging purposes and to output the “old” mappings to a file for later retrieval.
Set fso = CreateObject("Scripting.FileSystemObject")
The first logic in the script parses the command line looking for an argument. The syntax of this script requires that you specify and output file to dump the current mappings to.
'*****************************************************
'Parse the command line
'*****************************************************
Set Args = Wscript.Arguments
If Not Args.Count = 1 Then
Wscript.Echo "Usage: DelPMap.wsf OutPutFile"
Wscript.Quit
End If
Once we notice the argument we then create the output file if it doesn’t exist.
'*****************************************************
'create the OutPut file if it doesn't exist
'*****************************************************
OutPutFileName = Args(0)
If Not fso.FileExists(OutPutFileName) Then
fso.CreateTextFile(OutPutFileName)
End If
Set f = fso.GetFile(OutPutFileName)
Set ts = f.OpenAsTextStream(8, -2)
ts.WriteLine(Now & " - Delete this line before using as an input file")
ts.WriteLine("Server Driver=Client Driver - Delete this line before using as an input file")
ts.close
If you notice we write a line “Server Driver=Client Driver - Delete this line before using as an input file")” This file will be written to the text file to let the next person running an AddMap script to delete the line before using this as an input file for importing printer mappings into the datastore.
Once the output file is created we then configure our log file name and create it. As you can see, this example is hardcoded to C:. This is sloppiness on my part. :-)
'*****************************************************
'define the log file name here
'*****************************************************
LogFileName = "c:\DelPMap.txt"
'*****************************************************
'create the log file if it doesn't exist
'*****************************************************
If Not fso.FileExists(LogFileName) Then
fso.CreateTextFile(LogFileName)
End If
Set f = fso.GetFile(LogFileName)
Set ts = f.OpenAsTextStream(8, -2)
ts.WriteLine
ts.WriteLine(Now)
ts.WriteLine("Server Driver=Client Driver, Success/Failure")
ts.close
Now that our log files and output files are created we then begin to access the MetaFrame farm object:
'*****************************************************
' Create MetaFrame Farm Object
'*****************************************************
Set theFarm = CreateObject("MetaFrameCOM.MetaFrameFarm")
if Err.Number <> 0 Then
WScript.Echo "Can't create MetaFrameFarm object"
WScript.Echo "(" & Err.Number & ") " & Err.Description
WScript.Quit Err.Number
End if
Then we initialize the farm:
'*****************************************************
' Initialize the farm
'***************************************************** '
theFarm.Initialize(MetaFrameWinFarmObject)
if Err.Number <> 0 Then
WScript.Echo "Can't Initialize MetaFrameFarm object"
WScript.Echo "(" & Err.Number & ") " & Err.Description
WScript.Quit Err.Number
End if
After that we verify that the current user executing the script is a citrix administrator. If not, the functions in the script will fail so we want to stop it here. Also (if haven’t noticed yet) this format so far follows the examples in the Citrix SDK pretty closely. (You can download the SDK for free from the Citrix Developer Network.)
'*****************************************************
' Check Citrix Admin Credentials
'*****************************************************
if theFarm.WinFarmObject.IsCitrixAdministrator = 0 then
WScript.Echo "You must be a Citrix admin to run this script"
WScript.Quit 0
End If
Now that all that beginning stuff is out of the way the script gets more interesting. First, we initialize the PrintDriverMappings within the farm. If we can’t access the mappings the script quits. After that we start a simple FOR loop. For each print driver mapping it finds in the farm, it gathers the following information:
- Server driver name
- Server driver platform
- Client driver name
We then delete the mapping and write it to the output file in this format:
ServerDriverName=ClientDriverName
This is the same format that can be used as an input file for the script that re-adds the mappings.
'*****************************************************
' Read and delete the driver mapping
'***************************************************** '
set theMappings = theFarm.WinFarmObject.PrinterDriverMappings
if Err.Number <> 0 Then
WScript.Echo "Can't Initialize PrintDriverMappings object"
Wscript.Echo "(" & Err.Number & ") " & Err.Description
Wscript.Quit Err.Number
End If
For each Map in theMappings
sDriver = Map.ServerDriverName
sPlatform = Map.ServerDriverPlatform
cDriver = Map.ClientDriverName
' wscript.echo sDriver & ", " & sPlatform & ", " & cDriver
Map.Delete
Set f = fso.GetFile(OutPutFileName)
Set ts = f.OpenAsTextStream(8, -2)
ts.WriteLine(sDriver & "=" & cDriver)
ts.close
If Not Err.Number = 0 then
Next, we have a IF statement that checks for success or failure and writes it to the log file.
'*****************************************************
'write failure into log file
'*****************************************************
Set f = fso.GetFile(LogFileName)
Set ts = f.OpenAsTextStream(8, -2)
ts.WriteLine(sDriver & "=" & cDriver & " Mapping Deletion Failure ****")
ts.close
Else
'*****************************************************
'write success into log file
'*****************************************************
Set f = fso.GetFile(LogFileName)
Set ts = f.OpenAsTextStream(8, -2)
ts.WriteLine(sDriver & "=" & cDriver & " Mapping Deletion Successful")
ts.close
end if
Next 'Map
'*****************************************************
'End the Script
'*****************************************************
WScript.Echo "Script Complete, Log file written to: " & LogFileName
</script>
</job>
</package>
At the end of the script we simply echo that the script is complete and show the user the log file location. A great thing you can do with this is to get a new mapping list together, test it, make sure its perfect, then (in a matter of minutes) completely clean up your old mappings and replace them with new ones.
Below you’ll find the complete code for both the DelMap and AddMap scripts. Happy scripting!
<package>
<job id="Print Driver Mappings">
<comment>
File: DelMap.wsf
Description: Deletes all Print Driver Mappings from the MetaFrame
farm Data Store.
Requirements: WSH 5.5 or higher.
</comment>
<runtime>
<description>
Deletes all Print Driver Mappings from the MetaFrame farm Data Store.
on MetaFrame Servers in the farm. It will save current mappings
in the OutPutFile for later use.
</description>
<example> CScript //nologo DelPMap.wsf
</example>
</runtime>
<reference object="MetaFrameCOM.MetaFrameFarm"/>
<script language="VBScript">
Dim fso, f, ts, LogFileName, OutPutFileName
Dim theFarm, theMappings, Map, sDriver, sPlatform, cDriver
Set fso = CreateObject("Scripting.FileSystemObject")
'*****************************************************
'Parse the command line
'*****************************************************
Set Args = Wscript.Arguments
If Not Args.Count = 1 Then
Wscript.Echo "Usage: DelPMap.wsf OutPutFile"
Wscript.Quit
End If
'*****************************************************
'create the OutPut file if it doesn't exist
'*****************************************************
OutPutFileName = Args(0)
If Not fso.FileExists(OutPutFileName) Then
fso.CreateTextFile(OutPutFileName)
End If
Set f = fso.GetFile(OutPutFileName)
Set ts = f.OpenAsTextStream(8, -2)
ts.WriteLine(Now & " - Delete this line before using as an input file")
ts.WriteLine("Server Driver=Client Driver - Delete this line before using as an input file")
ts.close
'*****************************************************
'define the log file name here
'*****************************************************
LogFileName = "c:\DelPMap.txt"
'*****************************************************
'create the log file if it doesn't exist
'*****************************************************
If Not fso.FileExists(LogFileName) Then
fso.CreateTextFile(LogFileName)
End If
Set f = fso.GetFile(LogFileName)
Set ts = f.OpenAsTextStream(8, -2)
ts.WriteLine
ts.WriteLine(Now)
ts.WriteLine("Server Driver=Client Driver, Success/Failure")
ts.close
'*****************************************************
' Create MetaFrame Farm Object
'*****************************************************
Set theFarm = CreateObject("MetaFrameCOM.MetaFrameFarm")
if Err.Number <> 0 Then
WScript.Echo "Can't create MetaFrameFarm object"
WScript.Echo "(" & Err.Number & ") " & Err.Description
WScript.Quit Err.Number
End if
'*****************************************************
' Initialize the farm
'***************************************************** '
theFarm.Initialize(MetaFrameWinFarmObject)
if Err.Number <> 0 Then
WScript.Echo "Can't Initialize MetaFrameFarm object"
WScript.Echo "(" & Err.Number & ") " & Err.Description
WScript.Quit Err.Number
End if
'*****************************************************
' Check Citrix Admin Credentials
'*****************************************************
if theFarm.WinFarmObject.IsCitrixAdministrator = 0 then
WScript.Echo "You must be a Citrix admin to run this script"
WScript.Quit 0
End If
'*****************************************************
' Read and delete the driver mapping
'***************************************************** '
set theMappings = theFarm.WinFarmObject.PrinterDriverMappings
if Err.Number <> 0 Then
WScript.Echo "Can't Initialize PrintDriverMappings object"
Wscript.Echo "(" & Err.Number & ") " & Err.Description
Wscript.Quit Err.Number
End If
For each Map in theMappings
sDriver = Map.ServerDriverName
sPlatform = Map.ServerDriverPlatform
cDriver = Map.ClientDriverName
' wscript.echo sDriver & ", " & sPlatform & ", " & cDriver
Map.Delete
Set f = fso.GetFile(OutPutFileName)
Set ts = f.OpenAsTextStream(8, -2)
ts.WriteLine(sDriver & "=" & cDriver)
ts.close
If Not Err.Number = 0 then
'*****************************************************
'write failure into log file
'*****************************************************
Set f = fso.GetFile(LogFileName)
Set ts = f.OpenAsTextStream(8, -2)
ts.WriteLine(sDriver & "=" & cDriver & " Driver Mapping Deletion Failure ******* ")
ts.close
Else
'*****************************************************
'write success into log file
'*****************************************************
Set f = fso.GetFile(LogFileName)
Set ts = f.OpenAsTextStream(8, -2)
ts.WriteLine(sDriver & "=" & cDriver & " Driver Mapping Deletion Successful")
ts.close
end if
Next 'Map
'*****************************************************
'End the Script
'*****************************************************
WScript.Echo "Scipt Complete, Log file written to: " & LogFileName
</script>
</job>
</package>
Here is the AddMap script and a sample input file for it. Notice that the input file has no quotes around the driver names. It’s simply a client driver name followed by an equal sign and a server driver name. The output from the DelMap listed above creates a file exactly like this. In addition, you could modify the DelMap script so it DOESN’T delete the mappings and instead just records them to the output file. This will then allow you to edit the text file and get ready for the deletion and re-importation for the mappings.
Input file sample:
HP LaserJet 4/4M=HP LaserJet 4
HP LaserJet 4P/4MP=HP LaserJet 4P
HP LaserJet 4 Plus/4M Plus=HP LaserJet 4 Plus
HP LaserJet 4Si/4Si MX=HP LaserJet 4Si
HP LaserJet 4V/4MV=HP LaserJet 4V
HP LaserJet 5/5M - Enhanced=HP LaserJet 5
HP LaserJet 5/5M - Standard=HP LaserJet 5
AddMap.wsf Script
<package>
<job id="Print Driver Mappings">
<comment>
File: AddMap.wsf
Description: Adds Print Driver Mappings to the MetaFrame farm Data Store.
Requirements: WSH 5.5 or higher.
</comment>
<runtime>
<description>
Adds Print Driver Mappings to the MetaFrame farm Data Store.
</description>
<example> CScript //nologo AddPMap.wsf InputFile
InputFile must be in the format ClientDriver=ServerDriver
with no spaces around the equals sign
</example>
</runtime>
<reference object="MetaFrameCOM.MetaFrameFarm"/>
<script language="VBScript">
Dim fso, f, ts, LogFileName, Args, InputFileName, eqCount
Dim theFarm, theMap, sDriver, sPlatform, cDriver, OSVer
set fso = CreateObject("Scripting.FileSystemObject")
OSVer = "1"
'*****************************************************
'Parse the command line
'*****************************************************
Set Args = Wscript.Arguments
If Not Args.Count = 1 Then
Wscript.Echo "Usage: AddPMap.wsf InputFile"
Wscript.Quit
End If
'*****************************************************
'Verify Input File
'*****************************************************
InputFileName = Args(0)
If Not fso.FileExists(InputFileName) Then
Wscript.Echo "The input file is not found."
Wscript.Echo "Usage: AddPMap.wsf Inputfile"
Wscript.Quit
End If
'*****************************************************
'define the log file name here
'*****************************************************
LogFileName = "c:\AddPMap.txt"
'*****************************************************
'create the log file if it doesn't exist
'*****************************************************
If Not fso.FileExists(LogFileName) Then
fso.CreateTextFile(LogFileName)
End If
Set f = fso.GetFile(LogFileName)
Set ts = f.OpenAsTextStream(8, -2)
ts.WriteLine
ts.WriteLine(NOW)
ts.WriteLine("Server Driver=Client Driver, Success/Failure")
ts.close
'*****************************************************
' Create MetaFrame Farm Object
'*****************************************************
Set theFarm = CreateObject("MetaFrameCOM.MetaFrameFarm")
if Err.Number <> 0 Then
WScript.Echo "Can't create MetaFrameFarm object"
WScript.Echo "(" & Err.Number & ") " & Err.Description
WScript.Quit Err.Number
End if
'*****************************************************
' Initialize the farm
'***************************************************** '
theFarm.Initialize(MetaFrameWinFarmObject)
if Err.Number <> 0 Then
WScript.Echo "Can't Initialize MetaFrameFarm object"
WScript.Echo "(" & Err.Number & ") " & Err.Description
WScript.Quit Err.Number
End if
'*****************************************************
' Check Citrix Admin Credentials
'*****************************************************
if theFarm.WinFarmObject.IsCitrixAdministrator = 0 then
WScript.Echo "You must be a Citrix admin to run this script"
WScript.Quit 0
End If
'*****************************************************
' Create PrintDriverMappings object
'*****************************************************
set theMap = CreateObject("MetaFrameCOM.MetaFramePrinterDriverMapping")
if Err.Number <> 0 Then
WScript.Echo "Can't create PrintDriverMapping object"
Wscript.Echo "(" & Err.Number & ") " & Err.Description
Wscript.Quit Err.Number
End If
'*****************************************************
' Input and add the driver mapping
'***************************************************** '
Set objTextStream = fso.OpenTextFile(InputFileName, 1)
Do Until objTextStream.AtEndOfStream
Mapping = objTextStream.ReadLine
eqCount = InStr(Mapping, "=")
cDriver = Left(Mapping, (eqCount-1))
sDriver = Right(Mapping, (Len(Mapping)-eqCount))
theMap.ServerDriverName = sDriver
theMap.ServerDriverPlatform = OSVer
theMap.ClientDriverName = cDriver
theMap.Save
' wscript.echo cDriver & "=" & sDriver
If Not Err.Number = 0 then
'*****************************************************
'write failure into log file
'*****************************************************
Set f = fso.GetFile(LogFileName)
Set ts = f.OpenAsTextStream(8, -2)
ts.WriteLine(sDriver & "=" & cDriver & " Driver Mapping Addition Failed ******* ")
ts.close
Else
'*****************************************************
'write success into log file
'*****************************************************
Set f = fso.GetFile(LogFileName)
Set ts = f.OpenAsTextStream(8, -2)
ts.WriteLine(sDriver & "=" & cDriver & " Driver Mapping Addition Successful")
ts.close
end if
Loop 'objTextStream
objTextStream.Close
'*****************************************************
'End the Script
'*****************************************************
WScript.Echo "Scipt Complete, Log file written to: " & LogFileName
</script>
</job>
</package>
(Note: You must be logged in to post a comment.)
If you log in and nothing happens, delete your cookies from BrianMadden.com and try again. Sorry about that, but we had to make a one-time change to the cookie path when we migrated web servers.