Hi All,
Seriously stuck here in implementing delta imports with my ECMA (ver 2.2, call-based), hoping someone here can guide me with the basic concepts around it.
I'm writing a Lync provisioning ECMA, and my full import run profile works just fine. Now I need to move towards delta imports. In order to get changed objects, I use the DateTime of the last Import operation as the watermark and gather all objects which have changed since the last import operation. However, I'm stuck on how to detect which of those changed objects only has some changed attributes (i.e. they already exist in the connector space), and which objects are brand new. I can't find any documentation or examples on this :(. The code I'm using for my delta import is as follows:
public GetImportEntriesResults GetImportEntries(GetImportEntriesRunStep importRunStep)
{
//System.Diagnostics.Debugger.Launch();
GetImportEntriesResults importReturnInfo;
List<CSEntryChange> csentries = new List<CSEntryChange>();
// Create powershell environment
InitialSessionState initial = InitialSessionState.CreateDefault();
initial.ImportPSModule(new string[] { "C:\\Program Files\\Common Files\\Microsoft Lync Server 2010\\Modules\\Lync\\Lync.psd1",
"C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\Modules\\ActiveDirectory\\ActiveDirectory.psd1"});
Runspace runspace = RunspaceFactory.CreateRunspace(initial);
runspace.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = runspace;if (OperationType.Delta == m_importOperation) { ps.Commands.AddCommand("Get-csaduser"); ps.Commands.AddCommand("where-object"); ScriptBlock filter = ScriptBlock.Create("$_.Enabled -eq $True -and $_.SipAddress -ne $Null"); ps.AddParameter("FilterScript", filter); foreach (PSObject result in ps.Invoke()) { CSEntryChange csentry1 = CSEntryChange.Create(); csentry1.ObjectModificationType = ObjectModificationType.Update; csentry1.ObjectType = "user"; IList<CSEntryChange> existingcsentries = importRunStep.FullObjectEntries; // Returns 0 objects, why? PowerShell ps2 = PowerShell.Create(); ps2.Runspace = runspace; ps2.Commands.AddCommand("get-aduser"); string script = string.Format("(samaccountname -eq \"{0}\") -and (modified -gt \"{1}\")", result.Members["samaccountname"].Value,importRunStep.CustomData); ScriptBlock filter2 = ScriptBlock.Create(script); ps2.Commands.AddParameter("Filter", filter2); ps2.Commands.AddParameter("Properties", "*"); //ps2.Commands.AddCommand("select").AddArgument("employeeID"); foreach (PSObject result2 in ps2.Invoke()) { csentry1.AttributeChanges.Add(AttributeChange.CreateAttributeUpdate("FirstName", result2.Members["GivenName"].Value)); csentry1.AttributeChanges.Add(AttributeChange.CreateAttributeUpdate("LastName", result2.Members["Surname"].Value.ToString())); csentry1.AttributeChanges.Add(AttributeChange.CreateAttributeUpdate("EmployeeID", result2.Members["employeeID"].Value.ToString())); csentries.Add(csentry1); } //csentries.Add(csentry1); ps2.Stop(); ps2.Dispose(); } } importReturnInfo = new GetImportEntriesResults(); importReturnInfo.MoreToImport = false; importReturnInfo.CSEntries = csentries; importReturnInfo.CustomData = DateTime.Now.ToString(); ps.Stop(); ps.Dispose(); runspace.Close(); return importReturnInfo; }
The code simply selects users from Lync who are still active and who have a SIP address and whose modified date is after the last import. The above code generally works if I modify a user (say change the firstname in AD), since I'm hardcoding the changetype as "update". However, if I provision a new user to Lync and run the Delta Import, the new user doesn't get added to the connector space (because I'm using Update and not Add)
Now, how would I detect if the object changed already exists in the connector space? I can't find any way to tell if the modification type should be an "Add" or an "Update". I thought I could use the .FullObjectEntries property to retrieve a list of existing CSEntry objects in the connector space, but that returns 0 objects (even though there are 3 objects in the CS)
Hope my question makes sense, and sorry for the shoddy code.
Thanks in advance