public override object GetParametersInstance()
    {
        ActiveDirectoryHandlerParameters parms = new ActiveDirectoryHandlerParameters();

        parms.Users = new List <AdUser>();
        AdUser user = new AdUser();

        user.Identity = "cn=mfox,ou=FamousActors,dc=sandbox,dc=local";
        parms.Users.Add(user);

        parms.Groups = new List <AdGroup>();
        AdGroup group = new AdGroup();

        group.Identity = "cn=BackToTheFuture,ou=Movies,dc=sandbox,dc=local";
        parms.Groups.Add(group);

        parms.OrganizationalUnits = new List <AdOrganizationalUnit>();
        AdOrganizationalUnit ou = new AdOrganizationalUnit();

        ou.Identity = "ou=Movies,dc=sandbox,dc=local";
        parms.OrganizationalUnits.Add(ou);

        parms.SearchRequests = new List <AdSearchRequest>();
        AdSearchRequest search = new AdSearchRequest();

        search.SearchBase       = "ou=Synapse,dc=sandbox,dc=local";
        search.Filter           = "(objectClass=User)";
        search.ReturnAttributes = new List <string>();
        search.ReturnAttributes.Add("Name");
        search.ReturnAttributes.Add("objectGUID");
        parms.SearchRequests.Add(search);


        return(parms);
    }
    public override ExecuteResult Execute(HandlerStartInfo startInfo)
    {
        int           cheapSequence = 0;
        const string  __context     = "Execute";
        ExecuteResult result        = new ExecuteResult()
        {
            Status   = StatusType.Complete,
            Sequence = int.MaxValue
        };
        string    msg = "Complete";
        Exception exc = null;

        this.startInfo = startInfo;
        requestUser    = WhoAmI();
        isDryRun       = startInfo.IsDryRun;

        try
        {
            //deserialize the Parameters from the Action declaration
            ActiveDirectoryHandlerParameters parameters = YamlHelpers.Deserialize <ActiveDirectoryHandlerParameters>(startInfo.Parameters);

            OnLogMessage("Execute", $"Running Handler As User [{System.Security.Principal.WindowsIdentity.GetCurrent().Name}]");
            OnLogMessage("Execute", $"Request User : [{requestUser}]");

            //TODO : if IsDryRun == true, test if ConnectionString is valid and works.
            if (startInfo.IsDryRun)
            {
                OnProgress(__context, "Attempting connection", sequence: cheapSequence++);


                result.ExitData = "Success";
                result.Message  = msg =
                    $"Connection test successful!";

                throw new NotImplementedException("Dry Run Functionality Has Not Yet Been Implemented.");
            }
            else
            {
                switch (config.Action)
                {
                case ActionType.Get:
                    ProcessActiveDirectoryObjects(parameters.Users, ProcessGet);
                    ProcessActiveDirectoryObjects(parameters.Groups, ProcessGet);
                    ProcessActiveDirectoryObjects(parameters.OrganizationalUnits, ProcessGet);
                    break;

                case ActionType.Create:
                    ProcessActiveDirectoryObjects(parameters.OrganizationalUnits, ProcessCreate);
                    ProcessActiveDirectoryObjects(parameters.Groups, ProcessCreate);
                    ProcessActiveDirectoryObjects(parameters.Users, ProcessCreate);
                    break;

                case ActionType.Modify:
                    ProcessActiveDirectoryObjects(parameters.OrganizationalUnits, ProcessModify);
                    ProcessActiveDirectoryObjects(parameters.Groups, ProcessModify);
                    ProcessActiveDirectoryObjects(parameters.Users, ProcessModify);
                    break;

                case ActionType.Delete:
                    ProcessActiveDirectoryObjects(parameters.Users, ProcessDelete);
                    ProcessActiveDirectoryObjects(parameters.Groups, ProcessDelete);
                    ProcessActiveDirectoryObjects(parameters.OrganizationalUnits, ProcessDelete);
                    break;

                case ActionType.AddToGroup:
                    ProcessActiveDirectoryObjects(parameters.Users, ProcessGroupAdd);
                    ProcessActiveDirectoryObjects(parameters.Groups, ProcessGroupAdd);
                    break;

                case ActionType.RemoveFromGroup:
                    ProcessActiveDirectoryObjects(parameters.Users, ProcessGroupRemove);
                    ProcessActiveDirectoryObjects(parameters.Groups, ProcessGroupRemove);
                    break;

                case ActionType.AddAccessRule:
                    ProcessActiveDirectoryObjects(parameters.Users, ProcessAccessRules);
                    ProcessActiveDirectoryObjects(parameters.Groups, ProcessAccessRules);
                    ProcessActiveDirectoryObjects(parameters.OrganizationalUnits, ProcessAccessRules);
                    break;

                case ActionType.RemoveAccessRule:
                    ProcessActiveDirectoryObjects(parameters.Users, ProcessAccessRules);
                    ProcessActiveDirectoryObjects(parameters.Groups, ProcessAccessRules);
                    ProcessActiveDirectoryObjects(parameters.OrganizationalUnits, ProcessAccessRules);
                    break;

                case ActionType.SetAccessRule:
                    ProcessActiveDirectoryObjects(parameters.Users, ProcessAccessRules);
                    ProcessActiveDirectoryObjects(parameters.Groups, ProcessAccessRules);
                    ProcessActiveDirectoryObjects(parameters.OrganizationalUnits, ProcessAccessRules);
                    break;

                case ActionType.PurgeAccessRules:
                    ProcessActiveDirectoryObjects(parameters.Users, ProcessAccessRules);
                    ProcessActiveDirectoryObjects(parameters.Groups, ProcessAccessRules);
                    ProcessActiveDirectoryObjects(parameters.OrganizationalUnits, ProcessAccessRules);
                    break;

                case ActionType.AddRole:
                    ProcessActiveDirectoryObjects(parameters.Users, ProcessRoles);
                    ProcessActiveDirectoryObjects(parameters.Groups, ProcessRoles);
                    ProcessActiveDirectoryObjects(parameters.OrganizationalUnits, ProcessRoles);
                    break;

                case ActionType.RemoveRole:
                    ProcessActiveDirectoryObjects(parameters.Users, ProcessRoles);
                    ProcessActiveDirectoryObjects(parameters.Groups, ProcessRoles);
                    ProcessActiveDirectoryObjects(parameters.OrganizationalUnits, ProcessRoles);
                    break;

                case ActionType.Search:
                    ProcessSearchRequests(parameters.SearchRequests);
                    break;

                default:
                    throw new AdException($"Unknown Action {config.Action} Specified", AdStatusType.NotSupported);
                }
            }
        }
        //something wnet wrong: hand-back the Exception and mark the execution as Failed
        catch (Exception ex)
        {
            exc             = ex;
            result.Status   = StatusType.Failed;
            result.ExitData = msg =
                ex.Message + " | " + ex.InnerException?.Message;
        }

        if (string.IsNullOrWhiteSpace(result.ExitData?.ToString()))
        {
            result.ExitData = results.Serialize(config.OutputType, config.PrettyPrint);
        }

        if (!config.SuppressOutput)
        {
            OnProgress(__context, result.ExitData?.ToString(), result.Status, sequence: cheapSequence++, ex: exc);
        }

        //final runtime notification, return sequence=Int32.MaxValue by convention to supercede any other status message
        OnProgress(__context, msg, result.Status, sequence: int.MaxValue, ex: exc);

        return(result);
    }