Video Screencast Help

SEP Dynamic Grouping and Configuration Setup Tool

Created: 18 Apr 2013 • Updated: 20 Apr 2013 | 2 comments
Ludvik Jerabek's picture
+3 3 Votes
Login to vote

Over the course of the years I have seen large organizations looking for a quick way to deploy SEP to their hosts and have them placed in the correct group or even better have the group created dynamically. I have created a tool which allows a single package to be create for 32 and 64 bit windows hosts and will dynamically assign the group name as well as which SEP features to install.

This tool allows for a single package to be created that can be deployed to 64 and 32 bit servers and workstations. It’s also possible to configure the tool to detect different system roles such as DHCP server or Domain Controller and to allow custom groups and product features for those specific roles. The primary way grouping can also be done is via host naming convention. Most people who have used the tool based their detections on hostname tokens by using regex grouping and take actions on the parse tokens. All these configuration settings are done via an XML file. Unfortunately there is no official documentation that exists at the moment, however; the XML file is highly commented with a pre-defined example configuration.

From this point forward when the term “the script” is used it is referring to the sep_setup.vbs.

When the script loads there is a single entry point function called Main() initially it reads the sep_setup.xml using a custom class name ScriptConfig. The configuration object is used to read configuration data from the XML file in order to process all the necessary actions and set all process environment variables.

NOTE: In order to use the script it’s helpful to understand XPATH search strings and process level environment variables. It is not necessary to know VBScript, however; a basic knowledge of scripting or VBScript can be beneficial when there is a need for custom code execution via “actions” in the XML file. Custom actions were created to mitigate modifications to the sep_setup.vbs. These custom actions are defined as <CDATA> nodes with embedded VBScript which are dynamically loaded via the script’s ScriptConfig.custom_action method using the Execute command. This will be this will be discussed in further detail later in this document.

To help the user understand what is occurring internally the order of operations will be discussed.

The first three methods that are executed are:

  1. objConfig.process_os_info()
  2. objConfig.process_cpu_info()
  3. objConfig.process_role_info()

These methods set the environment variables defined in the <device-info /> XML node by querying WMI (See the sep_setup.xml for more details)

  • %os_prod_type %
  • %cpu_addrw_type%
  • %os_system_role%
  • %os_ver_major%
  • %os_ver_min%
  • %os_ver_rev%
  • %os_ver_ext%

After these initial environment variables are set the script executes a static action called “pre”. The action is static because it’s called by the script during every execution and not as the result of an XML setting. Three are two types of static actions “pre” and “post”. The pre action(s) occur before the call to process global-dynamic-map is performed. The “post” action(s) occur after all dynamic-map and group-map processing is completed. There are “post” action(s) responsible for manipulating the installer sylink.xml and setAID.ini installation properties in the sep_setup.xml.

  1. objConfig.process_custom_actions("pre")
  • Custom actions can be configured to require a successful outcome by setting the must_pass attribute of a <custom-action> node. If the attribute is set to true or 1 the value returned from the custom action must be custom_action=ERROR_SUCCESS, the constant ERROR_SUCCESS is equal to 0. Hence any other integer return value is considered an error.
  • Custom actions are processed by their type attribute of a <custom-action> node.
  • If multiple <custom-action> nodes exist with the same type attribute value they are processed in the order they are listed in the XML. If the must_pass attribute is set to true or 1 on any or all of the nodes that fail, no further processing of actions is performed.
  • Custom actions require a description attribute which is used during logging to identify the current executing action. See the example of a <custom-action> node below.

 

<custom-action type="pre" description="My Action Name" must_pass="false" >

<![CDATA[

<!-- Custom VBScript Content Goes Between CDATA -->

custom_action=ERROR_SUCCESS

]]>

</custom-action>

 

See the <custom-actions> section of the sep_setup.xml for more details.

 

