Monday 5 December 2011

MIIS Database (MicrosoftIdentityIntegrationServer):



MIIS 2003 uses SQL Server 2000 as its data store. Each edition of MIIS 2003 is supported by specific editions of Microsoft® Windows Server™ 2003 and SQL Server 2000.








Windows Server 2003 and SQL Server 2000 Editions:


MIIS 2003 Requirements for SQL Server 2000


The following are MIIS 2003 requirements for SQL Server 2000:

1. SQL Server 2000 and MIIS 2003 can be installed on the same server or different servers, but they must be located in the same domain.

2. If you configure SQL Server 2000 to use a communications port other than the default SQL Server port 1433, you must use the SQL Server Client Network Utility on the computer on which you run MIIS 2003 to set the communications port to be used by SQL Server clients on that computer. You must do this even if MIIS 2003 is running on the same computer that SQL Server 2000 is running on.

Recommendations for Running SQL Server 2000 to Support MIIS 2003


Do not attempt to manually modify data that is stored in the MIIS database. Modify the database only by using Identity Manager, which can determine if and what changes are necessary.
Maintain your transaction log files for the MIIS database on a separate drive from the drive that contains the MIIS database.
To ensure availability and provide redundancy in large-scale environments, use SQL Server clustering with MIIS 2003, Enterprise Edition.
In addition to using the performance improvement methods described elsewhere in this document, use performance tuning to optimize SQL Server 2000 performance.

MicrosoftIdentityIntegrationServer Database in SQL Server 2000
When MIIS 2003 is installed, a SQL Server 2000 database that is named   MicrosoftIdentityIntegrationServer is created within SQL Server 2000. The MicrosoftIdentityIntegrationServer database contains all the metadirectory data used by MIIS 2003, including the following:
Metaverse data
Management agent data
Connector space data
Rules extension data
Object link data
Management agent run profiles
Management agent run history
Joiner log

The MicrosoftIdentityIntegrationServer database does not contain any of the following:
Event log files
Contents of the directory at C:\ProgramFiles\Microsoft Identity Integration Server\MaData
Administrative scripts

Example:



Backup Strategies for MIIS Database:


Backing Up the MIIS 2003 Encryption Key:

You need to regularly back up the encryption key that MIIS 2003 uses to encrypt data and credentials. Failure to back up encryption keys can lead to loss of encrypted data and credentials. To back up the encryption key, use the MIIS Key Management Utility.

The MIIS Key Management Utility has two different user interfaces:
1. command line and
2. Windows wizard.
For most backup and restore operations of the encryption key, the command line interface is sufficient. For more advanced backup operations of the encryption key, for example, to add a new encryption key to the key set or to abandon an existing key set and create a new set, you need to use the MIIS Key Management wizard.


To back up the encryption key, you must be logged on as a member of an MIIS security group and have administrative credentials on the local computer.

To back up the MIIS 2003 encryption key by using the command line
1. On the server where MIIS 2003 is running, change the directory by typing the following at the command line:

cd %Programfiles%\Microsoft Identity Integration Server\bin
2. Type the following at the command line to save the encryption key to a floppy disk:

miiskmu /e a:keyback.bin /u miisadmin *













To back up the MIIS 2003 encryption key by using the MIISkmu wizard:

1. Click Start, point to All Programs and Microsoft Identity Integration Server, and then click Key 
Management Utility.
2. Follow the instructions in the wizard.

Note: When using the MIISkmu wizard, you might need to stop the Microsoft Identity Integration Server service in Windows Services in order to enable advanced options.



Sunday 4 December 2011

Querying the MicrosoftIdentityIntegrationServer database



Many organisations and customers often express their requirement to effectively report on  information contained within the ILM database (MicrosoftIdentityIntegrationServer). Although I would never recommend that direct database access is used for this there are some cases in which information must be pulled from the ILM database itself.

However, since ILM assumes that the MIISServer.exe process has got exclusive access to the database; locking issues could cause you problems. (ILM will generate exceptions when locking occurs.)

In an effort to overcome this, one solution is to read ‘dirty’ data from the SQL database. In this way you run the risk of not having completely accurate information, but you mitigate your risk of causing locking issues.

NOLOCK:Using NOLOCK politely asks SQL Server to ignore locks and read directly from the tables. This means you completely circumvent the lock system, which is a major performance and scalability improvement. However, you also completely circumvent the lock system, which means your code is living dangerously. You might read the not-necessarily-valid uncommitted modifications of a running transaction. This is a calculated risk.

Within the MIIS/ILM database, the NOLOCK hint is not used for performance reasons but rather for safe MIIS/ILM operations. It is recommended that the NOLOCK hint is used so that your queries does not lock any data that MIIS/ILM might need during processing thus causing MIIS/ILM to fail or generate errors. Keep in mind that ILM assumes that it has total database control.

