void RevertImpersonation() { if (!ShouldImpersonate()) { return; } Tracer.Enter("revertimpersonation"); Tracer.Indent(); try { Tracer.TraceInformation("closing-impersonation-context"); m_ImpersonationContext.Undo(); Tracer.TraceInformation("closing-impersonation-tokenhandle {0}", impersonationToken); NativeMethods.CloseHandle(impersonationToken); Tracer.TraceInformation("closing-impersonation-duplicated-tokenhandle {0}", tokenDuplicate); NativeMethods.CloseHandle(tokenDuplicate); } catch (Exception ex) { Tracer.TraceError("revertimpersonation", ex); throw; } finally { Tracer.Unindent(); Tracer.Exit("revertimpersonation"); } }
public CloseImportConnectionResults CloseImportConnection(CloseImportConnectionRunStep importRunStep) { Tracer.Enter("closeimportconnectionresults"); Tracer.Indent(); try { CloseRunspace(); //RevertImpersonation(); CloseImportConnectionResults cicr = new CloseImportConnectionResults(); Tracer.TraceInformation("custom-data {0}", importRunStep.CustomData); Tracer.TraceInformation("close-reason {0}", importRunStep.Reason); if (importRunStep.Reason == CloseReason.Normal) { cicr.CustomData = importRunStep.CustomData; } Dispose(); return(cicr); } catch (Exception ex) { Tracer.TraceError("closeimportconnection", ex); throw; } finally { Tracer.Unindent(); Tracer.Exit("closeimportconnectionresults"); } }
void IMAExtensible2CallExport.OpenExportConnection(System.Collections.ObjectModel.KeyedCollection <string, ConfigParameter> configParameters, Schema types, OpenExportConnectionRunStep exportRunStep) { Tracer.IndentLevel = 0; Tracer.Enter("openexportconnection"); Tracer.Indent(); try { InitializeConfigParameters(configParameters); OpenRunspace(); schema = types; exportType = exportRunStep.ExportType; Tracer.TraceInformation("export-type '{0}'", exportType); exportBatchSize = exportRunStep.BatchSize; Tracer.TraceInformation("export-batch-size '{0}'", exportBatchSize); } catch (Exception ex) { Tracer.TraceError("openexportconnection", ex); throw new TerminateRunException(ex.Message); } finally { Tracer.Unindent(); Tracer.Exit("openexportconnection"); } }
void SetupImpersonationToken() { Tracer.Enter("setupimpersonationtoken"); try { if (!ShouldImpersonate()) { Tracer.TraceInformation("impersonation-not-configured-running-as-sync-service-account"); WhoAmI(); return; } WindowsIdentity m_ImpersonatedUser; Tracer.TraceInformation("user-before-impersonation: {0}", WindowsIdentity.GetCurrent(TokenAccessLevels.MaximumAllowed).Name); //bool success = NativeMethods.LogonUser(impersonationUsername, impersonationUserDomain, impersonationUserPassword, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out impersonationToken); bool success = NativeMethods.LogonUser(impersonationUsername, impersonationUserDomain, impersonationUserPassword, (int)LogonType.LOGON32_LOGON_NETWORK_CLEARTEXT, (int)LogonProvider.LOGON32_PROVIDER_WINNT50, out impersonationToken); if (!success) { SecurityException ex = new SecurityException(string.Format("failed-to-impersonate: domain: '{0}', username: '******', password: **secret***", impersonationUserDomain, impersonationUsername)); Tracer.TraceError(ex.ToString()); throw ex; } else { Tracer.TraceInformation("succeeded-in-impersonating: domain: '{0}', username: '******', password: **secret***", impersonationUserDomain, impersonationUsername); if (NativeMethods.DuplicateToken(impersonationToken, (int)ImpersonationLevel.SecurityImpersonation, ref tokenDuplicate) != 0) { m_ImpersonatedUser = new WindowsIdentity(tokenDuplicate); m_ImpersonationContext = m_ImpersonatedUser.Impersonate(); Tracer.TraceInformation("succeeded-in-duplicating-impersonation-token"); if (m_ImpersonationContext != null) { Tracer.TraceInformation("user-after-impersonation: {0}", WindowsIdentity.GetCurrent(TokenAccessLevels.MaximumAllowed).Name); WhoAmI(); } else { throw new Exception("impersonation-context-is-null"); } } else { throw new Exception("could-not-duplicate-impersonation-token"); } } } catch (Exception ex) { Tracer.TraceError("setupimpersonationtoken", ex); throw; } finally { Tracer.Unindent(); Tracer.Exit("setupimpersonationtoken"); } }
public PowerShellManagementAgent() { Tracer.IndentLevel = 0; Tracer.Enter("initialize"); Tracer.Indent(); try { Tracer.TraceInformation("memory-usage {0:n} Mb", GC.GetTotalMemory(true) / 102400); System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly(); FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location); string version = fvi.FileVersion; Tracer.TraceInformation("psma-version {0}", version); Tracer.TraceInformation("reading-registry-settings"); RegistryKey machineRegistry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64); RegistryKey mreRootKey = machineRegistry.OpenSubKey(@"SOFTWARE\Granfeldt\FIM\ManagementAgents\PowerShell", false); if (mreRootKey != null) { Tracer.TraceInformation("adding-eventlog-listener-for name: {0}, source: {1}", EventLogName, EventLogSource); EventLog evl = new EventLog(EventLogName); evl.Log = EventLogName; evl.Source = EventLogSource; EventLogTraceListener eventLog = new EventLogTraceListener(EventLogSource); eventLog.EventLog = evl; EventTypeFilter filter = new EventTypeFilter(SourceLevels.Warning | SourceLevels.Error | SourceLevels.Critical); eventLog.TraceOutputOptions = TraceOptions.Callstack; eventLog.Filter = filter; Tracer.Trace.Listeners.Add(eventLog); if (!EventLog.SourceExists(EventLogSource)) { Tracer.TraceInformation("creating-eventlog-source '{0}'", EventLogSource); EventLog.CreateEventSource(EventLogSource, EventLogName); } string logFileValue = mreRootKey.GetValue("DebugLogFileName", null) as string; if (logFileValue != null) { Tracer.TraceWarning("Logging to file is no longer supported. Please remove registrykey DebugLogFileName and use DebugView or similar instead to catch traces from this Management Agent"); } } } catch (Exception ex) { Tracer.TraceError("could-not-initialize", ex); throw; } finally { Tracer.Unindent(); Tracer.Exit("initialize"); } }
void CallPasswordScript(PasswordOperation Action, CSEntry csentry, SecureString oldPassword, SecureString newPassword, PasswordOptions options) { Tracer.Enter("callpasswordscript"); Tracer.Indent(); PSDataCollection <PSObject> passwordPipeline = new PSDataCollection <PSObject>(); try { Command cmd = new Command(Path.GetFullPath(PasswordManagementScript)); cmd.Parameters.Add(new CommandParameter("User", Username)); cmd.Parameters.Add(new CommandParameter("Password", Password)); cmd.Parameters.Add(new CommandParameter("Credentials", GetSecureCredentials())); cmd.Parameters.Add(new CommandParameter("Action", Action.ToString())); if (options.HasFlag(PasswordOptions.UnlockAccount)) { cmd.Parameters.Add(new CommandParameter("UnlockAccount")); } if (options.HasFlag(PasswordOptions.ForceChangeAtLogOn)) { cmd.Parameters.Add(new CommandParameter("ForceChangeAtLogOn")); } if (options.HasFlag(PasswordOptions.ValidatePassword)) { cmd.Parameters.Add(new CommandParameter("ValidatePassword")); } cmd.Parameters.Add(new CommandParameter("NewPassword", newPassword.ConvertToUnsecureString())); if (Action == PasswordOperation.Change) { cmd.Parameters.Add(new CommandParameter("OldPassword", oldPassword.ConvertToUnsecureString())); } passwordPipeline.Add(new PSObject(csentry)); passwordResults = InvokePowerShellScript(cmd, passwordPipeline); } catch (Exception ex) { Tracer.TraceError("callpasswordscript", ex); throw; } finally { passwordPipeline = null; Tracer.Unindent(); Tracer.TraceInformation("callpasswordscript"); } }
ParameterValidationResult IMAExtensible2GetParameters.ValidateConfigParameters(System.Collections.ObjectModel.KeyedCollection <string, ConfigParameter> configParameters, ConfigParameterPage page) { try { Tracer.Enter("validateconfigparameters"); Tracer.Indent(); if (page == ConfigParameterPage.Connectivity) { string schemaScriptFilename = Path.GetFullPath(configParameters[Constants.Parameters.SchemaScript].Value); if (!File.Exists(schemaScriptFilename)) { return(new ParameterValidationResult(ParameterValidationResultCode.Failure, string.Format("Can not find or access Schema script '{0}'. Please make sure that the FIM Synchronization Service service account can read and access this file.", schemaScriptFilename), Constants.Parameters.SchemaScript)); } } if (page == ConfigParameterPage.Global) { string importScriptFilename = Path.GetFullPath(configParameters[Constants.Parameters.ImportScript].Value); if (!File.Exists(importScriptFilename)) { return(new ParameterValidationResult(ParameterValidationResultCode.Failure, string.Format("Can not find or access Import script '{0}'. Please make sure that the FIM Synchronization Service service account can read and access this file.", importScriptFilename), Constants.Parameters.ImportScript)); } string exportScriptFilename = Path.GetFullPath(configParameters[Constants.Parameters.ExportScript].Value); if (!File.Exists(exportScriptFilename)) { return(new ParameterValidationResult(ParameterValidationResultCode.Failure, string.Format("Can not find or access Export script '{0}'. Please make sure that the FIM Synchronization Service service account can read and access this file.", exportScriptFilename), Constants.Parameters.ExportScript)); } string passwordManagementScriptFilename = Path.GetFullPath(configParameters[Constants.Parameters.PasswordManagementScript].Value); if (!File.Exists(passwordManagementScriptFilename)) { return(new ParameterValidationResult(ParameterValidationResultCode.Failure, string.Format("Can not find or access Password Management script '{0}'. Please make sure that the FIM Synchronization Service service account can read and access this file.", passwordManagementScriptFilename), Constants.Parameters.PasswordManagementScript)); } } } catch (Exception ex) { Tracer.TraceError("validateconfigparameters", ex); throw; } finally { Tracer.Unindent(); Tracer.Exit("validateconfigparameters"); } return(new ParameterValidationResult(ParameterValidationResultCode.Success, "", "")); }
void IMAExtensible2Password.SetPassword(CSEntry csentry, SecureString newPassword, PasswordOptions options) { Tracer.Enter("setpassword"); Tracer.Indent(); try { CallPasswordScript(PasswordOperation.Set, csentry, new SecureString(), newPassword, options); } catch (Exception ex) { Tracer.TraceError("setpassword", ex); throw; } finally { Tracer.Unindent(); Tracer.Exit("setpassword"); } }
void IMAExtensible2Password.ChangePassword(CSEntry csentry, SecureString oldPassword, SecureString newPassword) { Tracer.Enter("changepassword"); Tracer.Indent(); try { CallPasswordScript(PasswordOperation.Change, csentry, oldPassword, newPassword, PasswordOptions.None); } catch (Exception ex) { Tracer.TraceError("changepassword", ex); throw; } finally { Tracer.Unindent(); Tracer.Exit("changepassword"); } }
void IMAExtensible2CallExport.CloseExportConnection(CloseExportConnectionRunStep exportRunStep) { Tracer.Enter("closeexportconnection"); Tracer.Indent(); try { CloseRunspace(); Dispose(); } catch (Exception ex) { Tracer.TraceError("closeexportconnection", ex); throw; } finally { Tracer.Unindent(); Tracer.Exit("closeexportconnection"); } }
void IMAExtensible2Password.ClosePasswordConnection() { Tracer.Enter("closepasswordconnection"); Tracer.Indent(); try { CloseRunspace(); Dispose(); } catch (Exception ex) { Tracer.TraceError("closepasswordconnection", ex); throw; } finally { Tracer.Unindent(); Tracer.Exit("closepasswordconnection"); } }
void CloseRunspace() { Tracer.Enter("closerunspace"); Tracer.Indent(); try { if (powershell != null) { Tracer.TraceInformation("disposing-powershell"); powershell.Runspace.Close(); powershell.Dispose(); Tracer.TraceInformation("disposed-powershell"); } if (runspace != null) { Tracer.TraceInformation("runspace-state '{0}'", runspace.RunspaceStateInfo.State); if (runspace.RunspaceStateInfo.State != RunspaceState.Closed) { Tracer.TraceInformation("removing-runspace-eventhandlers"); runspace.StateChanged -= Runspace_StateChanged; runspace.AvailabilityChanged -= Runspace_AvailabilityChanged; Tracer.TraceInformation("removed-runspace-eventhandlers"); Tracer.TraceInformation("dispose-runspace"); runspace.Dispose(); // dispose also closes runspace Tracer.TraceInformation("disposed-runspace"); } } } catch (Exception ex) { Tracer.TraceError("closerunspace", ex); throw; } finally { Tracer.Unindent(); Tracer.Exit("closerunspace"); } }
void IMAExtensible2Password.OpenPasswordConnection(KeyedCollection <string, ConfigParameter> configParameters, Partition partition) { Tracer.IndentLevel = 0; Tracer.Enter("openpasswordconnection"); Tracer.Indent(); try { InitializeConfigParameters(configParameters); OpenRunspace(); } catch (Exception ex) { Tracer.TraceError("openpasswordconnection", ex); throw; } finally { Tracer.Unindent(); Tracer.Exit("openpasswordconnection"); } }
public void Dispose() { Tracer.Enter("dispose"); Tracer.Indent(); try { Tracer.TraceInformation("clearing-variables"); csentryqueue = null; objectTypeAnchorAttributeNames = null; Tracer.TraceInformation("collection-garbage"); GC.Collect(0, GCCollectionMode.Default, true); } catch (Exception ex) { Tracer.TraceError(ex.ToString()); throw; } finally { Tracer.Unindent(); Tracer.Exit("dispose"); } }
void WhoAmI() { Tracer.Enter("show-identity"); Tracer.Indent(); try { using (WindowsIdentity currentIdentity = WindowsIdentity.GetCurrent()) { Tracer.TraceInformation("identity-name: {0}", currentIdentity.Name); Tracer.TraceInformation("identity-token: {0}", currentIdentity.Token); Tracer.TraceInformation("identity-user-value: {0}", currentIdentity.User.Value); if (currentIdentity.Actor != null) { Tracer.TraceInformation("identity-actor: {0}", currentIdentity.Actor.Name); Tracer.TraceInformation("identity-actor-auth-type: {0}", currentIdentity.Actor.AuthenticationType); } if (currentIdentity.Groups != null) { foreach (IdentityReference group in currentIdentity.Groups) { NTAccount account = group.Translate(typeof(NTAccount)) as NTAccount; Tracer.TraceInformation("group-membership {0}", account.Value); } } } } catch (Exception ex) { Tracer.TraceError("error-showing-current-identity", ex); throw; } finally { Tracer.Unindent(); Tracer.Exit("show-identity"); } }
public void InitializeConfigParameters(System.Collections.ObjectModel.KeyedCollection <string, ConfigParameter> configParameters) { Tracer.Enter("initializeconfigparameters"); Tracer.Indent(); try { if (configParameters != null) { foreach (ConfigParameter cp in configParameters) { Tracer.TraceInformation("{0}: '{1}'", cp.Name, cp.IsEncrypted ? "*** secret ***" : cp.Value); if (cp.Name.Equals(Constants.Parameters.Username)) { Username = configParameters[cp.Name].Value; } if (cp.Name.Equals(Constants.Parameters.Password)) { Password = configParameters[cp.Name].SecureValue.ConvertToUnsecureString(); SecureStringPassword = configParameters[cp.Name].SecureValue; } if (cp.Name.Equals(Constants.Parameters.ImpersonationDomain)) { impersonationUserDomain = configParameters[cp.Name].Value; } if (cp.Name.Equals(Constants.Parameters.ImpersonationUsername)) { impersonationUsername = configParameters[cp.Name].Value; } if (cp.Name.Equals(Constants.Parameters.ImpersonationPassword)) { impersonationUserPassword = configParameters[cp.Name].SecureValue.ConvertToUnsecureString(); } if (cp.Name.Equals(Constants.Parameters.SchemaScript)) { SchemaScript = configParameters[cp.Name].Value; } if (cp.Name.Equals(Constants.Parameters.ImportScript)) { ImportScript = configParameters[cp.Name].Value; } if (cp.Name.Equals(Constants.Parameters.ExportScript)) { ExportScript = configParameters[cp.Name].Value; } if (cp.Name.Equals(Constants.Parameters.PasswordManagementScript)) { PasswordManagementScript = configParameters[cp.Name].Value; } if (cp.Name.Equals(Constants.Parameters.ExportSimpleObjects)) { ExportSimpleObjects = configParameters[cp.Name].Value == "0" ? false : true; } if (cp.Name.Equals(Constants.Parameters.UsePagedImport)) { UsePagedImport = configParameters[cp.Name].Value == "0" ? false : true; } } } } catch (Exception ex) { Tracer.TraceError("initializeconfigparameters", ex); throw; } finally { Tracer.Unindent(); Tracer.Exit("initializeconfigparameters"); } }
public GetImportEntriesResults GetImportEntries(GetImportEntriesRunStep importRunStep) { Tracer.Enter("getimportentries"); Tracer.Indent(); try { #region call import script // if results is null, then this is the first time that we're called, // so call script and get pipeline object and custom data Tracer.TraceInformation("more-to-import '{0}'", MoreToImport); if (MoreToImport) { MoreToImport = false; // make sure we set more-to-import to false; could be overwritten further down if pagedimports is true, though // on first call, we set customdata to value from last successful run returnedCustomData = importRunStep.CustomData; Command cmd = new Command(Path.GetFullPath(ImportScript)); cmd.Parameters.Add(new CommandParameter("User", Username)); cmd.Parameters.Add(new CommandParameter("Password", Password)); cmd.Parameters.Add(new CommandParameter("Credentials", GetSecureCredentials())); cmd.Parameters.Add(new CommandParameter("OperationType", importOperationType.ToString())); cmd.Parameters.Add(new CommandParameter("UsePagedImport", UsePagedImport)); cmd.Parameters.Add(new CommandParameter("PageSize", ImportRunStepPageSize)); Tracer.TraceInformation("setting-custom-data '{0}'", importRunStep.CustomData); powershell.Runspace.SessionStateProxy.SetVariable("RunStepCustomData", importRunStep.CustomData); Tracer.TraceInformation("setting-page-token '{0}'", pageToken); powershell.Runspace.SessionStateProxy.SetVariable("PageToken", pageToken); importResults = InvokePowerShellScript(cmd, null).ToList <PSObject>(); returnedCustomData = powershell.Runspace.SessionStateProxy.GetVariable("RunStepCustomData"); pageToken = powershell.Runspace.SessionStateProxy.GetVariable("PageToken"); Tracer.TraceInformation("page-token-returned '{0}'", pageToken == null ? "(null)" : pageToken); Tracer.TraceInformation("custom-data returned '{0}'", returnedCustomData); Tracer.TraceInformation("number-of-object(s)-in-pipeline {0:n0}", importResults.Count); if (UsePagedImport) { Tracer.TraceError("paged-import-not-supported-currently"); object moreToImportObject = powershell.Runspace.SessionStateProxy.GetVariable("MoreToImport"); if (moreToImportObject == null) { Tracer.TraceError("For paged imports, the global variable 'MoreToImport' must be set to 'true' or 'false'"); } else { Tracer.TraceInformation("MoreToImport-value-returned '{0}'", moreToImportObject); if (bool.TryParse(moreToImportObject == null ? bool.FalseString : moreToImportObject.ToString(), out MoreToImport)) { Tracer.TraceInformation("paged-import-setting-MoreToImport-to '{0}'", MoreToImport); } else { Tracer.TraceError("Value returned in MoreToImport must be a boolean with value of 'true' or 'false'"); } } } else { MoreToImport = false; Tracer.TraceInformation("non-paged-import-setting-MoreToImport-to '{0}'", MoreToImport); } } #endregion #region parse returned objects if (importResults != null && importResults.Count > 0) { List <PSObject> importResultsBatch = importResults.Take(ImportRunStepPageSize).ToList(); if (importResults.Count > ImportRunStepPageSize) { importResults.RemoveRange(0, importResultsBatch.Count); } else { importResults.Clear(); } Tracer.TraceInformation("converting-objects-to-csentrychange {0:n0}", importResultsBatch.Count); foreach (PSObject obj in importResultsBatch) { HashSet <AttributeDefinition> attrs = new HashSet <AttributeDefinition>(); Tracer.TraceInformation("start-connector-space-object"); Tracer.Indent(); try { CSEntryChange csobject = CSEntryChange.Create(); if (obj.BaseObject.GetType() != typeof(System.Collections.Hashtable)) { Tracer.TraceWarning("invalid-object-in-pipeline '{0}'", obj.BaseObject.GetType()); continue; } object AnchorValue = null; string AnchorAttributeName = null; string objectDN = null; string objectClass = ""; // should be string to prevent null exceptions string changeType = null; string ErrorName = null; string ErrorDetail = null; MAImportError ImportErrorType = MAImportError.Success; // assume no error Hashtable hashTable = (Hashtable)obj.BaseObject; #region get control values Tracer.TraceInformation("start-getting-control-values"); Tracer.Indent(); foreach (string key in hashTable.Keys) { if (key.Equals(Constants.ControlValues.ObjectClass, StringComparison.OrdinalIgnoreCase) || key.Equals(Constants.ControlValues.ObjectClassEx, StringComparison.OrdinalIgnoreCase)) { objectClass = (string)hashTable[key]; Tracer.TraceInformation("got-objectclass {0}, {1}", objectClass, key); continue; } if (key.Equals(Constants.ControlValues.DN, StringComparison.OrdinalIgnoreCase)) { objectDN = (string)hashTable[key]; Tracer.TraceInformation("got-dn {0}, {1}", objectDN, key); continue; } if (key.Equals(Constants.ControlValues.ChangeType, StringComparison.OrdinalIgnoreCase) || key.Equals(Constants.ControlValues.ChangeTypeEx, StringComparison.OrdinalIgnoreCase)) { changeType = (string)hashTable[key]; Tracer.TraceInformation("got-changetype {0}, {1}", changeType, key); continue; } if (key.Equals(Constants.ControlValues.ErrorName, StringComparison.OrdinalIgnoreCase)) { ErrorName = (string)hashTable[key]; Tracer.TraceInformation("got-errorname {0}, {1}", ErrorName, key); continue; } if (key.Equals(Constants.ControlValues.ErrorDetail, StringComparison.OrdinalIgnoreCase)) { ErrorDetail = (string)hashTable[key]; Tracer.TraceInformation("got-errordetail {0}, {1}", ErrorDetail, key); continue; } } if (string.IsNullOrEmpty(objectClass)) { Tracer.TraceError("missing-objectclass"); ImportErrorType = MAImportError.ImportErrorCustomContinueRun; ErrorName = "missing-objectclass-value"; ErrorDetail = "No value provided for objectclass attribute"; } else { AnchorAttributeName = objectTypeAnchorAttributeNames[objectClass] == null ? "" : (string)objectTypeAnchorAttributeNames[objectClass]; if (string.IsNullOrEmpty(AnchorAttributeName)) { ImportErrorType = MAImportError.ImportErrorInvalidAttributeValue; ErrorName = "invalid-objecttype"; ErrorDetail = "Objecttype not defined in schema"; } foreach (string key in hashTable.Keys) { if (key.Equals(AnchorAttributeName, StringComparison.OrdinalIgnoreCase)) { AnchorValue = hashTable[key]; Tracer.TraceInformation("got-anchor {0}, {1}", AnchorValue, key); break; } } } Tracer.Unindent(); Tracer.TraceInformation("end-getting-control-values"); if (AnchorValue == null) { Tracer.TraceError("missing-anchor"); ImportErrorType = MAImportError.ImportErrorCustomContinueRun; ErrorName = "missing-anchor-value"; ErrorDetail = "No value provided for anchor attribute"; } if (AnchorValue != null && string.IsNullOrEmpty(objectDN)) { Tracer.TraceInformation("setting-anchor-as-dn {0}", AnchorValue); objectDN = AnchorValue.ToString(); } if (!string.IsNullOrEmpty(ErrorName)) { ImportErrorType = MAImportError.ImportErrorCustomContinueRun; if (string.IsNullOrEmpty(ErrorDetail)) { ErrorDetail = "No error details provided"; } } #endregion control values #region return invalid object if (ImportErrorType != MAImportError.Success) { Tracer.TraceInformation("returning-invalid-object"); if (AnchorValue != null) { csobject.AnchorAttributes.Add(AnchorAttribute.Create(AnchorAttributeName, AnchorValue)); } csobject.ObjectModificationType = ObjectModificationType.Add; if (!string.IsNullOrEmpty(objectClass)) { try { csobject.ObjectType = objectClass; } catch (NoSuchObjectTypeException otEx) { Tracer.TraceError("no-such-object '{0}'", otEx); } } if (!string.IsNullOrEmpty(objectClass)) { csobject.DN = objectDN; } Tracer.TraceError("invalid-object dn: {0}, type: {1}, name: {2}, details: {3} ", objectDN, ImportErrorType, ErrorName, ErrorDetail); csobject.ErrorCodeImport = ImportErrorType; csobject.ErrorName = ErrorName; csobject.ErrorDetail = ErrorDetail; csentryqueue.Add(csobject); continue; } #endregion #region return deleted object // we must set ObjectModificationType before any other attributes; otherwise it will default to 'Add' if (!string.IsNullOrEmpty(changeType) && changeType.Equals("delete", StringComparison.OrdinalIgnoreCase)) { Tracer.TraceInformation("returning-deleted-object"); Tracer.TraceInformation("change-type {0}", changeType); csobject.ObjectModificationType = ObjectModificationType.Delete; csobject.ObjectType = objectClass; csobject.DN = objectDN; // we need to get the object anchor value for the deletion csobject.AnchorAttributes.Add(AnchorAttribute.Create(AnchorAttributeName, AnchorValue)); csentryqueue.Add(csobject); continue; } #endregion #region returned live object Tracer.TraceInformation("returning-valid-object"); csobject.ObjectModificationType = ObjectModificationType.Add; csobject.ObjectType = objectClass; csobject.DN = objectDN; csobject.AnchorAttributes.Add(AnchorAttribute.Create(AnchorAttributeName, AnchorValue)); foreach (string key in hashTable.Keys) { try { if (Regex.IsMatch(key, string.Format(@"^(objectClass|\[objectclass\]|changeType|\[changetype\]|\[DN\]|\[ErrorName\]|\[ErrorDetail\]|{0})$", AnchorAttributeName), RegexOptions.Compiled | RegexOptions.IgnoreCase)) { Tracer.TraceInformation("skip-control-value {0}", key); continue; } if (hashTable[key] == null) { Tracer.TraceInformation("skip-null-value-for '{0}'", key); continue; } SchemaAttribute sa = schema.Types[objectClass].Attributes[key]; Tracer.TraceInformation("attribute: {0} (type {1}, {2}): '{3}'", key, sa.DataType, sa.IsMultiValued ? "multi-value" : "single-value", hashTable[key]); if (sa.IsMultiValued) { //Tracer.TraceInformation("add-multivalue '{0}' [{1}]", key, hashTable[key].GetType()); List <object> mvs = new List <object>(); if (hashTable[key].ToString().EndsWith("[]")) { mvs.AddRange((object[])hashTable[key]); } else { mvs.Add(hashTable[key]); } csobject.AttributeChanges.Add(AttributeChange.CreateAttributeAdd(key, mvs)); } else { csobject.AttributeChanges.Add(AttributeChange.CreateAttributeAdd(key, hashTable[key])); } } catch (KeyNotFoundException keyexception) { Tracer.TraceError("attribute-is-not-defined-for '{0}' / '{1}' ({2})", key, objectClass, keyexception.ToString()); } } #endregion if (csobject.ErrorCodeImport != MAImportError.Success) { Tracer.TraceError("defective-csentrychange id: {0}, dn: {1}, errorcode: {2}, error: {3}, details: {4}", csobject.Identifier, csobject.DN, csobject.ErrorCodeImport, csobject.ErrorName, csobject.ErrorDetail); } Tracer.TraceInformation("returning-csentry dn: {0}, id: {1}", csobject.DN, csobject.Identifier); csentryqueue.Add(csobject); } catch (Exception ex) { Tracer.TraceError("creating-csentrychange", ex); } finally { Tracer.Unindent(); Tracer.TraceInformation("end-connector-space-object"); } } // clearing results for next loop importResultsBatch.Clear(); } #endregion #region dequeue csentries GetImportEntriesResults importReturnInfo = null; Tracer.TraceInformation("total-import-object(s)-left {0:n0}", importResults.Count); Tracer.TraceInformation("total-connector-space-object(s)-left {0:n0}", csentryqueue.Count); List <CSEntryChange> batch = csentryqueue.Take(ImportRunStepPageSize).ToList(); if (csentryqueue.Count > ImportRunStepPageSize) { csentryqueue.RemoveRange(0, batch.Count); } else { csentryqueue.Clear(); } importReturnInfo = new GetImportEntriesResults(); importReturnInfo.MoreToImport = MoreToImport || importResults.Count > 0 || (csentryqueue.Count > 0); importReturnInfo.CustomData = returnedCustomData == null ? "" : returnedCustomData.ToString(); importReturnInfo.CSEntries = batch; Tracer.TraceInformation("should-return-for-more {0}", importReturnInfo.MoreToImport); Tracer.TraceInformation("custom-data '{0}'", importReturnInfo.CustomData); Tracer.TraceInformation("connector-space-object(s)-returned {0:n0}", importReturnInfo.CSEntries.Count); return(importReturnInfo); #endregion } catch (Exception ex) { Tracer.TraceError("getimportentries", ex); throw; } finally { Tracer.Unindent(); Tracer.Exit("getimportentries"); } }
PutExportEntriesResults IMAExtensible2CallExport.PutExportEntries(IList <CSEntryChange> csentries) { Tracer.Enter("putexportentries"); Tracer.Indent(); PutExportEntriesResults exportEntries = new PutExportEntriesResults(); PSDataCollection <PSObject> exportPipeline = new PSDataCollection <PSObject>(); try { Command cmd = new Command(Path.GetFullPath(ExportScript)); cmd.Parameters.Add(new CommandParameter("User", Username)); cmd.Parameters.Add(new CommandParameter("Password", Password)); cmd.Parameters.Add(new CommandParameter("Credentials", GetSecureCredentials())); cmd.Parameters.Add(new CommandParameter("ExportType", exportType)); foreach (CSEntryChange csentryChange in csentries) { Tracer.TraceInformation("adding-object id: {0}, dn: '{1}' [{2}]", csentryChange.Identifier, csentryChange.DN, csentryChange.ObjectModificationType); if (ExportSimpleObjects) { // http://karlprosser.com/coder/2008/06/12/generating-a-propertybag-aka-pscustomobject-in-c/ // creating a PSobject without any parameters in the constructor creates a PSCustomObject PSObject obj = new PSObject(); // PSNoteProperties are not strongly typed but do contain an explicit type. obj.Properties.Add(new PSNoteProperty(Constants.ControlValues.Identifier, csentryChange.Identifier.ToString())); obj.Properties.Add(new PSNoteProperty(Constants.ControlValues.Anchor, csentryChange.AnchorAttributes.Count > 0 ? csentryChange.AnchorAttributes.FirstOrDefault().Value : "")); obj.Properties.Add(new PSAliasProperty(Constants.ControlValues.IdentifierAsGuid, csentryChange.Identifier.ToString(), typeof(Guid))); obj.Properties.Add(new PSNoteProperty(Constants.ControlValues.ObjectModificationType, csentryChange.ObjectModificationType.ToString())); obj.Properties.Add(new PSNoteProperty(Constants.ControlValues.ObjectType, csentryChange.ObjectType)); List <string> attrs = schema.Types[csentryChange.ObjectType].Attributes.Select(a => a.Name).ToList <string>(); obj.Properties.Add(new PSNoteProperty(Constants.ControlValues.AttributeNames, attrs)); obj.Properties.Add(new PSNoteProperty(Constants.ControlValues.ChangedAttributeNames, csentryChange.ChangedAttributeNames == null ? new List <string>() : csentryChange.ChangedAttributeNames)); obj.Properties.Add(new PSNoteProperty(Constants.ControlValues.DN, csentryChange.DN)); obj.Properties.Add(new PSNoteProperty(Constants.ControlValues.RDN, csentryChange.RDN)); foreach (AttributeChange ac in csentryChange.AttributeChanges) { if (!ac.IsMultiValued) { foreach (ValueChange vc in ac.ValueChanges) { obj.Properties.Add(new PSNoteProperty(string.Format("{0}", ac.Name), vc.Value)); } } else { List <object> values = new List <object>(); foreach (ValueChange vc in ac.ValueChanges) { values.Add(vc.Value); } obj.Properties.Add(new PSNoteProperty(string.Format("{0}", ac.Name), values.ToArray())); } } exportPipeline.Add(obj); } else { exportPipeline.Add(new PSObject(csentryChange)); } } exportResults = InvokePowerShellScript(cmd, exportPipeline); if (exportResults != null) { foreach (PSObject result in exportResults) { if (result.BaseObject.GetType() != typeof(System.Collections.Hashtable)) { continue; } Hashtable hashTable = (Hashtable)result.BaseObject; string ErrorName = "unspecified-error"; string ErrorDetail = "No details specified"; Guid identifier = new Guid(); // get anchor attribute changes List <AttributeChange> attrchanges = new List <AttributeChange>(); foreach (string key in hashTable.Keys) { if (key.Equals(Constants.ControlValues.Identifier, StringComparison.OrdinalIgnoreCase)) { try { identifier = new Guid(hashTable[key].ToString()); Tracer.TraceInformation("got-identifier {0}, {1}", identifier, key); } catch (FormatException fex) { Tracer.TraceError("identifier-format-error '{0}'", fex.ToString()); } continue; } if (key.Equals(Constants.ControlValues.ErrorName, StringComparison.OrdinalIgnoreCase)) { ErrorName = hashTable[key].ToString(); Tracer.TraceInformation("got-errorname {0}, {1}", ErrorName, key); continue; } if (key.Equals(Constants.ControlValues.ErrorDetail, StringComparison.OrdinalIgnoreCase)) { ErrorDetail = hashTable[key].ToString(); Tracer.TraceInformation("got-errordetail {0}, {1}", ErrorDetail, key); continue; } if (!(Regex.IsMatch(key, @"^\[.+\]$", RegexOptions.IgnoreCase))) { Tracer.TraceInformation("got-attribute-change {0}: '{1}'", key, hashTable[key]); attrchanges.Add(AttributeChange.CreateAttributeAdd(key, hashTable[key])); continue; } } if (string.IsNullOrEmpty(ErrorName) || ErrorName.Equals("success", StringComparison.OrdinalIgnoreCase)) { Tracer.TraceInformation("returning-success id: {0}", identifier); CSEntryChangeResult cschangeresult = CSEntryChangeResult.Create(identifier, attrchanges, MAExportError.Success); exportEntries.CSEntryChangeResults.Add(cschangeresult); } else { Tracer.TraceInformation("returning-error id: {0}, name: {1}, details: {2}", identifier, ErrorName, ErrorDetail); CSEntryChangeResult cschangeresult = CSEntryChangeResult.Create(identifier, attrchanges, MAExportError.ExportErrorCustomContinueRun, ErrorName, ErrorDetail); exportEntries.CSEntryChangeResults.Add(cschangeresult); } } } exportPipeline.Clear(); exportResults.Clear(); exportResults = null; return(exportEntries); } catch (Exception ex) { Tracer.TraceError("putexportentries", ex); throw; } finally { Tracer.Unindent(); Tracer.Exit("putexportentries"); } }
public OpenImportConnectionResults OpenImportConnection(System.Collections.ObjectModel.KeyedCollection <string, ConfigParameter> configParameters, Schema types, OpenImportConnectionRunStep openImportRunStep) { Tracer.IndentLevel = 0; Tracer.Enter("openimportconnection"); Tracer.Indent(); try { Tracer.TraceInformation("getting-schema"); Tracer.Indent(); try { foreach (SchemaType type in types.Types) { foreach (SchemaAttribute attr in type.AnchorAttributes) { Tracer.TraceInformation("{0}-anchor-attribute {1} [{2}]", type.Name, attr.Name, attr.DataType); objectTypeAnchorAttributeNames.Add(type.Name, attr.Name); } foreach (SchemaAttribute attr in type.Attributes) { Tracer.TraceInformation("{0}-attribute {1} [{2}]", type.Name, attr.Name, attr.DataType); } } schema = types; } catch (Exception ex) { Tracer.TraceError("getting-schema", ex); } finally { Tracer.Unindent(); Tracer.TraceInformation("got-schema"); } InitializeConfigParameters(configParameters); //SetupImpersonationToken(); OpenRunspace(); Tracer.TraceInformation("resetting-pipeline-results-and-counters"); importResults = new List <PSObject>(); pageToken = ""; OpenImportConnectionResults oicr = new OpenImportConnectionResults(); ImportRunStepPageSize = openImportRunStep.PageSize; Tracer.TraceInformation("openimportrunstep-pagesize '{0}'", ImportRunStepPageSize); oicr.CustomData = openImportRunStep.ImportType == OperationType.Full ? "" : openImportRunStep.CustomData; Tracer.TraceInformation("openimportrunstep-customdata '{0}'", oicr.CustomData); importOperationType = openImportRunStep.ImportType; Tracer.TraceInformation("openimportrunstep-importtype '{0}'", importOperationType); return(oicr); } catch (Exception ex) { Tracer.TraceError("openimportconnection", ex); throw; } finally { Tracer.Unindent(); Tracer.Exit("openimportconnection"); } }
Schema IMAExtensible2GetSchema.GetSchema(KeyedCollection <string, ConfigParameter> configParameters) { Tracer.Enter("getschema"); Tracer.Indent(); try { Schema schema = Schema.Create(); InitializeConfigParameters(configParameters); OpenRunspace(); Command cmd = new Command(Path.GetFullPath(SchemaScript)); cmd.Parameters.Add(new CommandParameter("Username", Username)); cmd.Parameters.Add(new CommandParameter("Password", Password)); cmd.Parameters.Add(new CommandParameter("Credentials", GetSecureCredentials())); schemaResults = InvokePowerShellScript(cmd, null); CloseRunspace(); if (schemaResults != null) { foreach (PSObject obj in schemaResults) { string objectTypeName = null; HashSet <AttributeDefinition> attrs = new HashSet <AttributeDefinition>(); foreach (PSPropertyInfo p in obj.Properties) { string[] elements = p.Name.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); string attrName = elements[0].Trim(); string attrType = elements[1].Trim(); if (string.Equals(attrName, Constants.ControlValues.ObjectClass, StringComparison.OrdinalIgnoreCase)) { objectTypeName = p.Value.ToString(); Tracer.TraceInformation("object-class '{0}'", objectTypeName); } else { AttributeDefinition ad = new AttributeDefinition(); ad.Name = Regex.Replace(attrName, "^Anchor-", "", RegexOptions.IgnoreCase); ad.IsAnchor = p.Name.StartsWith("anchor-", StringComparison.OrdinalIgnoreCase); ad.IsMultiValue = p.Name.EndsWith("[]", StringComparison.OrdinalIgnoreCase); switch (attrType.Replace("[]", "").ToLower()) { case "boolean": ad.Type = AttributeType.Boolean; break; case "binary": ad.Type = AttributeType.Binary; break; case "integer": ad.Type = AttributeType.Integer; break; case "reference": ad.Type = AttributeType.Reference; break; case "string": ad.Type = AttributeType.String; break; default: ad.Type = AttributeType.String; break; } Tracer.TraceInformation("name '{0}', isanchor: {1}, ismultivalue: {2}, type: {3}", ad.Name, ad.IsAnchor, ad.IsMultiValue, ad.Type.ToString()); attrs.Add(ad); } } if (string.IsNullOrEmpty(objectTypeName)) { Tracer.TraceError("missing-object-class"); throw new Microsoft.MetadirectoryServices.NoSuchObjectTypeException(); } SchemaType objectClass = SchemaType.Create(objectTypeName, true); foreach (AttributeDefinition def in attrs) { if (def.IsAnchor) { objectClass.Attributes.Add(SchemaAttribute.CreateAnchorAttribute(def.Name, def.Type)); } else { if (def.IsMultiValue) { objectClass.Attributes.Add(SchemaAttribute.CreateMultiValuedAttribute(def.Name, def.Type)); } else { objectClass.Attributes.Add(SchemaAttribute.CreateSingleValuedAttribute(def.Name, def.Type)); } } } if (objectClass.AnchorAttributes.Count == 1) { schema.Types.Add(objectClass); } else { Tracer.TraceError("missing-anchor-definition-on-object"); throw new Microsoft.MetadirectoryServices.AttributeNotPresentException(); } } } schemaResults.Clear(); return(schema); } catch (Exception ex) { Tracer.TraceError("getschema", ex); throw; } finally { Tracer.Unindent(); Tracer.Exit("getschema"); } }
void OpenRunspace() { Tracer.Enter("openrunspace"); Tracer.Indent(); try { if (runspace == null) { Tracer.TraceInformation("creating-runspace"); runspace = RunspaceFactory.CreateRunspace(); runspace.ApartmentState = System.Threading.ApartmentState.STA; runspace.ThreadOptions = PSThreadOptions.Default; runspace.StateChanged += Runspace_StateChanged; runspace.AvailabilityChanged += Runspace_AvailabilityChanged; Tracer.TraceInformation("created-runspace"); } else { Tracer.TraceInformation("existing-runspace-state '{0}'", runspace.RunspaceStateInfo.State); } if (runspace.RunspaceStateInfo.State == RunspaceState.BeforeOpen) { Tracer.TraceInformation("opening-runspace"); runspace.Open(); } else { Tracer.TraceInformation("runspace-already-open"); } Tracer.TraceInformation("runspace-state '{0}'", runspace.RunspaceStateInfo.State); if (runspace.RunspaceStateInfo.State == RunspaceState.Opened) { Tracer.TraceInformation("runspace-powershell-version {0}.{1}", runspace.Version.Major, runspace.Version.Minor); } if (powershell == null) { Tracer.TraceInformation("creating-powershell"); powershell = PowerShell.Create(); powershell.Runspace = runspace; Tracer.TraceInformation("powershell instanceid: {0}, runspace-id: {1}", powershell.InstanceId, powershell.Runspace.InstanceId); Tracer.TraceInformation("powershell apartmentstate: {0}, version: {1}", powershell.Runspace.ApartmentState, powershell.Runspace.Version); // the streams (Error, Debug, Progress, etc) are available on the PowerShell instance. // we can review them during or after execution. // we can also be notified when a new item is written to the stream (like this): powershell.Streams.ClearStreams(); powershell.Streams.Error.DataAdded += new EventHandler <DataAddedEventArgs>(Error_DataAdded); powershell.Streams.Verbose.DataAdded += new EventHandler <DataAddedEventArgs>(Verbose_DataAdded); powershell.Streams.Warning.DataAdded += new EventHandler <DataAddedEventArgs>(Warning_DataAdded); powershell.Streams.Debug.DataAdded += new EventHandler <DataAddedEventArgs>(Debug_DataAdded); powershell.Streams.Progress.DataAdded += new EventHandler <DataAddedEventArgs>(Progress_DataAdded); Tracer.TraceInformation("created-powershell"); } } catch (Exception ex) { Tracer.TraceError("openrunspace", ex); throw; } finally { Tracer.Unindent(); Tracer.Exit("openrunspace"); } }