Before I get started on this blog, this is actually an article I wrote in 2008 I never did anything with. Some of the wording in the article is a bit funky but ultimately the reason this exists is not just to show how to use the UCCE Bulk Import Tools. Some of the bulk tools rely on ID’s created by previous bulk tools. Coming with this tutorial are a set of very small perl scripts you can use/modify to help you gather these ID’s and insert them into you flat files.

All scripts can be FOUND HERE


I came to a bridge I needed to cross in order to build a test bed for Load Testing a client application. When no backups were available of a large enterprise, I decided to create my own.

The document’s purpose is to be a simple all around learning tool that can show the power of automated configuration. We will investigate the power of Perl to generate the imports, a very simple yet powerful programming language based around text manipulation and creation. Also, it will serve as a guide to successfully creating ICM Bulk Configuration Files and an ordered approach to make this easier.

While there are many moving parts to this document, the only part we can understand without understanding anything else, is Perl as a language. The Application we have written to generate the import files for ICM Bulk Configuration Utilities is a very simple application. The goal is to make a customized enterprise environment on the fly. By setting some user defined variables for customization and creating 1 small processing loop, we can quickly create the necessary import files necessary to complete our task at hand. I will go over the application’s source code to show how and why it generates what it does.



Here is the best part about Perl; there is only 1 type of single element variable, the Scalar. Think of the Scalar as a one variable type fits all. It can contain integers or strings! Also it does automatic conversion of string to integers and vice versa on the fly. Therefore if you recover the number ‘5’ as a string you can happily add it to the integers of 6. Lastly, the Scalar is defined with a $ sign.

My $string = ‘5’;  Initialize a string into a Scalar denoted with ‘  ‘
My $Integer = 6;  Initialize an integer into a Scalar
My ($Result); Define a variable is allowed to be used

$Result = $string + $Integer;  add a string to an integer

$Result  = 11

As you can see Perl is variable powerful since there is no need to deal with data type. There are also Arrays and Hash’s in Perl but they are outside the scope of my simple document.



use strict;    (OPTIONAL) This tells Perl that all variables must be initialized before using them.


In our test bed we are aiming to load test a simulated environment of 300 agents. Also I have always been interested if ICM could actually handle a 300 Person skill group with everyone logged in and taking the calls of a single dialled number, so we are going to try that approach. That being said lets look at the snippet of our code doing user defines in Perl.

my $AgentTotalToAdd = 300;  			    Number of agents to add
my $StartDNForAgents = 7000;			    Start DN
my $DeviceParameter = '/devtype ciscophone /DN ';   Device Target Configuration Parameter
my $AgentFirstName = 'John';			    Generic First Name
my $AgentLastName = 'Doe';			    Generic Last Name
my $CMPGPID = 5001;				    CM PG Peripheral ID
my $CMPGNAME = 'CM.';				    Name of CM Pg for Enterprise Names
my $VRUPGPID = 5000;				    VRU Peripheral ID
my $LabelType = 'Normal';			    Label Type for Device Targets
my ( $i , $AgentDN , $AgentID ); 		    Initialize Variables (refer to 2.3.1)
my ( @AgentName );				    Initialize Array (refer to 2.3.1)


As with any programming language it’s highly useful for login and data input to be able to read files in and out. In Perl they give us a very easy way of doing this. Please note in the example below, the files will only be opened if they are in the same directory, if you want to locate files in other directories please point to the raw paths (C:\Program Files\Stuff\Things…). The last point to notice in the value below is the significance of the “>” sign.

> Signifies that you are OUTPUTING to a file. (Used for outputting data)
< Signifies that you are TAKING INPUT FROM A FILE to the Perl Interpreter. (Used for inputting data)

open(ICMDEVTARGET, ">DeviceTargetsFinal.txt");          Open/Create File and use ICMDEVTARGET as a pointer to the file
open(ICMLABEL, ">LabelIntermediary.txt");
open(ICMPERSON, ">PersonFinal.txt");
open(ICMAGENT, ">AgentIntermediary.txt");


