Give commands to multiple RDP and wait for result - c#

I have a repetitive task at the end of the month to give commands to multiple Remote Desktop Connections (Win7, Win Server 2008, Win server 2012, Win 8 ...) and i need to open all of them one by one to do this task. I want somekind of tool that would log on each and every one of them and give commands.
Here is what i tried :
public Form1()
{
InitializeComponent();
rdp.Server = "1.2.3.4";
rdp.UserName = "Rmlabuser2";
IMsTscNonScriptable secured = (IMsTscNonScriptable)rdp.GetOcx();
secured.ClearTextPassword = "Rmlabuser2";
rdp.Connect();
// open cmd.exe and give commands like VER and return output into a message text box
// rdp.SecuredSettings.StartProgram = #"c:\windows\System32\cmd.exe";
}
Full code :
http://www.codeproject.com/Articles/43705/Remote-Desktop-using-C-NET
Any ideeas?
Thanks.

You can use psexec to run commands on remote computer.
If you need to run commands within active session, you can create a scheduled task on that computer that will do the needed stuff. Scheduled tasks can be configured to run under currently logged-in session or from system/predefined account.
There are a number of C# libraries that can work with windows scheduled tasks. For example http://taskscheduler.codeplex.com/

Related

C#: Programmatically Detect Windows Server Has Booted

I'm working on an automation process in C# that is going to remotely reboot a Windows (2008/2012/2016) server and I need to wait until that server is back online before proceeding.
I know 'back online' can be ambiguous, so for my requirements, I need the server to be back at the Ctrl-Alt-Del screen.
The reason for this is to have the server in a consistent state before proceeding. In my experience, there are several factors that could prevent the server from reaching this screen, such as installing windows updates that gets stuck in a reboot cycle or getting stuck at 'Waiting for Local Session Manager' etc.
I've spent a few days looking in to this to no avail:
The server obviously starts responding to ping requests before it is available
System Boot Time occurs before the Server reaches the desired state
Any events indicating the system has booted are logged before the desired state
I can't simply poll for an essential service - when Windows is applying computer updates prior to logon these services can be already started. Additionally, sometimes a server will reboot itself whilst installing updates at this stage which could result in false positives.
Polling CPU activity could also produce false positives or introduce delays
Is there anyway to detect a Windows server has finished booting and is available for an interactive logon?
It sounds like you've covered most of the possible ways I know of. Which makes me revert to brute force ideas. I am curious what you're doing where you can't install a windows service on the box (or is that just not very viable because of the number)
First would just be trying to remote login or whatever, and having some way to test if it fails or not, wait 1 minute, try again. But seems like that might cause side-issues for you somehow?
My idea of a brute force method that wouldn't affect state:
Ping every 1-5seconds
Once it starts responding
wait 5 or 10 or even 15 minutes, whilst still pinging it
If pings fail reset that timer (windows updates restart case)
Then be pretty confident you're at the right state.
With potentially thousands of servers, I can't imagine 15 minutes each would be a big deal, especially if it is consistent enough to be able to run in larger batches
So I've been able to accomplish this by using a hacky method put seems to work in my test environment.
Note that the el.Current.Name property will equate to the Ctrl-Alt-Del text, so on 2008R2 this is 'Press CTRL-ALT-DEL to log on' and 'Press CTRL-ALT-DEL to sign in.' on 2012R2
I've built a C# console application that uses UI Automation:
using System;
using System.Windows.Automation;
namespace WorkstationLocked
{
class Program
{
static void Main()
{
AutomationElement el = AutomationUI.FindElementFromAutomationID("LockedMessage");
if (el !=null)
{
Console.WriteLine(el.Current.Name);
}
}
}
class AutomationUI
{
public static AutomationElement FindElementFromAutomationID(string automationID)
{
string className = "AUTHUI.DLL: LogonUI Logon Window";
PropertyCondition condition = new PropertyCondition(AutomationElement.ClassNameProperty, className);
AutomationElement logonui = AutomationElement.RootElement.FindFirst(TreeScope.Children, condition);
if (logonui != null)
{
condition = new PropertyCondition(AutomationElement.AutomationIdProperty, automationID);
return logonui.FindFirst(TreeScope.Descendants, condition);
}
else
{
return null;
}
}
}
}
I can then execute this console application via PsExec, however, because this needs to be launched in the winlogon desktop, which can only be done by running under the local system, PsExec is invoked twice. For example:
psexec.exe \\ServerA -s -d C:\PsTools\PsExec.exe -accepteula -d -x C:\Utils\WorkstationLocked.exe
This is very much a work in progress right now as I can't get the output of the command to pass through to the calling process so I may just look to populate a registry value or write to a file that can be subsequently interrogated.

