Beispiel #1
0
        private void SetupListener()
        {
            try
            {
                this.stopped = false;
                LdapDirectoryIdentifier directory = new LdapDirectoryIdentifier(this.HostName);
                NetworkCredential       creds     = this.GetCredentialPackage();

                if (creds != null)
                {
                    this.Log($"Connecting to {this.HostName} as {this.Username}");
                    this.connection = new LdapConnection(directory, creds);
                }
                else
                {
                    this.Log($"Connecting to {this.HostName} as {Thread.CurrentPrincipal.Identity.Name}");
                    this.connection = new LdapConnection(directory);
                }

                List <string> attributesToGet = new List <string>()
                {
                    ActiveDirectoryChangeTrigger.ObjectClassAttribute
                };
                attributesToGet.AddRange(ActiveDirectoryChangeTrigger.TimeStampAttributesToIgnore);

                SearchRequest r = new SearchRequest(
                    this.BaseDN,
                    "(objectClass=*)",
                    SearchScope.Subtree,
                    attributesToGet.ToArray()
                    );

                r.Controls.Add(new DirectoryNotificationControl());

                this.request = this.connection.BeginSendRequest(
                    r,
                    TimeSpan.FromDays(100),
                    PartialResultProcessing.ReturnPartialResultsAndNotifyCallback,
                    this.Notify,
                    r);

                this.Log($"Listening for changes from {this.HostName}");
            }
            catch (Exception ex)
            {
                this.LogError("Could not start the listener", ex);

                if (MessageSender.CanSendMail())
                {
                    string messageContent = MessageBuilder.GetMessageBody(this.ManagementAgentName, this.Type, this.Description, DateTime.Now, true, ex);
                    MessageSender.SendMessage($"{this.ManagementAgentName}: {this.Type} trigger error", messageContent);
                }

                throw;
            }
        }
Beispiel #2
0
        private void SetupListener()
        {
            try
            {
                this.stopped = false;
                LdapDirectoryIdentifier directory = new LdapDirectoryIdentifier(this.HostName);

                if (this.HasCredentials)
                {
                    this.connection = new LdapConnection(directory, this.GetCredentialPackage());
                }
                else
                {
                    this.connection = new LdapConnection(directory);
                }

                SearchRequest r = new SearchRequest(
                    this.BaseDN,
                    "(objectClass=*)",
                    SearchScope.Subtree,
                    ActiveDirectoryChangeTrigger.ObjectClassAttribute,
                    ActiveDirectoryChangeTrigger.LastLogonAttributeName,
                    ActiveDirectoryChangeTrigger.LastLogonTimeStampAttributeName,
                    ActiveDirectoryChangeTrigger.BadPasswordAttribute);

                r.Controls.Add(new DirectoryNotificationControl());

                this.request = this.connection.BeginSendRequest(
                    r,
                    TimeSpan.FromDays(100),
                    PartialResultProcessing.ReturnPartialResultsAndNotifyCallback,
                    this.Notify,
                    r);
            }
            catch (Exception ex)
            {
                this.LogError("Could not start the listener", ex);

                if (MessageSender.CanSendMail())
                {
                    string messageContent = MessageBuilder.GetMessageBody(this.ManagementAgentName, this.Type, this.Description, DateTime.Now, true, ex);
                    MessageSender.SendMessage($"{this.ManagementAgentName}: {this.Type} trigger error", messageContent);
                }

                throw;
            }
        }
        private void CheckTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            try
            {
                ResourceManagementClient c = new ResourceManagementClient(this.HostName);

                string xpath;

                if (this.lastCheckDateTime == null)
                {
                    xpath = "/Request";
                    this.Trace("No watermark available. Querying for latest request history item");
                }
                else
                {
                    xpath = string.Format("/Request[msidmCompletedTime > '{0}']", this.lastCheckDateTime.Value.ToResourceManagementServiceDateFormat(false));
                    this.Trace($"Searching for changes since {this.lastCheckDateTime.Value.ToResourceManagementServiceDateFormat(false)}");
                }

                ISearchResultCollection r = c.GetResources(xpath, 1, new[] { "msidmCompletedTime" }, "msidmCompletedTime", false);

                this.Trace($"Found {r.Count} change{r.Count.Pluralize()}");

                if (r.Count <= 0)
                {
                    return;
                }

                this.lastCheckDateTime = r.First().Attributes["msidmCompletedTime"].DateTimeValue;

                this.Fire(MARunProfileType.DeltaImport, "default");
            }
            catch (Exception ex)
            {
                this.LogError("Change detection failed", ex);

                if (MessageSender.CanSendMail())
                {
                    string messageContent = MessageBuilder.GetMessageBody(this.ManagementAgentName, this.Type, this.Description, DateTime.Now, false, ex);
                    MessageSender.SendMessage($"{this.ManagementAgentName}: {this.Type} trigger error", messageContent);
                }
            }
        }