Below, the for loop tells the program to do 300 iterations which will effectively create 300 agents worth of configuration files (Each iteration represents a single Agent). Note its getting the 300 from the User Defines section. It then increments the DN by one each time through the loop so each agent has a new DN 1 higher in sequence (#2). Next it creates the name of the Agent for the Agent’s Enterprise name. It does this by concatenating 2 strings together. A Period in Perl represents a concatenation character (#3). Lastly, in the print lines of the program, we are writing our data to out Files. Its good to note in the examples below “\t” is a tab as ICM asks for Tab Delimited Files.

for($i = 0; $i < $AgentTotalToAdd; $i++){ 
      $AgentDN = $StartDNForAgents + $i;
        $AgentName[$i] = $AgentFirstName . "_" . $AgentLastName . $i;
	print ICMDEVTARGET "$AgentDN\t$AgentDN\t$DeviceParameter$AgentDN\n";
	print ICMLABEL "$AgentDN\t$CMPGPID\t$LabelType\t$AgentDN\n";
	print ICMLABEL "$AgentDN\t$VRUPGPID\t$LabelType\t$AgentDN\n";
	print ICMPERSON "$AgentFirstName\t$AgentLastName$i\t$AgentDN\t$AgentDN\n";
	print ICMAGENT "$CMPGPID\t$AgentDN\t$AgentDN\t$CMPGNAME$AgentName[$i]\n";

3 Bulk Imports

We will be running a series of imports in an ordered manner to ensure the smoothest flow of imports. We will also have to run two utilities to make this truly automated, without having to select a ton of manual entries. We will follow the steps as listed in order, and in the end we will have an ICM with 300 fully working agents configured. The other thing this document will help you understand is some of the SQL to Configuration Manager naming a Mapping convention.


The reason we import the Device Targets first is that they have no other dependencies on any other part of the ICM configuration, meaning that it’s a great place for us to start importing. There were 3 Fields that were created by my tool; they are listed below as you will find them in Device Target Bulk Insert.

1. Enterprise Name – Self Explanatory
2. Global Address – Self Explanatory
3. ConfigParam – Self Explanatory

Figure 1 Bulk Device Target Insert Tool

Click OK then Click Save on the box behind it to finish the import



Many may be wondering why we even need this utility. Well the answer is simple. Bulk Label Insert tool requires a field titled “NetworkTargetID” and this ID represent the DeviceTarget. The annoying thing about this is that the ID is randomly generated and not recoverable anywhere in ICM except directly in SQL (It can’t be found in Configuration Manager). It is located in the t_Deivce_Target Table. Now since it’s randomly generated, and it could be ordered all over the place, we can recover it manually and then work around the import file in Excel, but with a 300 Agent system, it may take awhile. What we do in the following is to use a utility I wrote that works with my import set that basically takes in our “DeviceTargetsFinal.txt” and uses that file to query the ICM SQL for the correct NetworkTargetID, it then appends this information in the right places to “Labelntermediary.txt” and creates our actual import file for ICM “LabelFinal.txt”.

I have also included the source code of this tool, but I will not go through the source code as it touches on way to many concepts for a non Perl coder, but would serve as a good reference for someone who is learning Perl.


Basically you need to create a directory anywhere on the ICM server and have the following files in it.

Figure 2 ICM Folder Screenshot

From here you will have local access to the SQL server without having to create an ODBC hook on another box. (NOTE: In this document we chose to install the Perl Interpreter on ICM for development, but in an actual customer environment we defiantly want to use a tool like ActiveState Perl or Perl2exe.exe to create and Executable file from the Perl script. This way we don’t have to install anything that’s potentially harmful on the ICM Server.)

After this we just double click either the Perl script or the Exe we made, and you will see a LabelFinal.txt appear. We will use this file to import our labels!!


Now that we have our nice perfectly generated file from our tool used in the last section we should it, since all the labels depend on in ICM is our Device Targets. Our “LabelFinal.txt” file includes 5 fields in it. The Fields are as follows.

1. NetworkTargetID – This is the ID that our tool in the previous Section Recovered, it’s a reference to the corresponding Device Target/DN.
2. Label – This is our DN for the agent we need the label for.
3. RoutingClientID – This is the Peripheral ID of our CM PG.
4. LabelType – Self Explanatory, we will use “Normal” in this document.
5. Description – Self Explanatory

Figure 3 Bulk Label Insert

Click OK then Click Save on the box behind it to finish the import


Next we insert the Person Import with the “PersonFinal.txt” File. The person import is very straight forward and asks for 4 fields.

1. First Name – Self-Explanatory
2. Last Name – Self-Explanatory
3. Login Name – Self-Explanatory
4. Password – Self-Explanatory

Figure 4 Bulk Person Insert Tool

Click OK and the Save on the next box to finish the Import.



Like the other tool we created and used in Section 3.3, we will address a pitfall of the Bulk Utilities again. This time We have to recover “PersonID” from the t_Person table and the AgentDeskSettingsID from the t_Agent_Desk_Settings table. (NOTE: Make sure to update the name of the AgentDeskSetting you would like to use within the user defines. Refer to Section 2.3.2 if you forgot how to manipulate User Defines. I will not go into the technical details of this script, as it’s even a bit more complex then the previous one just set it up the same way we did before, and run the script or exe. (Figure 2 and Section 3.3.2)

After you run the application the “AgentFinal.txt” will appear and this will be our final import file to run before our test environment is complete!


The Agent Import we just created has 6 fields inside it. They are as follows.

1. PersonID – This is the ID that corresponds to the Person we created in the Previous Person Imports, our tool ( Address’s this
2. AgentDeskSettingsID – This is the ID that corresponds to the AgentDeskSettings we would like to use
3. PeripheralID – This is the PeripheralD of the CM PG.
4. Peripheral Number – This is the AgentID in the Configuration Manager.
5. Peripheral Name – Self-Explanatory
6. Enterprise Name – Self-Explanatory

Figure 5

Click OK and Save on the next box the Import is complete.

There are 3 small tasks left to complete a load testing environment

1. Associate all newly created agents to an Agent Team.
2. Associate all newly create agents to a Skill Group
3. Create a small script to route calls into the skill group.

I will assume for this document that anyone that is reading this should have enough knowledge about ICM to know what I’m talking about, as the rest of the document was focused at more advanced methods anyways.

ICM is a buggy little system, but with the tools provided and my small insight into the database of ICM, people should be able to figure out most quirks. It should give everyone the information necessary to correctly use the Bulk Import utilities for ICM, even though Cisco tried their hardest to make them unusable. I hope everyone enjoyed it and feel free to contact me at with any questions about ICM Bulk Configuration.