So where do we use it…
    SELECT        object_id
    FROM            mms_metaverse WITH (nolock)
    WHERE        (employeeID = @EMPID)



Metaverse Rules Extension

Generally, you prepare one rules extension .dll for the metaverse. Your rules extension .dll must include rule logic for rules defined as extension implemented. The provisioning rule can only be extension implemented.

The following procedure details how to create a metaverse rules extension project. To create a project, you must be a member of the MIISAdmins security group.





To create a metaverse rules extension project

    1. On the Tools menu of the UI, click Options.

    2. Select the Enable Metaverse Rules Extension check box, and provide a name for the file to contain the extension code.

    3. Select the Run this extension in a separate process check box if the extension module is to run in a separate process from MIIS 2003.

    4. Select the Enable Provisioning Rules Extension check box if you want to enable provisioning.

    5. In the GlobalRules Extension Settings portion of the display, specify if you want to unload the rules extension when the duration of a single      operation exceeds a certain value. The default value is 60 seconds. This also applies to management agent rules extensions.

    6. Click Create Rules Extension Project. The rules extension project defaults to Visual Basic .NET 2003 as a programming language. If desired, select      Visual C# .NET 2003, if desired.

                      

MIIS 2003 supplies a default project name of MVExtension. You might change this if you wish. By default, Visual Studio .NET 2003 builds a .dll with the same name as your project and stores it in the MIIS 2003 Extensions directory. Therefore, it is essential to ensure that your project has a different name from all other rules extension projects within the solution. A valid rules extension name can contain uppercase and lowercase letters A through Z, dashes (-), underscores (_), and spaces. Other characters are not permitted and it cannot be a reserved system file name.

If you want to change the default folder in which the project is created, click Browse….

Select the Launch in VS .Net IDE box to launch a Visual Studio .NET 2003 project in the IDE.

If necessary, create an initialization file to hold configuration information; save this file in the Extensions folder for MIIS 2003.

Using the Metaverse Rules Extension Initialize and Terminate Methods

Your rules extension .dll contains an Initialize method, which you can use to include code for any preprocessing work that the rules extensions in the .dll might require. For example, you might place code here to read an XML file that contains constants for the rule extensions or make a connection to a database. MIIS 2003 only loads the .dll when it determines that a call will be made to a rules extension in the .dll. After loading the .dll, MIIS 2003 calls Initialize prior to making the first call to the rules extension.

The rules extension .dll also contains a Terminate method, in which you can include code for cleanly releasing resources before the .dll is unloaded. For example, if you connected to a database in the Initialize method, yourTerminate code would close this connection. As with management agent rules extensions, although the current version of MIIS 2003 calls Terminate when no rules extension is called within a 5-minute interval, you should not build your rules assuming that this will be the case in the future.

Using the Metaverse Object Deletion Function

In MIIS 2003, a metaverse object is deleted when its last connector disconnects, without any further processing. Through the UI you can also choose to have a metaverse object deleted when a connector associated with a particular management agent disconnects, or you can choose to use a rules extension. If the metaverse object deletion rule has been defined as extension implemented, then the ShouldDeleteFromMV function is called.








ShouldDeleteFromMV

ShouldDeleteFromMV returns True if the Metaverse object should be deleted.

ShouldDeleteFromMV Parameters

csentry
This parameter is the connector space object that is being disconnected from the metaverse.

mventry

This parameter is the Metaverse object that was linked to the connector space object and is the candidate for deletion.

Example:

The following example shows an implementation of the metaverse object deletion function; the intention is that this function deletes the mventry if the csentry that projected it disconnects. In fact, the logic relies on a particular attribute (uid in this case) being provided only by the csentry that projected it, and you can usually find such an attribute by analyzing the rules used to populate the metaverse.


Public Function ShouldDeleteFromMV(ByVal csentry As CSEntry, ByVal mventry As MVEntry) As Boolean Implements IMVSynchronization.ShouldDeleteFromMV
        ShouldDeleteFromMV = False

        If csentry.MA.Name = mventry.("uid").LastContributingMA.Name then
            ShouldDeleteFromMV = True
        End If

End Function



Using the Provisioning Method

The objective of the inbound synchronization phase is to update the metaverse with authoritative identity data. A connector space object can only be linked to one metaverse object and can therefore only update one metaverse object.

A metaverse object can be linked to several connector space objects. As soon as the metaverse has been updated, the synchronization service determines whether there is a need to distribute the new data to the connected connector space objects, which is the objective of the outbound synchronization phase.



A provisioning rule is used after inbound management agent synchronization rules are applied and before any management agent outbound synchronization rules are applied. The provisioning rule:

    1. Creates a new connector space object

    2. Renames an existing connector space object

    3. Removes a link to an existing connector space object to trigger the deprovisioning rule and

    4. Completes any other processing that might be useful.

