public void ConfigureService(RunnerSettings settings, CommandSettings command) { Trace.Entering(); if (!_windowsServiceHelper.IsRunningInElevatedMode()) { Trace.Error("Needs Administrator privileges for configure runner as windows service."); throw new SecurityException("Needs Administrator privileges for configuring runner as windows service."); } // We use NetworkService as default account for actions runner NTAccount defaultServiceAccount = _windowsServiceHelper.GetDefaultServiceAccount(); string logonAccount = command.GetWindowsLogonAccount(defaultValue: defaultServiceAccount.ToString(), descriptionMsg: "User account to use for the service"); string domainName; string userName; GetAccountSegments(logonAccount, out domainName, out userName); if ((string.IsNullOrEmpty(domainName) || domainName.Equals(".", StringComparison.CurrentCultureIgnoreCase)) && !logonAccount.Contains('@')) { logonAccount = String.Format("{0}\\{1}", Environment.MachineName, userName); domainName = Environment.MachineName; } Trace.Info("LogonAccount after transforming: {0}, user: {1}, domain: {2}", logonAccount, userName, domainName); string logonPassword = string.Empty; if (!defaultServiceAccount.Equals(new NTAccount(logonAccount)) && !NativeWindowsServiceHelper.IsWellKnownIdentity(logonAccount)) { while (true) { logonPassword = command.GetWindowsLogonPassword(logonAccount); if (_windowsServiceHelper.IsValidCredential(domainName, userName, logonPassword)) { Trace.Info("Credential validation succeed"); break; } else { if (!command.Unattended) { Trace.Info("Invalid credential entered"); _term.WriteLine("Invalid windows credentials entered. Try again or ctrl-c to quit"); } else { throw new SecurityException("Invalid windows credentials entered. Try again or ctrl-c to quit"); } } } } string serviceName; string serviceDisplayName; CalculateServiceName(settings, ServiceNamePattern, ServiceDisplayNamePattern, out serviceName, out serviceDisplayName); if (_windowsServiceHelper.IsServiceExists(serviceName)) { _term.WriteLine($"The service already exists: {serviceName}, it will be replaced"); _windowsServiceHelper.UninstallService(serviceName); } Trace.Info("Verifying if the account has LogonAsService permission"); if (_windowsServiceHelper.IsUserHasLogonAsServicePrivilege(domainName, userName)) { Trace.Info($"Account: {logonAccount} already has Logon As Service Privilege."); } else { if (!_windowsServiceHelper.GrantUserLogonAsServicePrivilege(domainName, userName)) { throw new InvalidOperationException($"Cannot grant LogonAsService permission to the user {logonAccount}"); } } // grant permission for runner root folder and work folder Trace.Info("Create local group and grant folder permission to service logon account."); string runnerRoot = HostContext.GetDirectory(WellKnownDirectory.Root); string workFolder = HostContext.GetDirectory(WellKnownDirectory.Work); Directory.CreateDirectory(workFolder); _windowsServiceHelper.GrantDirectoryPermissionForAccount(logonAccount, new[] { runnerRoot, workFolder }); _term.WriteLine($"Granting file permissions to '{logonAccount}'."); // install service. _windowsServiceHelper.InstallService(serviceName, serviceDisplayName, logonAccount, logonPassword); // create .service file with service name. SaveServiceSettings(serviceName); Trace.Info("Configuration was successful, trying to start the service"); _windowsServiceHelper.StartService(serviceName); }