Automate the .aspx through windows task scheduler in server

I have an .aspx in that it will send email to the employees. I want this page should be automatically send to employees everyday. So i have published in IIS and created an windows task scheduler in the server "C:\Program Files\Internet Explorer\IEXPLORE.EXE""http://syspexsap03/AUTOEMAIL/Default.aspx" It works fine "if the operations runs successfully" i receive email after that still IE is working in the background apps in server.so immediately it cannot run the next task..It works locally.In case of server when i deploy no use. I have used this codes to kill the process:
Process[] AllProcesses = Process.GetProcesses();
foreach (var process in AllProcesses)
{
if (process.MainWindowTitle != "")
{
string s = process.ProcessName.ToLower();
if (s == "iexplore" || s == "iexplorer")
process.Kill();
}
}
and tried to do with the process id no use every time it generate new Pid:
Process p = Process.GetProcessById(15844);
p.Kill();
Process p1 = Process.GetProcessById(13380);
p1.Kill();
Process p2 = Process.GetProcessById(196);
p2.Kill();
How to schedule the aspx page in the windows task scheduler and kill the IE at the same time to run the next task ? Should run everyday on a specified time.. Please guide me..
In order to make an activity which runs at a particular schedule you don't need an aspx page or web application and publish in IIS for it.
It should be a console application where the .exe file can be scheduled in the window task scheduler at a particular time.Task Scheduler runs ordinary EXEs.
Also if you are sending email to employees which belong to same domain then there is no limitation on mails per day.
But if the email are not of the same domain then there is an limitation. Link below in order to check the limitation
http://group-mail.com/sending-email/email-send-limits-and-options/

Process.Start won't work

I am trying to launch a process from a web page's back-end code/app pool. This process will launch an App that i built myself.
For some reason, the process only works / runs when i start it from VS2013... it never works when i launch it from IIS(7.5) itself.
I am on a Windows 7 machine (both IIS host, and App location), and I've setup my web site to only be accessible via internal network.
Here's the code, followed by the config / attempts to fix the issue:
protected void btn_DoIt_Click(object sender, EventArgs e)
{
string file_text = this.txt_Urls.Text;
if (!String.IsNullOrWhiteSpace(file_text))
File.WriteAllText(ConfigurationManager.AppSettings["filePath"], file_text);
ProcessStartInfo inf = new ProcessStartInfo();
SecureString ss = GetSecureString("SomePassword");
inf.FileName = #"........\bin\Release\SomeExecutable.exe";
inf.Arguments = ConfigurationManager.AppSettings["filePath"];
inf.UserName = "SomeUserName";
inf.Password = ss;
inf.UseShellExecute = false;
//launch desktop app, but don't close it in case we want to see the results!
try
{
Process.Start(inf);
}
catch(Exception ex)
{
this.txt_Urls.Text = ex.Message;
}
this.txt_Urls.Enabled = false;
this.btn_DoIt.Enabled = false;
this.txt_Urls.Text = "Entries received and process started. Check local machine for status update, or use refresh below.";
}
Here are the things I've tried to resolve the issue:
Made sure the executing assembly was built with AnyCPU instead of
x86
Ensured that the AppPool that runs the app, also runs under the same account (SomeUsername) as the ProcessStartInfo specified.
Ensured that the specific user account has full access to the executable's folder.
Ensured that IIS_USR has full access to the executable's folder.
Restarted both the app pool and IIS itself many times over implementing these fixes
I am now at a loss as to why this simply will not launch the app... when i first looked into the event log, i saw that the app would die immediately with code 1000:KERNELBASE.dll, which got me on the AnyCPU config instead of X86 fix... that fixed the event log entries but the app still doesn't start (nothing comes up in task manager), and i get no errors in the event log...
if someone could help me fix this problem i would really appreciate it. This would allow me to perform specific tasks on my main computer from any device on my network (phone, tablet, laptop, etc etc) without having to be in front of my main PC...
UPDATE
The comment to my OP, and ultimate answer from #Bradley Uffner actually nailed the problem on the head: My "app" is actually a desktop application with a UI, and in order to run that application, IIS would need to be able to get access to the desktop and the UI, just like if it were a person sitting down in front of the PC. This of course is not the case since IIS is running only as a service account and it makes sense that it shouldn't be launching UI programs in the background. Also see his answer for one way of getting around this.
Your best bet might be to try writing this as 2 parts. A web site that posts commands to a text file (or database, or some other persistent storage), and a desktop application that periodically polls that file (database, etc) for changes and executes those commands. You could write out the entire command line, including exe path command arguments, and switches.
This is the only way I can really think of to allow a service application like IIS to execute applications that require a desktop context with a logged in user.
You should assign a technical user with enough high priviliges to the running application pool. By default the application pool is running with ApplicationPoolIdentity identy which has a very low priviliges.