The only way to define this rule is through a rules extension that implements the Provision method – there is no declarative route within the UI.


Provision Parameters

mventry
This parameter is the metaverse object involved. Attributes are read-only.

Example:

The following example shows an implementation of the Provisioning method. The code provisions a new person object in the Telephone management agent if one does not already exist. It only provisions if the metaverse objects have an attribute called EmpType to the value “employee.”



Public Sub Provision(ByVal mventry As Microsoft.MetadirectoryServices.MVEntry) Implements IMVSynchronization.Provision
        ' First, the telephone system only takes person objects
        If mventry.ObjectType.Equals("person") Then
            ' Also, telephone MA should only receive employee objects
            If mventry("EmpType").Value.ToLower = "employee" Then
                Dim csentry As CSEntry
                Dim PhoneMA As ConnectedMA = mventry.ConnectedMAs("Phone MA")
                ' If there is no connector present, add a new telephone connector
                If TelephoneMA.Connectors.Count = 0 Then
                    csentry = TelephoneMA.Connectors.StartNewConnector("person")
                    csentry("EMPID").Values.Add(mventry("employeeID").Value)
                    csentry.CommitNewConnector()
                ElseIf PhoneMA.Connectors.Count = 1 Then
                    ' Nothing to do, connector already exists for this MV object
                Else
                    Throw New UnexpectedDataException("Multiple connectors:" + PhoneMA.Connectors.Count.ToString)
                End If
            End If 'employees only
        End If 'person objects only
End Sub



WORKING WITH ACTIVE DIRECTORY LASTLOGONTIMESTAMP ATTRIBUTE


WORKING WITH ACTIVE DIRECTORY LASTLOGONTIMESTAMP ATTRIBUTE:



Active Directory includes an attribute – lastLogon – that tells you the last time a user or computer logged on.
The lastLogon attribute is not replicated from one domain controller to another.
There’s a brand-new attribute in the schema: lastLogonTimestamp.
This attribute also keeps track of the last time a user logged on to the domain, but this new attribute is replicated from one domain controller to another.
The lastLogonTimestamp is replicated only once every 14 days. This helps limit replication traffic.
The lastLogonTimestamp is stored as a 64-bit integer. When you query the lastLogonTimestamp you don’t get back a date-time like May 15, 2005 8:05 AM. Instead, you get back the number of 100-nanosecond intervals that passed between January 1, 1601 and the time the user last logged on.

Incidentally,VBScript can’t actually handle the 64-bit integer returned by lastLogonTimestamp.
But at least there is a workaround for this: ADSI’s IADsLargeInterger interface can break this into a pair of 32-bit integers for us.

---------------------------------------------------------------------------------------------------------------------------------
This code will bind to the user account in Active Directory and then use the Get method to retrieve the lastLogonTimestamp, storing that value in an IADsLargeInteger object with the object reference objLastLogon.

Set objUser = GetObject("LDAP://cn=Ken Myer, ou=Finance, dc=fabrikam, dc=com")
Set objLastLogon = objUser.Get("lastLogonTimestamp")

'The IADsLargeInteger object has two properties: HighPart, which stores the upper 32 bits of our 64-bit integer;
'and LowPart, which stores the lower 32 bits of the integer.

intLastLogonTime = objLastLogon.HighPart * (2^32) + objLastLogon.LowPart

'There are 1,000,000,000 nanoseconds in a second, 60 seconds in a minute and 1,440 minutes in every 24-hour day.
'This line of code tells us how many days have elapsed.

intLastLogonTime = intLastLogonTime / (60 * 10000000)
intLastLogonTime = intLastLogonTime / 1440

'Add the number of days that passed to the date January 1, 1601.

Wscript.Echo "Last logon time: " & intLastLogonTime + #1/1/1601#


Output:
Last logon time: 4/25/2005 2:54:09 PM

---------------------------------------------------------------------------------------------------------------------------------

Alternate solution:

'Use a method on DateTime called FromFileTime(long nanotime).This method returns a DateTime using
'the current Time Zone, so we don’t have to convert it.

Dim lastLogonDateTime As DateTime

Set objUser = GetObject("LDAP://cn=Ken Myer, ou=Finance, dc=fabrikam, dc=com")
Set objLastLogon = objUser.Get("lastLogonTimestamp")

lastLogonDateTime = DateTime.FromFileTime(objLastLogon)

Wscript.Echo "Last logon time: " & lastLogonDateTime.ToString

Working with null values in the .NET Framework





A null value is a value that doesn't refer to any object. It's the default value of reference-type variables(e.g., class, interface, delegate, string).



For example:

