public bool Run(DtoClientPolicy singleModulePolicy = null) { if (singleModulePolicy == null) { _policiesToRun = _trigger == EnumPolicy.Trigger.Login ? new APICall().LocalApi.GetLoginPolicies(Environment.UserDomainName + "\\" + Environment.UserName) : new PolicySelector(_trigger, Environment.UserDomainName + "\\" + Environment.UserName).GetPoliciesToExecute(); } else { _policiesToRun = new DtoTriggerResponse(); _policiesToRun.Policies.Add(singleModulePolicy); } if (_policiesToRun == null) { Logger.Error("Error Trying To Parse Policies. Aborting Trigger: " + _trigger); return(false); } if (_policiesToRun.Policies.Count == 0) { Logger.Info(string.Format("No Policies For Trigger {0} Were Found For This Computer", _trigger)); return(true); } DtoGobalSettings.PolicyIsRunning = true; bool cacheFailedWithTriggerStop = false; //Check for any conditions that will need cached var conditionNeedsCached = false; if (_policiesToRun.Policies.Any(x => x.MessageModules.Any())) { foreach (var messageModule in _policiesToRun.Policies.Select(x => x.MessageModules)) { if (messageModule.Any(x => x.Condition.Guid != null)) { conditionNeedsCached = true; break; } } } if (_policiesToRun.Policies.Any(x => x.PrinterModules.Any()) && !conditionNeedsCached) { foreach (var printerModule in _policiesToRun.Policies.Select(x => x.PrinterModules)) { if (printerModule.Any(x => x.Condition.Guid != null)) { conditionNeedsCached = true; break; } } } //Check if install of remote access needs cached var remotelyNeedsCached = false; if (_policiesToRun.Policies.Any(x => x.RemoteAccess == EnumPolicy.RemoteAccess.ForceReinstall)) { remotelyNeedsCached = true; } else if (new ServiceSystemService().IsRemotelyInstalled()) { remotelyNeedsCached = false; } else if (_policiesToRun.Policies.Any(x => x.RemoteAccess == EnumPolicy.RemoteAccess.Enabled)) { remotelyNeedsCached = true; } //cache all policies first if any need cached if (_policiesToRun.Policies.Any(x => x.SoftwareModules.Any() || x.FileCopyModules.Any() || x.WuModules.Any() || x.ScriptModules.Any() || x.CommandModules.Any()) || conditionNeedsCached || _policiesToRun.Policies.Any(x => x.Condition.Guid != null) || remotelyNeedsCached) { //grab a download slot Logger.Debug("Obtaining A Download Connection."); var downloadConRequest = new DtoDownloadConRequest(); downloadConRequest.ComputerGuid = DtoGobalSettings.ClientIdentity.Guid; downloadConRequest.ComputerName = DtoGobalSettings.ClientIdentity.Name; downloadConRequest.ComServer = DtoGobalSettings.ComServer; var downloadConnection = new DtoDownloadConnectionResult(); if (_trigger == EnumPolicy.Trigger.Login) { downloadConnection = new APICall().LocalApi.CreateDownloadConnection(downloadConRequest); } else { downloadConnection = new APICall().PolicyApi.CreateDownloadConnection(downloadConRequest); } var conAttempCounter = 0; while (downloadConnection.QueueIsFull || !downloadConnection.Success) { if (!downloadConnection.Success) { Logger.Error("Could Not Obtain Download Connection. " + downloadConnection.ErrorMessage); DtoGobalSettings.PolicyIsRunning = false; return(true); } if (downloadConnection.QueueIsFull && conAttempCounter == 0) { Logger.Debug("Download Connections Are Full. Will Retry Continuously Every 1 Minute For The Next 10 Minutes."); } Task.Delay(60 * 1000).Wait(); conAttempCounter++; if (conAttempCounter == 10) { Logger.Debug("Download Connections Remain Filled. Giving Up. Will Retry At Next Checkin."); return(true); } if (_trigger == EnumPolicy.Trigger.Login) { downloadConnection = new APICall().LocalApi.CreateDownloadConnection(downloadConRequest); } else { downloadConnection = new APICall().PolicyApi.CreateDownloadConnection(downloadConRequest); } } foreach (var policy in _policiesToRun.Policies) { SetPolicyLogLevel(policy); var cacheResult = new PolicyCacher(policy).Cache(); if (policy.SkipServerResult) { cacheResult.SkipServerResult = true; } if (policy.ExecutionType == EnumPolicy.ExecutionType.Cache) { _policyResults.Add(cacheResult); } if (cacheResult.PolicyResult != EnumPolicy.Result.Success) { if (IsTriggerStopError(policy)) { cacheFailedWithTriggerStop = true; break; } } } //release the download slot Logger.Debug("Releasing The Download Connection."); if (_trigger == EnumPolicy.Trigger.Login) { new APICall().LocalApi.RemoveDownloadConnection(downloadConRequest); } else { new APICall().PolicyApi.RemoveDownloadConnection(downloadConRequest); } } if (!cacheFailedWithTriggerStop) { foreach (var policy in _policiesToRun.Policies) { SetPolicyLogLevel(policy); if (policy.ExecutionType == EnumPolicy.ExecutionType.Cache) { Logger.Debug("Policy's Execution Type Is Cache Only And Will Not Install"); continue; } var policyResult = new PolicyExecutor(policy).Execute(); if (policy.SkipServerResult) { policyResult.SkipServerResult = true; } _policyResults.Add(policyResult); if (policyResult.PolicyResult == EnumPolicy.Result.Failed) { if (IsTriggerStopError(policy)) { break; } } else if (policyResult.PolicyResult == EnumPolicy.Result.Success && policy.CompletedAction == EnumPolicy.CompletedAction.Reboot) { _reboot = true; break; } else if (policyResult.PolicyResult == EnumPolicy.Result.Success && policy.CompletedAction == EnumPolicy.CompletedAction.RebootIfNoLogins) { _rebootNoLogins = true; break; } } } Logger.Info("Policies Complete. Starting Policy Cleanup."); DtoGobalSettings.PolicyIsRunning = false; RecordResults(); CleanupCache(); //restore global log level ((Hierarchy)LogManager.GetRepository()).Root.Level = DtoGobalSettings.LogLevel; ((Hierarchy)LogManager.GetRepository()).RaiseConfigurationChanged( EventArgs.Empty); if (_reboot) { Logger.Info("Policy Initiated Reboot. Rebooting Now."); if (_trigger == EnumPolicy.Trigger.Login) { new APICall().LocalApi.LogoutAllUsers(); } else { new ServiceUserTracker().LogoutAllUsers(); } Process.Start("shutdown.exe", "/r /t " + DtoGobalSettings.ShutdownDelay); } if (_rebootNoLogins) { Logger.Info("Policy Initiated Reboot If No Users Are Logged In."); Logger.Info("Checking For Any Logged In Users."); if (_trigger != EnumPolicy.Trigger.Login) { var users = new ServiceUserLogins().GetUsersLoggedIn(); if (users.Count > 0) { Logger.Info("User Found, Reboot Skipped."); } else { Logger.Info("No Users Found, Issuing Reboot Command."); Process.Start("shutdown.exe", "/r /t " + DtoGobalSettings.ShutdownDelay); } } else { Logger.Info("User Found, Policy Is A Login Policy, Reboot Skipped."); } } return(true); }
public DtoTriggerResponse Execute(DtoPolicyRequest policyRequest) { var triggerResponse = new DtoTriggerResponse(); var list = new List <DtoClientPolicy>(); var computer = _uow.ComputerRepository.GetFirstOrDefault(x => x.Guid == policyRequest.ClientIdentity.Guid); if (computer == null) { return(null); } if (string.IsNullOrEmpty(policyRequest.CurrentComServer)) { Logger.Debug("Could Not Determine The Client's Policy. A Com Server Was Not Provided."); return(null); } //without this, viewing the computer's effective policy, clears these values if (!string.IsNullOrEmpty(policyRequest.ClientVersion) && !string.IsNullOrEmpty(policyRequest.PushURL)) { computer.LastCheckinTime = DateTime.Now; computer.ClientVersion = policyRequest.ClientVersion; computer.PushUrl = policyRequest.PushURL; computer.LastIp = IpServices.GetIPAddress(); new ServiceComputer().UpdateComputer(computer); } var groupMemberships = _uow.GroupRepository.GetMembershipsForClientPolicy(computer.Id); if (policyRequest.UserLogins != null) { var userLoginsResult = new ServiceUserLogins().AddOrUpdate(policyRequest.UserLogins, computer.Id); if (userLoginsResult != null) { triggerResponse.UserLoginsSubmitted = userLoginsResult.Success; } } if (policyRequest.AppMonitors != null) { var appMonitorResult = new ServiceAppMonitor().AddOrUpdate(policyRequest.AppMonitors, computer.Id); if (appMonitorResult != null) { triggerResponse.AppMonitorSubmitted = appMonitorResult.Success; } } foreach (var membership in groupMemberships) { var clientPoliciesJson = new ServiceGroup().GetActiveGroupPolicy(membership.GroupId); if (clientPoliciesJson == null) { continue; } if (policyRequest.Trigger == EnumPolicy.Trigger.Startup) { list.AddRange(JsonConvert.DeserializeObject <List <DtoClientPolicy> >(clientPoliciesJson.PolicyJson).Where(x => x.StartDate <= DateTime.UtcNow && (x.Trigger == EnumPolicy.Trigger.Startup || x.Trigger == EnumPolicy.Trigger.StartupOrCheckin))); } else if (policyRequest.Trigger == EnumPolicy.Trigger.Checkin) { list.AddRange(JsonConvert.DeserializeObject <List <DtoClientPolicy> >(clientPoliciesJson.PolicyJson).Where(x => x.StartDate <= DateTime.UtcNow && (x.Trigger == EnumPolicy.Trigger.Checkin || x.Trigger == EnumPolicy.Trigger.StartupOrCheckin))); } else { list.AddRange(JsonConvert.DeserializeObject <List <DtoClientPolicy> >(clientPoliciesJson.PolicyJson).Where(x => x.StartDate <= DateTime.UtcNow && x.Trigger == policyRequest.Trigger)); } } var distinctList = list.GroupBy(dto => dto.Guid).Select(y => y.First()).ToList(); var toRemoveByComServer = new List <DtoClientPolicy>(); //refine list to only designated com servers foreach (var p in distinctList) { if (p.PolicyComCondition == EnumPolicy.PolicyComCondition.Any) { continue; } var policyComServers = _uow.PolicyRepository.GetPolicyComServerUrls(p.Id); if (!policyComServers.Contains(policyRequest.CurrentComServer.ToLower())) { toRemoveByComServer.Add(p); } } foreach (var p in toRemoveByComServer) { distinctList.Remove(p); } //refine list to designated schedules var currentDayOfWeek = (int)DateTime.Now.DayOfWeek; var currentTimeOfDay = DateTime.Now.TimeOfDay; var serviceSchedule = new ServiceSchedule(); var toRemoveBySchedule = new List <DtoClientPolicy>(); foreach (var p in distinctList.Where(x => x.StartWindowScheduleId != -1 && x.EndWindowScheduleId != -1 && x.Trigger != EnumPolicy.Trigger.Login)) { //items in here have a more refined schedule. Check if they should be removed from the current run list. var start = serviceSchedule.GetSchedule(p.StartWindowScheduleId); var end = serviceSchedule.GetSchedule(p.EndWindowScheduleId); if (start == null || end == null) { continue; } if (!start.IsActive || !end.IsActive) { continue; } if (p.Frequency != EnumPolicy.Frequency.OncePerWeek && p.Frequency != EnumPolicy.Frequency.OncePerMonth) //day of week is already defined in weekly frequency and day of month is already defined { if (currentDayOfWeek == 0 && !start.Sunday) { toRemoveBySchedule.Add(p); } else if (currentDayOfWeek == 1 && !start.Monday) { toRemoveBySchedule.Add(p); } else if (currentDayOfWeek == 2 && !start.Tuesday) { toRemoveBySchedule.Add(p); } else if (currentDayOfWeek == 3 && !start.Wednesday) { toRemoveBySchedule.Add(p); } else if (currentDayOfWeek == 4 && !start.Thursday) { toRemoveBySchedule.Add(p); } else if (currentDayOfWeek == 5 && !start.Friday) { toRemoveBySchedule.Add(p); } else if (currentDayOfWeek == 6 && !start.Saturday) { toRemoveBySchedule.Add(p); } } try { var startMinute = start.Minute == 0 ? "00" : start.Minute.ToString(); var endMinute = end.Minute == 0 ? "00" : end.Minute.ToString(); var startTimeOfDay = DateTime.ParseExact(start.Hour + " " + startMinute, "H mm", CultureInfo.InvariantCulture).TimeOfDay; var endTimeOfDay = DateTime.ParseExact(end.Hour + " " + endMinute, "H mm", CultureInfo.InvariantCulture).TimeOfDay; if (currentTimeOfDay >= startTimeOfDay && currentTimeOfDay <= endTimeOfDay) { //ignored } else { toRemoveBySchedule.Add(p); } } catch (Exception ex) { Logger.Error("Could Not Parse Schedule Times For " + start.Name + " " + end.Name); Logger.Error(ex.Message); continue; } } foreach (var p in toRemoveBySchedule) { distinctList.Remove(p); } triggerResponse.Policies = distinctList; triggerResponse.CheckinTime = Convert.ToInt32(ServiceSetting.GetSettingValue(SettingStrings.CheckinInterval)); triggerResponse.ShutdownDelay = Convert.ToInt32(ServiceSetting.GetSettingValue(SettingStrings.ShutdownDelay)); return(triggerResponse); }