In part 1, we defined the location levels and we built the location tree. After that we tried to tell the Scense runtime system how it can determine the location for a certain computer and we saw that that’s not an easy task. In part 2 we try to achieve more accuracy on locating computers using external data.
As the name ‘Location Services’ suggests there is more than one location service. The first one evaluates the scopes on the location objects. The second one tries a different approach. Where scopes are very useful for testing data in a fixed way, like testing if an IP-address is within a subnet mask, or if a variable has a certain value, they quickly lose their value when there’s a need for a more flexible way of testing. That’s where Pattern Matching comes in. Pattern matching is about testing if a certain value matches an existing location. Setting this up can be somewhat complex, but it’s worth the trouble.
To configure pattern matching we need at least 3 things:
A pattern source
This is (external) data that contains an (encoded) location. Useful pattern sources can be: Computer names, configuration management databases, network administration databases, other (manually updated) databases or lists that contain location data for computers.
A pattern is an algorithm that describes how the data in the pattern source relates to the location codes. This algorithm can be created relatively easy using the pattern builder in Scense Explorer.
Each location object in the location tree can be given a code. E.g. ‘Floor 1’ gets code ‘1’. When all location objects get such a code, then automatically each location can be addressed with the hierarchical concatenation of these codes. Big words for something simple as the location codes example below will show.
The pattern source
First we need a pattern source. As mentioned before; this is a data source containing encoded location data for computers. Some administrators like to encode the location in the computer name, e.g. like this:
A computer name ‘ WS01020131 ‘ might contain the following information:
WS it’s a workstation
01 Building 1
02 2nd floor
01 Room 1
31 just a sequence number to make it unique.
In this case the pattern source would be the computer name (which is actually the default in the pattern builder). One might argue that using the computer name to encode location data is not very efficient because each time a specific computer is moved to another room; the computer name has to be changed. So, it’s probably better to use some sort of database where administrators keep track of computer locations. As noted above, this will most likely be a configuration management database but it might as well be just a file.
Once we established our pattern source we need to identify the pattern elements. This means we have to answer the question; what codes are used for locations? E.g. what code belongs to Room 1 on the 2nd floor in Building 2? This can be anything, but most likely it’s a logical one like ‘221’ or ‘020201’ or ‘2201’ or ‘2-02-01’ etc. As long as the pattern consists of elements that mean something.
We have chosen the following encoding: B-F-R, which is equal to the way the location data is actually stored in our text file (workstations.txt somewhere on the network).
Position 1 (B) Building
Position 2 (-) Just a separator
Position 3 (F) Floor
Position 4 (-) Another separator
Position 5 (R) Room
So, 2-1-2 would mean: Building 2, Floor 1, Room 2.
The next thing we need to do is to make sure all location objects have the correct location code. It is essential that the location codes in the location objects are identical to the ones used in our pattern source. (There are ways to do translation, but that would make things really complex for this article).
So, Building 1 would get location code ‘1’, Building 2 would get location code ‘2’.
Next, Floor 1 gets code ‘1’ regardless of the building it’s in, just like all 2nd floors get location code ‘2’.
The rooms are coded accordingly: all Rooms 1 get code ‘1’ and all Rooms 2 get code ‘2’.
After all locations have their codes we can see the ‘location pattern’ for a location in Scense Explorer;
The location pattern in the property page above shows the location codes of all parent locations and the current one: 212, meaning Building 2, 1st floor, Room 2. We can already see how this location pattern resembles the encoding in the pattern source.
Accessing the pattern source
Now we have to solve a problem; how can Scense access our pattern source? We happen to have a text file that contains a list of workstations and location codes, but the pattern builder only supports a variable to represent the pattern source. So, how do we go from a variable to actually reading our text file?
First of all; we should seriously consider replacing our text file for a high performance store, like e.g. the Scense database. There are several reasons why a file on a server is not recommended:
- Reading from a file requires access to the location of the file through SMB, which is probably only usable within the corporate network.
- Reading from a file requires: the file… And if the file is not available for some reason then the pattern matching (and everything that depends on it) will fail.
- Reading from a Microsoft Office file (Excel, Access) requires Microsoft Office, which might not be available on all workstations.
- Reading from a file will give concurrency issues, probably starting when there are 50 workstations or more.
- Reading from a file is no match for a database (MSSQL, Oracle) when it comes to performance.
Besides the disadvantages of a file, there are several advantages when using a database system; like speed, data integrity and security.
So, what should we do with the text file? This is what we did;
- We created a new table in the Scense database called ‘usLocations’.
We chose to use the ‘us’ prefix to make it clear that this is a user table and not a Scense table.
- Our text file had 2 columns: Workstation and LocationCode. So in the table we created these exact columns and we made the Workation column the primary key.
- To make sure the Scense system can access this table we granted read access to this new table to both the ‘scense’ and the ‘scenseadmin’ database users. If you’re using Windows integrated security you should grant the ‘Scense Database Users’ group the read access rights.
- Next, we copied and pasted the entire file in the newly created table.
Now the location data is accessible for the Scense Client, but it’s no longer accessible for easy manual updates. This is easily solved by creating an MS Access database in which we linked the ‘usLocations’ table from the Scense database. So, now we can update the list on our workstations just like we always did, but now using MS Access. The difference, of course, being that the data is no longer free text, but managed data instead. This has the advantage that it’s no longer possible to have double entries etc.
Now that the pattern source is available to the Scense Client we need to build the algorithm in the pattern builder. As mentioned before, the pattern builder requires the pattern data to come from a variable, and there’s currently no variable that will give us the required data. So we have to create one.
The Scense runtime system supports function-variables. A function variable is really a scripted routine which can be called as if it were a variable.
The syntax for such a function variable is like this: %Function://functionname% .
The function below will retrieve the location code for the current workstation from the ‘usLocations’ table in the Scense database using the ‘UserDBRead’ method.
We have stored this function as a Scripting Action inside the ‘\Scense System\Script Container\Function Scripts’ folder and named it ‘GetLocationCode’. We now have effectively created a variable; a function variable that can be specified like this: %Function://GetLocationCode% .
The pattern algorithm
In the Pattern Matching Manager we add a new pattern and specify a name and our new variable.
Because all necessary location ‘plumbing’ has been done, we can immediately see the function variable begin to work after we typed its name in the pattern source input field. The workstation we’re currently creating this pattern on is in the database table and we see the correct location code being displayed as the ‘test source value’. The value ‘1-2-2’ comes directly from the database table.
Now we need to create the algorithm, or rather; we have to tell the algorithm how it should match the pattern. For this we need to add elements. Our location code contains 3 elements: Building, Floor and Room. So, we need to add 3 elements, starting with the Building. To do this we click ‘Add element’ and configure it on the right side of the window. This element represents the Building level, so we pick ‘Building’ from the location level selector. Next we configure the position in the location code that represents the building level; it starts on position 1 and has a length of 1. The easiest way of doing this is to simply select the correct position in the ‘test source value’, then the start position and the element length will be automatically set. Don’t forget to click the ‘Store element’ button. We repeat this for the Floor and Room levels.
After we created the 3 levels and they show up correctly in the pattern elements list on the left, then we can click the ‘Test’ button and see if it correctly identifies the location. We’re satisfied with the results, so we OK our way out of these dialogs and we are finished setting up pattern matching. It is a bit of work to set this up, but fortunately it’s a one time job. Our location system can now determine the room in which a computer is located. A huge improvement over the location configuration we did in part 1.
In part 3 we will take a look at proper runtime usage of the Location Services.