string sTest = "Test";
if (sTest == null) {
Console.WriteLine("sTest is Null")
}

This code works without any problems with C#,but there's no VB.NET equivalent of the null keyword. Instead,VB.NET uses the Nothing keyword. The following code demonstrates its use:

Dim sTest As String
If (sTest Is Nothing) Then
Console.WriteLine("sTest is Null")
End If

EXECUTE SQL COMMAND in Visual Basic









------------------------------------------------------------------------------------------------------------
Needed Import Statment:

Imports System.Data.SqlClient
------------------------------------------------------------------------------------------------------------
CASE 1: COMMAND which WILL NOT RETUN ANY ROW. Example: UPDATE


Dim connectionString as String
Dim connection as SqlConnection
Dim commandString as String
Dim command as SqlCommand

connectionString = "Data Source=CPHWIN0151;Initial Dialog=ABC Billing Infor;uid=abc_billing;pwd=abc@123"
commandString = "UPDATE ABCTable set costcenter=12345"

connection = New SqlConnection(connectionString)

Try
    connection.open()
    command = New SqlCommand(commandString,connection)
    command.ExecuteNonQuery()
    command.connection.close()
Catch ex As SQLException   

Finnaly
connection.close()

End Try

------------------------------------------------------------------------------------------------------------

CASE 2: COMMAND WHICH WILL RETURN ROW. Example: SELECT


Dim connectionString as String
Dim connection as SqlConnection
Dim commandString as String
Dim command as SqlCommand


connectionString = "Data Source=CPHWIN0151;Initial Dialog=ABC Billing Infor;uid=abc_billing;pwd=abc@123"
commandString = "SELECT objIdentifier,UID FROM V_MA_ORDER WHERE UID='12345'"

connection = New SqlConnection(connectionString)

Try
    connection.open()   
    command = New SqlCommand(commandString,connection)
   
    Dim dr As SqlDataReader = command.ExecuteReader

    Do While dr.Read()
        objId = dr(0).ToString.Trim
        uid = dr(1).ToString.trim
    Loop
   
    dr.close()
    command.connection.close()
Catch ex As SqlException

Finnaly
connection.close()

End Try

------------------------------------------------------------------------------------------------------------

Use of XML in MIIS


It is useful to use some kind of initialization or configuration file to control the behavior of a .dll file without having to recompile it. You can do this by providing an XML file of parameters that are read in the Initialize sub of a management agent or metaverse .dll assembly (any initialization file   will be sufficient, but XMLworks best).


------------------------------------------------------------------------------------------------------------
Needed Import statment:

Imports System.Xml
Imports Microsoft.Win32
Imports Microsoft.Win32.Registry
Imports Microsoft.Win32.RegistryKey
------------------------------------------------------------------------------------------------------------
Public Sub UseRuleExtensionsConfig(ByVal filename As String)

            Dim RuleExtensions_config_file As String = "\" + filename
            Dim config As XmlDocument = New XmlDocument
            Dim rnode, node As XmlNode
           
        ' Call registry to get the path for MIIS which is "C:\Program Files\Microsoft Identity Integration Server\"
        ' Then load the file "RuleExtensions_config.xml" which is actually save in MaData folder

        Dim regKey As Microsoft.Win32.RegistryKey
            regKey = Registry.LocalMachine.OpenSubKey("SYSTEM\CurrentControlSet\Services\miiserver\Parameters", False)
            config.Load(regKey.GetValue("Path") & "MaData\" & filename)

            rnode = config.SelectSingleNode("rules-extension-properties/management-agents/SASDOM0001_UsersAndGroups")
            node = rnode.SelectSingleNode("useShortNames")
            ShortNames = node.InnerText

            rnode = config.SelectSingleNode("rules-extension-properties/account-provisioning/sasdom0001")
            node = rnode.SelectSingleNode("groups/departments/groupPrefix")
            sasdom0001DeptPrefix = node.InnerText
           
End Sub
------------------------------------------------------------------------------------------------------------
Call Sub routine:

Const RuleExtensions_config_file = "RuleExtensions_config.xml"
UseRuleExtensionsConfig(RuleExtensions_config_file)

------------------------------------------------------------------------------------------------------------

Contents of XML file:

<rules-extension-properties>
    <management-agents>
        <SASDOM0001_UsersAndGroups>
            <useShortNames>yes</useShortNames>
        </SASDOM0001_UsersAndGroups>
    </management-agents>

    <account-provisioning>
        <sasdom0001>
            <groups>
                <departments>
                    <GroupsOU>OU=DEPARTMENTS,OU=GROUPS</GroupsOU>
                    <groupPrefix>DEPT_</groupPrefix>
                </department>
            </groups>
        </sasdom0001>
    </account-provisioning>

</rules-extension-properties>

------------------------------------------------------------------------------------------------------------