How to run RDC Windows application

I tried lot in running RDC windows application on there I'm trying to capture details.
Like ---- > connecting Myremotedesktop ----> Run the windows application in rdc and enter values to get details (eg if I enter rollnumber address details will come) ----> capture details data and store it on my local desktop.
Is there any way to automate this process using c# code?
I'm able to connect remote desktop.
I tried the UIAutomation and the below code working fine for local desktop:
System.Threading.Thread.Sleep(500);
AutomationElement rootElement = AutomationElement.RootElement;
Condition appCondition = new PropertyCondition(AutomationElement.NameProperty, "Untitled - Notepad");
Condition documentCondition = new PropertyCondition(AutomationElement.LocalizedControlTypeProperty, "document");
AutomationElement documentElement = rootElement.FindFirst(TreeScope.Subtree, documentCondition);
documentElement.SetFocus();
SendKeys.SendWait("This is a test of the emergency broadcast system.")
How to do this same thing on remotedesktop?
Due to your requirement of not being able to put any software on the server side of the RDP connection remote control like you want to do is impossible unless the buttons you want to click are int he same position every time and you hard code the X,Y values of where to move the mouse in your automation script.
If you could run something on the RDP server you could take your automation code and write a listener program that would talk to your client over Virtual Channels which would allow you to pass messages to your listener over the RDP connection and the listener could perform the automation tasks server side.
Can you force the client side to be Windows 8? I believe that UI Automation requests get "tunneled" through the RDC connection on Windows 8.

c# Open IE From Scheduled Task

I have a c# console application that I want to run from task scheduler that has 2 main functions: 1) Closes all Internet Explorer processes; and 2) Restarts Internet Explorer and loads the appropriate website.
The console app does exactly what it is supposed to do if run from the command line, but fails if executed from Task Scheduler.
The app is designed to run on the client computer the only function of which is to load a single website and broadcast the website to our internal TV Channel 195. We have connection issues with our ISP and while the connection issue is usually temporary, Internet explorer needs to be restarted to re-show the website.
I want to set it up to run multiple times each day to eliminate any possible connection issues between the web server and the client.
private static void StartExplorer()
{
Process _process;
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = "iexplore.exe",
Arguments = "-noframemerging -private -k \"http://tv.TheelmAtClark.Com\""
};
try{
_process = Process.Start(psi);
}
catch(Exception Ex)
{
Console.WriteLine(Ex.ToString());
}
}
Is it possible to run the app using task scheduler?
I would recommend that you look at alternative approaches, if possible.
A Firefox plugin like Reload Every is designed to do just this. I use this in our to project to a big screen TV.
However, if you are keen on doing this via Internet explorer, again there are two approaches
1) Something similar to the Firefox plugin I mentioned above - Autorefresher for IE
2) If you insist on having a task scheduler, as you mentioned above, here is how I think you can do it-
To kill all Internet Explorer instances, use PSKill. Invoke it via Process.Start with arguments to kill Internet Explorer.
To launch a new instance, try invoking Process.Start with UseShellExecute=true.

Categories