Beispiel #4
0
        private void Run()
        {
            try
            {
                Thread.CurrentThread.SetThreadName($"{this.DisplayName} on {this.ManagementAgentName}");

                this.powershell = PowerShell.Create();
                this.powershell.AddScript(System.IO.File.ReadAllText(this.ScriptPath));
                this.powershell.Invoke();

                if (this.powershell.Runspace.SessionStateProxy.InvokeCommand.GetCommand("Get-RunProfileToExecute", CommandTypes.All) == null)
                {
                    this.LogError($"The file '{this.ScriptPath}' did not contain a function called Get-RunProfileToExecute and will be ignored");
                    return;
                }

                while (!this.cancellationToken.Token.IsCancellationRequested)
                {
                    this.cancellationToken.Token.ThrowIfCancellationRequested();

                    this.powershell.ResetState();

                    this.powershell.AddCommand("Get-RunProfileToExecute");

                    Collection <PSObject> results;

                    try
                    {
                        results = this.powershell.Invoke();
                        this.cancellationToken.Token.ThrowIfCancellationRequested();
                        this.powershell.ThrowOnPipelineError();
                    }
                    catch (OperationCanceledException)
                    {
                        throw;
                    }
                    catch (Exception ex)
                    {
                        bool shouldTerminate = this.ExceptionBehaviour == ExecutionErrorBehaviour.Terminate;

                        this.LogError($"The PowerShell execution trigger '{this.DisplayName}' encountered an error", ex);

                        if (MessageSender.CanSendMail())
                        {
                            string messageContent = MessageBuilder.GetMessageBody(this.ManagementAgentName, this.Type, this.Description, DateTime.Now, shouldTerminate, ex);
                            MessageSender.SendMessage($"{this.ManagementAgentName}: {this.Type} trigger error", messageContent);
                        }

                        if (shouldTerminate)
                        {
                            this.Log("The PowerShell trigger has been terminated as specified by config");
                            break;
                        }
                        else
                        {
                            if (!this.cancellationToken.IsCancellationRequested)
                            {
                                this.cancellationToken.Token.WaitHandle.WaitOne(this.Interval);
                            }

                            continue;
                        }
                    }

                    foreach (PSObject result in results)
                    {
                        string runProfileName = result.BaseObject as string;

                        if (runProfileName != null)
                        {
                            this.Fire(runProfileName);
                            continue;
                        }

                        ExecutionParameters p = result.BaseObject as ExecutionParameters;

                        if (p == null)
                        {
                            continue;
                        }

                        this.Fire(p);
                    }

                    this.cancellationToken.Token.ThrowIfCancellationRequested();
                    this.cancellationToken.Token.WaitHandle.WaitOne(this.Interval);
                }
            }
            catch (OperationCanceledException)
            {
            }
            catch (Exception ex)
            {
                this.LogError("The PowerShell execution trigger encountered an error and has been terminated", ex);

                if (MessageSender.CanSendMail())
                {
                    string messageContent = MessageBuilder.GetMessageBody(this.ManagementAgentName, this.Type, this.Description, DateTime.Now, true, ex);
                    MessageSender.SendMessage($"{this.ManagementAgentName}: {this.Type} trigger error", messageContent);
                }
            }
        }
        private void Run()
        {
            try
            {
                Thread.CurrentThread.SetThreadName($"{this.DisplayName} on {this.ManagementAgentName}");

                this.powershell = PowerShell.Create();
                this.powershell.AddScript(System.IO.File.ReadAllText(this.ScriptPath));
                this.powershell.Invoke();

                CommandInfo c = this.powershell.Runspace.SessionStateProxy.InvokeCommand.GetCommand("Get-RunProfileToExecute", CommandTypes.All);

                if (c == null)
                {
                    this.LogError($"The file '{this.ScriptPath}' did not contain a function called Get-RunProfileToExecute and will be ignored");
                    return;
                }

                bool cmdletRequiresCredentials = c.Parameters.ContainsKey("credentials");

                PSCredential creds = this.GetCredentialPackage();

                if (creds != null && !cmdletRequiresCredentials)
                {
                    this.LogError("Credentials were provided for the PowerShell script, but the Get-RunProfileToExecute function did not contain a 'credentials' parameter. See the wiki topic (https://github.com/lithnet/miis-autosync/wiki/Powershell-script-trigger) for more information");
                }

                while (!this.cancellationToken.Token.IsCancellationRequested)
                {
                    this.cancellationToken.Token.ThrowIfCancellationRequested();

                    this.powershell.ResetState();

                    if (cmdletRequiresCredentials)
                    {
                        this.powershell.AddCommand("Get-RunProfileToExecute").AddParameter("credentials", creds);
                    }
                    else
                    {
                        this.powershell.AddCommand("Get-RunProfileToExecute");
                    }

                    Collection <PSObject> results;

                    try
                    {
                        results = this.powershell.Invoke();
                        this.cancellationToken.Token.ThrowIfCancellationRequested();
                        this.powershell.ThrowOnPipelineError();
                    }
                    catch (OperationCanceledException)
                    {
                        throw;
                    }
                    catch (Exception ex)
                    {
                        bool shouldTerminate = this.ExceptionBehaviour == ExecutionErrorBehaviour.Terminate;

                        this.LogError($"The PowerShell execution trigger '{this.DisplayName}' encountered an error", ex);

                        if (MessageSender.CanSendMail())
                        {
                            string messageContent = MessageBuilder.GetMessageBody(this.ManagementAgentName, this.Type, this.Description, DateTime.Now, shouldTerminate, ex);
                            MessageSender.SendMessage($"{this.ManagementAgentName}: {this.Type} trigger error", messageContent);
                        }

                        if (shouldTerminate)
                        {
                            this.Log("The PowerShell trigger has been terminated as specified by config");
                            break;
                        }
                        else
                        {
                            if (!this.cancellationToken.IsCancellationRequested)
                            {
                                this.cancellationToken.Token.WaitHandle.WaitOne(this.Interval);
                            }

                            continue;
                        }
                    }

                    foreach (PSObject result in results)
                    {
                        string runProfileName = result.BaseObject as string;

                        if (runProfileName != null)
                        {
                            this.Fire(runProfileName);
                            continue;
                        }

                        ExecutionParameters p = result.BaseObject as ExecutionParameters;

                        if (p == null)
                        {
                            continue;
                        }

                        this.Fire(p);
                    }

                    this.cancellationToken.Token.ThrowIfCancellationRequested();
                    this.cancellationToken.Token.WaitHandle.WaitOne(this.Interval);
                }
            }
            catch (OperationCanceledException)
            {
            }
            catch (Exception ex)
            {
                this.LogError("The PowerShell execution trigger encountered an error and has been terminated", ex);

                if (MessageSender.CanSendMail())
                {
                    string messageContent = MessageBuilder.GetMessageBody(this.ManagementAgentName, this.Type, this.Description, DateTime.Now, true, ex);
                    MessageSender.SendMessage($"{this.ManagementAgentName}: {this.Type} trigger error", messageContent);
                }
            }
        }
