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); } } }
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 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); } } } }