Scripting MetaFrame Data Store Printer Mapping

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 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>

Join the conversation

2 comments

Send me notifications when other members comment.

Please create a username to comment.

This message was originally posted by stefan on June 28, 2004
A nice way, if you want to built printer stuff from scratch, in a poluted data store. (usually inherited by a previous clueless admin)
My compliments.
Cancel
Maybe I'm reading this wrong, but kind of weird that inputfile is "Client -> Server" and logfile is "Server -> Client".  Not a big deal, just something to be aware of for consistency's sake.  Just swap "sDriver" and "cDriver" in the writelog section.  Also looks like delmap writes as "Server -> Client" and it's mentioned you can use this as an input for addmap.  It's just... Backwards.
Cancel

-ADS BY GOOGLE

SearchVirtualDesktop

SearchEnterpriseDesktop

SearchServerVirtualization

SearchVMware

Close