Beispiel #6
0
        private void Notify(IAsyncResult result)
        {
            lock (this.lockObject)
            {
                try
                {
                    if (this.stopped)
                    {
                        this.connection?.EndSendRequest(result);
                        return;
                    }

                    PartialResultsCollection resultsCollection = this.connection?.GetPartialResults(result);

                    if (resultsCollection == null)
                    {
                        this.Trace("Results collection was empty");
                        return;
                    }

                    if (DateTime.Now < this.nextTriggerAfter)
                    {
                        //this.Trace("Discarding change because next trigger time has not been reached");
                        return;
                    }

                    DateTime lastLogonOldestDate = DateTime.UtcNow.Subtract(this.LastLogonTimestampOffset);

                    foreach (SearchResultEntry r in resultsCollection.OfType <SearchResultEntry>())
                    {
                        if (r.Attributes == null || !r.Attributes.Contains(ActiveDirectoryChangeTrigger.ObjectClassAttribute))
                        {
                            this.Trace($"Skipping entry {r.DistinguishedName} because the object class list was empty");
                            continue;
                        }

                        IList <string> objectClasses = r.Attributes[ActiveDirectoryChangeTrigger.ObjectClassAttribute].GetValues(typeof(string)).OfType <string>().ToList();

                        if (!this.ObjectClasses.Intersect(objectClasses, StringComparer.OrdinalIgnoreCase).Any())
                        {
                            continue;
                        }

                        if (objectClasses.Contains("computer", StringComparer.OrdinalIgnoreCase) && !this.ObjectClasses.Contains("computer", StringComparer.OrdinalIgnoreCase))
                        {
                            continue;
                        }

                        bool dateTooSoon = false;

                        foreach (string timestampAttribute in ActiveDirectoryChangeTrigger.TimeStampAttributesToIgnore)
                        {
                            if (r.Attributes.Contains(timestampAttribute))
                            {
                                string   ts    = r.Attributes[timestampAttribute][0] as string;
                                DateTime date1 = DateTime.FromFileTimeUtc(Convert.ToInt64(ts));

                                if (date1 > lastLogonOldestDate)
                                {
                                    dateTooSoon = true;
                                    break;
                                }
                            }
                        }

                        if (dateTooSoon)
                        {
                            continue;
                        }

                        this.Log($"Change detected on {r.DistinguishedName}");

                        this.Fire();
                    }
                }
                catch (LdapException ex)
                {
                    if (ex.ErrorCode == 85)
                    {
                        this.SetupListener();
                    }
                    else
                    {
                        this.LogError("The AD change listener encountered an unexpected error", ex);

                        if (MessageSender.CanSendMail())
                        {
                            string messageContent = MessageBuilder.GetMessageBody(this.ManagementAgentName, this.Type, this.Description, DateTime.Now, false, ex);
                            MessageSender.SendMessage($"{this.ManagementAgentName}: {this.Type} trigger error", messageContent);
                            Thread.Sleep(1000);
                        }
                    }
                }
                catch (Exception ex)
                {
                    this.LogError("The AD change listener encountered an unexpected error", ex);

                    if (MessageSender.CanSendMail())
                    {
                        string messageContent = MessageBuilder.GetMessageBody(this.ManagementAgentName, this.Type, this.Description, DateTime.Now, false, ex);
                        MessageSender.SendMessage($"{this.ManagementAgentName}: {this.Type} trigger error", messageContent);
                        Thread.Sleep(1000);
                    }
                }
            }
        }