背景
昨天遇到一個問題:本地電腦(Win7 x64)想要遠程啟動另一台電腦(Windows Server 2012 R2)上的一個程序(為*.exe程序),要求是:在不改變遠程電腦配置的前提下,被啟動的程序能彈出console界面,並有run as administrator的效果(類似於右擊某個程序->Run as administrator)
注意:當以Domain Admins group中某一域賬戶登錄某台電腦后,選擇某個程序->右擊->Run as administrator,其實是賦予了這個程序elevated privilege,這個程序的owner仍是此域賬戶,並不是local admin。具體的解釋請見下面的鏈接:
https://msdn.microsoft.com/en-us/library/windows/hardware/dn653293(v=vs.85).aspx
In Windows® XP, Windows Server® 2003, and earlier versions of the Windows operating system, all services run in the same session as the first user who logs on to the console. This session is called Session 0. Running services and user applications together in Session 0 poses a security risk because services run at elevated privilege and therefore are targets for malicious agents who are looking for a way to elevate their own privilege level.
In Windows Vista®, Windows Server 2008, and later versions of Windows, the operating system mitigates this security risk by isolating services in Session 0 and making Session 0 noninteractive. Only system processes and services run in Session 0. The first user logs on to Session 1, and subsequent users log on to subsequent sessions. This means that services never run in the same session as users’ applications and are therefore protected from attacks that originate in application code.
解決方案一
Telnet -- 只能本地回顯,達不到要求
解決方案二
PsExec
具體用法請見https://technet.microsoft.com/en-us/sysinternals/psexec.aspx
PsExec.exe -i -u domainname\username -p Password \\IPAddress c:\*.exe ----被啟動的程序只能以進程的形式顯示在task manager里,不顯示console界面
PsExec.exe -h -i -u domainname\username -p Password \\IPAddress c:\*.exe ----即使加上了-h,被啟動的程序仍只能以進程的形式顯示在task manager里,不顯示console界面
解決方案三
利用WMI Win32_Process class
如下code所示,有和Psexec相同的效果:被啟動的程序只能以進程的形式顯示在task manager里,不顯示console界面
ConnectionOptions theConnection = new ConnectionOptions(); theConnection.Username = "domainname\\username"; theConnection.Password = "Password"; theConnection.Impersonation = ImpersonationLevel.Impersonate; theConnection.EnablePrivileges = true; ManagementScope theScope = new ManagementScope("\\\\ip address\\root\\cimv2", theConnection); ManagementClass theClass = new ManagementClass(theScope, new ManagementPath("Win32_Process"), new ObjectGetOptions()); ManagementBaseObject inParams = theClass.GetMethodParameters("Create"); // Fill in input parameter values inParams["CommandLine"] = "c:\\*.exe"; ManagementBaseObject outParams = theClass.InvokeMethod("Create", inParams, null);
解決方案四
創建schedule task,通過schedule task來啟動程序(在Windows Server 2012 R2上實驗通過)
schtasks /create /s ipAddress -u domainname\username -p Password /sc ONCE /st 01:00 /tn MyTaskName /tr c:\*.exe /rl HIGHEST
schtasks /run /s ipAddress -u domainname\username -p Password /tn MyTaskName
schtasks /query /s ipAddress -u domainname\username -p Password /tn MyTaskName
如下code所示,先查詢遠程主機上是否已經存在這個schedule task,若不存在則創建,然后立即執行這個schedule task
private void CreateAndRunSchTask(string ip) { try { System.Diagnostics.Process p1 = new System.Diagnostics.Process(); p1.StartInfo.FileName = @"schtasks.exe"; p1.StartInfo.Arguments = string.Format(@" /query /s {0} -u domainname\username -p Password /tn MyTaskName", ip); p1.StartInfo.UseShellExecute = false; p1.StartInfo.RedirectStandardError = true; p1.StartInfo.RedirectStandardOutput = true; p1.StartInfo.StandardOutputEncoding = Encoding.UTF8; p1.StartInfo.StandardErrorEncoding = Encoding.UTF8; p1.StartInfo.CreateNoWindow = true; p1.Start(); string err = p1.StandardError.ReadToEnd(); string sop = p1.StandardOutput.ReadToEnd(); // If there is no schedule task created for ServiceCommandService, create one if (!string.IsNullOrEmpty(err) && string.IsNullOrEmpty(sop)) { p1.StartInfo.Arguments = string.Format(@" /create /s {0} -u domainname\username -p Password /sc ONCE /st 01:00 /tn MyTaskName /tr c:\*.exe /rl HIGHEST", ip); p1.Start(); err = p1.StandardError.ReadToEnd(); sop = p1.StandardOutput.ReadToEnd(); if (!sop.Contains("SUCCESS")) { throw new Exception(string.Format("Create schedule task failed on {0}", ip)); } } p1.StartInfo.Arguments = string.Format(@" /run /s {0} -u domainname\username -p Password /tn MyTaskName", ip); p1.Start(); err = p1.StandardError.ReadToEnd(); sop = p1.StandardOutput.ReadToEnd(); if (!string.IsNullOrEmpty(err) || !sop.Contains("SUCCESS")) { throw new Exception(string.Format("Run schedule task failed on {0}", ip)); } p1.WaitForExit(); p1.Close(); } catch (Exception e) { throw e; } }
P.S.
1. schtasks與at的區別
- schtasks applies To: Windows 8, Windows Server 2008, Windows Server 2012
- Schtasks replaces At.exe, a tool included in previous versions of Windows. Although At.exe is still included in the Windows Server 2003 family,schtasks is the recommended command-line task scheduling tool.
2. schtasks與WMI的Win32_ScheduledJob的區別
- SchTasks.exe performs the same operations as Scheduled Tasks in Control Panel. You can use these tools together and interchangeably.
- The Win32_ScheduledJob WMI class represents a job created with the AT command. The Win32_ScheduledJob class does not represent a job created with the Scheduled Task Wizard from the Control Panel. You cannot change a task created by WMI in the Scheduled Tasks UI. For more information, see the Remarks section.
本文基於署名-非商業性使用 3.0許可協議發布,歡迎轉載,演繹,但是必須保留本文的署名趙娟(包含鏈接http://www.cnblogs.com/jenneyblog/),且不得用於商業目的。如您有任何疑問或者授權方面的協商,請與我聯系。