After the “pre” actions are processed, the “global-dynamic-map” node is processed. The purpose of the global dynamic map is to translate values queried from WMI into more meaningful identifiers to be used at a later time. The reasoning behind this is to not restrict how that data can be used and processed. For example, the WMI object Win32_ComputerSystem has a DomainRole property. The call objConfig.process_role_info() (from step 3 above) sets the %os_system_role% process environment variable to the value of the Win32_ComputerSystem.DomainRole property. The value is an integer 0,1,2,3,4, or 5 based on current Microsoft Documentation.

 

  1. objConfig.process_dynamic_map( "/configuration/global-dynamic-map" )

 

  • XPATH search string(s) are defined in the criteria attribute of <dynamic-map> nodes.
  • It is possible to define multiple XPATH criteria by listing them separated by ';' as a delimiter
  • When multiple criteria are defined the tokens are processed from left to right until a match is found.
  • Once a match is found no further searching is performed for that <dynamic-map> node.
  • The matched node must have a value attribute which is used to set the environment variable name defined at the <dynamic-map> node’s map_to_env attribute.  In the event that no match is found the <dynamic-map> node’s default_value  is used instead. See the example below of a <dynamic-map> node used to remap the %os_system_role% environment variable.

<dynamic-map criteria="map[@key='%os_system_role%']" map_to_env="os_system_role" default_value="UNKNOWN" default_action="">

<map key="0" value="SW" />

<map key="1" value="MW" />

<map key="2" value="SS" />

<map key="3" value="MS" />

<map key="4" value="BDC" />

<map key="5" value="PDC" />

</dynamic-map>

 

  • The above example of a dynamic-map doesn’t utilize custom actions. However it is possible to execute a custom action on a matched criteria as well as if no criteria is matched.
  • The default_action  attribute of the <dynamic-map> node is only called if no criteria matches are found. Mapping nodes such as the <map> nodes show in the above example can have an action attribute which would execute a custom action upon a successful match. The action attribute should be assigned the action type name. Action type names are case sensitive and should match a type attribute of a <custom-action> node.

See the <dynamic-map> or <group-map> sections of the sep_setup.xml for more details on custom actions.

Once the global-dynamic-maps have been processed, the script’s process_dev_types method will attempt to determine if the hostname matches the defined pattern for a system type i.e. CLIENT, SERVER, etc.  The value CLIENT or SERVER is stored in the %os_prod_type% process environment variable which was remapped in the global-dynamic-map.

  1. objConfig.process_dev_types(host)

Since this section is highly subjective to personal needs, this behavior is not set in stone and can be overridden by manipulating the XPATH string assigned to the criteria attribute of the <dev-types> node. The default template provided by sep_setup.xml uses the following settings:

  <dev-types criteria="dev-type[@type='%os_prod_type%']" exit_on_unknown="false" reverse_lookup_on_fail="false" rcriteria="dev-type[@type='CLIENT'];dev-type[@type='SERVER']" r_map_to_env="os_prod_type" on_match_env="host_name_parsed" >

  • It is possible to trigger the script to exit if a match is not found via the exit_on_unknown property.
  • It is possible to force a reverse lookup if the forward criteria lookup fails.
    • This could occur if server OS is named with a workstation naming convention.
    • This could occur if workstation OS is named with a server naming convention.
    • WMI can’t query to determine the OS type.
  • Reverse lookup forcibly tests host regex patters for a match to set the system type.
  • In either case (forward or reverse lookup) the environment variable defined in the attribute on_match_env is set to 1 if a pattern was matched, otherwise 0. In the example above the %host_name_parsed% process environment variable is set.
  • The details of the attributes are fully documented in the sep_setup.xml template

 

The last two mapping methods called do additional dynamic mapping based on process environment variables created by previous mapping calls and device type detections. Device type host tokens are parsed into process environment strings and can be used in a multitude of ways to dynamically group and configure hosts. Truly the best way to understand these behaviors is to read the demo sep_setup.xml.

 

The value of objConfig.dyn_map is set to the value of the dynamic_map attribute of the matching <dev-type> node. The demo sep_setup xml file maps servers to "/configuration/server-dynamic-map" and clients to "/configuration/client-dynamic-map". In the case of unknown devices the value is set to “” and no dynamic map will be executed.

 

  1. objConfig.process_dynamic_map( objConfig.dyn_map )

 

The value of objConfig.group_mapper is set to the value of the group_mapper attribute of the matching <dev-type> node. The demo sep_setup xml file maps servers to "/configuration/server-group-map" and clients to "/configuration/client-group-map". In the case of unknown devices the value is set to "/configuration/unknown-group-map" so that unknown systems default group SEP group is set to “My Company\Default Group”

 

  1. objConfig.process_group_map( objConfig.group_mapper )

 

