private void ServiceMain() { const string testFile = @"C:\tmp\test-it.ps1"; File.Delete(testFile); File.WriteAllText(testFile, testPowershellScript); var permissionManager = new DesktopPermissionManager(userName); var startupInfo = new NativeMethods.StartupInfo(); string lpApplicationName = @"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"; var cmdLine = new StringBuilder(1024); cmdLine.AppendFormat(@" -InputFormat None -NoLogo -NoProfile -NonInteractive -File {0}", testFile); permissionManager.AddDesktopPermission(); using (var jobObject = new JobObject("StartProcessServiceJobObject")) { jobObject.KillProcessesOnJobClose = true; while (!ct.IsCancellationRequested) { try { log.Debug("Executing command: '{0}'", cmdLine); // Now create the process as the user NativeMethods.ProcessInformation pi; var saProcessAttributes = new NativeMethods.SecurityAttributes(); var saThreadAttributes = new NativeMethods.SecurityAttributes(); var createProcessFlags = NativeMethods.CreateProcessFlags.CREATE_NO_WINDOW | NativeMethods.CreateProcessFlags.CREATE_UNICODE_ENVIRONMENT; IntPtr primaryToken = Utils.LogonAndGetPrimaryToken(userName, password); if (NativeMethods.CreateProcessAsUser(primaryToken, lpApplicationName, cmdLine, saProcessAttributes, saThreadAttributes, false, createProcessFlags, IntPtr.Zero, workingDir, startupInfo, out pi)) { log.Debug("created process: '{0}' pid: '{1}'", cmdLine.ToString(), pi.dwProcessId); jobObject.AddProcess(pi.hProcess); log.Debug("job object has '{0}' processes in it.", jobObject.GetJobProcesses().Count()); NativeMethods.CloseHandle(pi.hProcess); NativeMethods.CloseHandle(pi.hThread); } else { int err = Marshal.GetLastWin32Error(); log.Error("Error '{0}' creating process.", err); } } catch (Exception ex) { log.ErrorException("Exception creating process.", ex); } finally { Thread.Sleep(TimeSpan.FromSeconds(10)); } } } permissionManager.RemoveDesktopPermission(); }