这是从用户生成的命令提示符运行时工作正常的命令:
PSEXEC \xxx.xxx.xxx.xxx -u xxxx -p xxxx -accepteula cmd /c "TYPE C:PyxislogPYXIS01.log|Find/i "%ID%"" >nul
但是,如果我尝试从系统调用的cmd提示符运行它,我会得到这个:
Couldn't access 10.219.149.65:
The handle is invalid.
Connecting to 10.219.149.65...
它必须以系统用户身份运行,因为它将通过以系统用户身份运行的远程软件工具进行部署。这是psexec的限制吗?是的,用户名和密码具有管理权限。
经过大量研究,阻止对系统用户的所有网络访问是一项 Windows 安全功能,其中包括以其他用户身份运行任务。我发现绕过这种情况的最佳方法是创建一个计划任务以从管理员帐户运行 psexec。
Psexec 通过添加 -s 参数强制使用系统用户帐户。
我们使用 psexec 在远程计算机中启动一些任务,并将其记录在数据库表中。当我们不使用 -s 参数时,用户显示为域\管理员,但如果您使用-s 参数显示为"系统"
对于无效的句柄消息,请检查以下内容:
https://superuser.com/questions/200938/psexec-the-handle-is-invalid
你试过使用 -h 标志吗?
来自 technet:-h 如果目标系统是 Vista 或更高版本,则使用帐户提升的令牌(如果可用)运行进程。
整页: https://technet.microsoft.com/en-us/sysinternals/psexec.aspx
它可能无关,但我实际上发现如果连接到机器 - 即机器睡着了,我会收到这个"句柄无效"错误。
这是我用来遵循的代码 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;
}
}
我的代码运行良好:
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() + "rn" + prc.StandardOutput.ReadToEnd()).Trim();
output = output.Substring(output.IndexOf(".comrnrn") + 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 Exploreriexplore.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.exe,pskill.exe和psservice.exe。