【问题标题】:PSEXEC - "The Handle is invalid" When running the command as System UserPSEXEC - “句柄无效”以系统用户身份运行命令时
【发布时间】:2012-12-01 19:59:07
【问题描述】:

如果从用户生成的命令提示符运行,这是可以正常工作的命令:

PSEXEC \\xxx.xxx.xxx.xxx -u xxxx -p xxxx -accepteula cmd /c "TYPE C:\Pyxislog\PYXIS01.log|Find/i "%ID%"" >nul

但是,如果我尝试从系统调用的 cmd 提示符运行它,我会得到:

Couldn't access 10.219.149.65:
The handle is invalid.
Connecting to 10.219.149.65...

它必须以系统用户身份运行,因为它将通过以系统用户身份运行的远程软件工具进行部署。这是 psexec 的限制吗?是的,用户名和密码具有管理权限。

【问题讨论】:

    标签: command-line batch-file psexec command-line-tool


    【解决方案1】:

    经过大量研究,它是一个 Windows 安全功能,可以阻止系统用户的所有网络访问,包括以其他用户身份运行任务。我发现规避此问题的最佳方法是创建一个计划任务以从管理员帐户运行 psexec。

    【讨论】:

      【解决方案2】:

      Psexec 通过添加 -s 参数强制使用系统用户帐户。

      我们使用 psexec 在远程计算机中启动一些任务,并将其记录在数据库表中。 当我们不使用 -s 参数时,用户显示为域\管理员,但如果您使用 -s 参数它显示为“系统”

      对于无效的句柄消息,请检查:

      https://superuser.com/questions/200938/psexec-the-handle-is-invalid

      【讨论】:

      • 感谢您的意见,但您可能误解了我的意思。如果我运行完整的批处理文件,该行可以正常工作,因为我将批处理文件作为用户帐户运行。但是,如果我尝试将包部署到它手动运行的同一台机器上,它会失败,因为部署运行的批处理文件作为 SYSTEM 用户。我不需要 PSEXEC 来访问远程计算机上的系统帐户,我需要它来访问管理员帐户。
      • 您是否在 psexec 登录中使用相同的用户帐户?我猜你是
      • 是的,例如,我将上面显示的 PSEXEC 命令(填充了 xxxx)复制粘贴到我通过开始 > 运行 > CMD 打开的 CMD 窗口中。然后我以 SYSTEM 用户身份调用另一个 CMD 窗口,方法是执行 psexec -i -s cmd.exe,然后粘贴与我在第一个 CMD 窗口中执行的完全相同的命令,它会重新创建此错误。
      【解决方案3】:

      您是否尝试过使用 -h 标志?

      来自 technet:-h 如果目标系统是 Vista 或更高版本,则使用帐户的提升令牌(如果可用)运行进程。

      整页:https://technet.microsoft.com/en-us/sysinternals/psexec.aspx

      【讨论】:

      • 此进程在 NT Authority\SYSTEM 帐户下运行,而不是以用户身份运行。因此它没有可使用的海拔令牌。
      【解决方案4】:

      这可能是无关的,但我实际上发现如果连接到机器时出现“句柄无效”错误 - 即机器睡着了。

      【讨论】:

        【解决方案5】:

        这是我用来按照 IT 人员的说明安排任务以管理员身份运行并避免“句柄无效”问题的代码。

                //Schedule a task that will run the script
                using (TaskService ts = new TaskService())
                {
                    TaskDefinition td = ts.NewTask();
                    td.RegistrationInfo.Description = "Runs script as admin user";
                    td.Triggers.Add(new TimeTrigger(DateTime.Now.AddMinutes(2)));
                    td.Actions.Add(new ExecAction(@"C:\...\script.exe"));
                    try
                    {
                        ts.RootFolder.RegisterTaskDefinition(@"Script", td, TaskCreation.CreateOrUpdate, "username", "password", logonType: TaskLogonType.Password);
                    }
                    catch (UnauthorizedAccessException e)
                    {
                        Console.WriteLine("Could not register task in task scheduler.");
                        Console.WriteLine(e.ToString());
                        return;
                    }
                }
        

        【讨论】:

          【解决方案6】:

          我的代码完美运行:

          public static void RunTask(string[] task, string username, string password)
          {
              System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(task[1] + ".exe");
              psi.RedirectStandardOutput = true;
              psi.RedirectStandardError = true;
              psi.CreateNoWindow = true;
              psi.UseShellExecute = false;
              string args = String.Format(@"-u {1} -p {2} -accepteula \\{0} " + (task[1] == "psexec" ? "-d -s -i 2 {3}" : "{3}"), task[0], username, password, task[1] == "psservice" ? task[2].TrimStart('"').Insert(task[2].IndexOf(' '), "\"") : task[2]);
              psi.Arguments = args;
          
              System.Diagnostics.Process prc = System.Diagnostics.Process.Start(psi);
              string output = (prc.StandardError.ReadToEnd() + "\r\n" + prc.StandardOutput.ReadToEnd()).Trim();
              output = output.Substring(output.IndexOf(".com\r\n\r\n") + 8);
          
              prc.WaitForExit();
          
              if (!(output.Contains("started on") || output.Contains("killed on") || output.Contains("SERVICE_NAME"))) throw new Exception(output);
          }
          

          示例调用:

              RunTask(new string[] { "MACHINE", "psexec", @"""C:\Program Files (x86)\Internet Explorer\iexplore.exe""" }, "USERNAME", "PASSWORD");
              RunTask(new string[] { "MACHINE", "pskill", @"""iexplore.exe""" }, "USERNAME", "PASSWORD");
              RunTask(new string[] { "MACHINE", "psservice", @"""start SOMESERVICE""" }, "USERNAME", "PASSWORD");
              RunTask(new string[] { "MACHINE", "psservice", @"""stop SOMESERVICE""" }, "USERNAME", "PASSWORD");
          
          • 确保您的程序旁边有 psexec.exepskill.exepsservice.exe

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-07-12
            • 1970-01-01
            • 2017-06-11
            • 2015-04-16
            • 1970-01-01
            • 1970-01-01
            • 2022-01-07
            相关资源
            最近更新 更多