The “post” static action(s) are the last to be called. The sep_setup.xml file uses the post actions to update the proper 32 or 64 bit installers sylink.xml file and setAID.ini file. The template xml file clearly demonstrates how to set these values.

 

  1. objConfig.process_custom_actions("post")

 

The installation is executed with the reconfigured sylink.xml and setAID.ini files.

 

  1. Execute the SEP install and wait for exit

 

Steps for Preparing a Package for Testing

 

  1. Export 32bit default install package (not a single exe)
  2. Export 64bit default install package (not a single exe)
  3. Move contents to their respective folder
  4. Test sep_setup.vbs via command line
  5. Update sep_setup.xml
  6. Once testing is complete, package using make.cmd

 

Below we have unchecked the “Create single .EXE” all options for both 32 and 64 bit should be identical to what is seen below. The sep_setup script will modify the client group and can be used to manipulate which features are installed on various types of devices via the use of custom actions.

pkgexport.png

The contents of the install should be placed into the respective x64 and x86 folder under sep_setup\src  please see the example below:

x64.png

Testing the sep_setup.vbs via the command line

options.png

Once all testing is done to a satisfactory level the code must be packaged using the make.cmd under the root directory of the sep_setup. You can simply double click the file.

make.png

 

Once the process is complete you will have two binary installs one csinstall.exe the other wsinstall.exe these installers use cscript.exe and wscript.exe respectively.

wsinst.png

wsinstall.exe  is the one which should be packaged for distribution as it doesn’t open a command prompt when executing. csinstall.exe can be used for debugging the exe package with the previously mentioned command line arguments.

The contents of the sep_setup.7z are below:

sep_setup
|   make.cmd
|
+---bin
|   |   7za.dll
|   |   7zr.exe
|   |   7zS.sfx
|   |   7zS2.sfx
|   |   7zS2con.sfx
|   |   7zSD.sfx
|   |   7zxa.dll
|   |   history.txt
|   |   License.txt
|   |   readme.txt
|   |
|   +---FAR
|   |       7-ZipEng.hlf
|   |       7-ZipEng.lng
|   |       7-ZipFar.dll
|   |       7-ZipFar64.dll
|   |       7-ZipRus.hlf
|   |       7-ZipRus.lng
|   |       7zToFar.ini
|   |       far7z.reg
|   |       far7z.txt
|   |
|   +---ResHack
|   |       Dialogs.def
|   |       ReadMe.txt
|   |       ResHacker.cnt
|   |       ResHacker.exe
|   |       ResHacker.hlp
|   |       ResHacker.ini
|   |       Version_History.txt
|   |       win32.manifest
|   |
|   \---x64
|           7za.dll
|           7zxa.dll
|
+---release
+---res
|       7zSDnc.sfx
|       cscript_config.txt
|       wscript_config.txt
|
\---src
    |   sep_setup.vbs
    |   sep_setup.xml
    |
    +---x64
    \---x86
 

Comments 2 CommentsJump to latest comment

.Brian's picture

Thanks for sharing. Will run this in my test lab.

Please click the "Mark as solution" link at bottom left on the post that best answers your question. This will benefit admins looking for a solution to the same problem.

+1
Login to vote
Ludvik Jerabek's picture

I also plan on documenting the the helper classes and functions internally which can be called and used by custom actions.

std_hostfile - Allows for easy hostfile querying and editing
std_registry - Allows for local and remote registry manipulation encapsulates all WMI
std_process - Allows for local and remote process manipulation encapsulates all WMI
std_service - Allows for local and remote service manipulation encapsulates all WM
std_fs_search - Unix style file system searcher allowing to search by regex, file atrributes, and types
std_logfile - Generic logging object allows for multiple types of log output similar to log4j
ini_read - VB Script version of GetPrivateProfileString
ini_write - VB Script version of WritePrivateProfileString
strftime - C style date format function
ping - Ping host and get ping stats like ttl etc.
nslookup - Resolve ip’s to names.

These objects and functions mean less work for custom actions.

0
Login to vote