Run mstsc.exe with specified username and password
Asked Answered
H

7

36

I realize that in Windows 7, it is not possible to save different credentials for the same host, but I need some workaround.

Can I provide the username and password manually in the code? Store them in a temp .rdp file?

Hive answered 2/7, 2012 at 15:36 Comment(1)
Basically the idea is to execute CMDKEY.EXE to create your temporary credentials in the stored credentials repository, and then execute MSTSC.EXE. MSTSC should find the credentials and use them. You can execute these programs from within C# using Process.Start; you don't need Powershell.Bowes
H
46
Process rdcProcess = new Process();
rdcProcess.StartInfo.FileName = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\system32\cmdkey.exe");
rdcProcess.StartInfo.Arguments = "/generic:TERMSRV/192.168.0.217 /user:" + "username" +  " /pass:" + "password";
rdcProcess.Start();

rdcProcess.StartInfo.FileName = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\system32\mstsc.exe");
rdcProcess.StartInfo.Arguments = "/v " + "192.168.0.217"; // ip or name of computer to connect
rdcProcess.Start();

The above code initiates a connection with .217 and I am not being prompted to provide a password. Thanks for help.

Hive answered 2/7, 2012 at 19:41 Comment(6)
If you don't want to keep stored credentials in repository, after this code you can call cmdkey.exe again with arguments /delete:TERMSRV/192.168.0.217Hurlow
I am still being prompted for password. My machine is using vista businessHydromechanics
I'm still being promped for password. My machine is using Windows 8.Undercurrent
It prompted me until I specified the domain -- /user:MyDomain\MyUserOmegaomelet
works. it would be also very cool to have a means to determine once the mstsc has fully logged into another systemFishworm
The Process class inherits from the Component class that implements IDisposable, so you're supposed to dispose the process instances after starting them.Terrain
A
38

If you want to use powershell you could add the credentials using

cmdkey /generic:DOMAIN/"computername or IP" /user:"username" /pass:"password"

Then call RDP connection using

Start-Process -FilePath "$env:windir\system32\mstsc.exe" -ArgumentList "/v:computer name/IP" -Wait

If you want to delete the credentials run

cmdkey /delete:DOMAIN/"Computer name or IP"

Remember to remove ""

Aslam answered 3/8, 2012 at 11:48 Comment(2)
I like this! I got it to work on Windows Server 2008 R2.Exception
See https://mcmap.net/q/427241/-how-to-ignore-the-certificate-warning-on-remote-desktop-connection for info on how to disable the certificate warning.Rausch
S
9

This is an updated version from Krzysiek's post.

var rdcProcess = new Process
    {
        StartInfo =
            {
                FileName = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\system32\cmdkey.exe"),
                Arguments = String.Format(@"/generic:TERMSRV/{0} /user:{1} /pass:{2}", 
                            fp.ipAddress,
                            (String.IsNullOrEmpty(fp.accountDomain)) ? fp.accountUserName : fp.accountDomain + "\\" + fp.accountUserName,
                            fp.accountPassword),
                            WindowStyle = ProcessWindowStyle.Hidden                                
            }
    };
rdcProcess.Start();
rdcProcess.StartInfo.FileName = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\system32\mstsc.exe");
rdcProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
rdcProcess.StartInfo.Arguments = String.Format("/f /v {0}", fp.ipAddress); // ip or name of computer to connect
rdcProcess.Start();
Skidmore answered 16/12, 2013 at 19:33 Comment(2)
It almost worked, but I still need to enter passwordUndercurrent
@MarekBar Your domain might have a GPO forbidding the storage of passwords for Remote Desktop connections.Protolithic
A
1

While trying to figure out how to allow users into our network, without giving them the keys to the castle, I enabled Remote Desktop Access for a few members of my team. Thinking more about this, I quickly remembered a project several years ago while working for the Department of Defense. That project required us to "lock down" access to only necessary personnel and limited access to the programs on the servers. After spending some time on Microsoft's KnowledgeBase, we realized that we could create desktop "shortcuts" for those employees that made the RDP connection, logged them in and limited their access to one specific application on that server.

Alundum answered 9/7, 2012 at 9:17 Comment(1)
Is that how Snowden got the info :) (J/K)Tenne
C
1
@echo off

cmdkey /generic:TERMSRV/"*IP or Server Name*" /user:%username%

start mstsc /v:*IP or Server Name*

cmdkey /delete:TERMSRV/"*IP or Server Name*"

quit
Carnahan answered 12/4, 2017 at 14:21 Comment(1)
While this code snippet may be the solution, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.Presocratic
E
1

The accepted answer solves the problem, but has the side effect of leaving the credentials in the users credential store. I wound up creating an IDisposable so I can use the credentials in a using statement.

using (new RDPCredentials(Host, UserPrincipalName, Password))
{
    /*Do the RDP work here*/
}

internal class RDPCredentials : IDisposable
{
    private string Host { get; }

    public RDPCredentials(string Host, string UserName, string Password)
    {
        var cmdkey = new Process
        {
            StartInfo =
            {
                FileName = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\system32\cmdkey.exe"),
                Arguments = $@"/list",
                WindowStyle = ProcessWindowStyle.Hidden,
                UseShellExecute = false,
                RedirectStandardOutput = true
            }
        };
        cmdkey.Start();
        cmdkey.WaitForExit();
        if (!cmdkey.StandardOutput.ReadToEnd().Contains($@"TERMSRV/{Host}"))
        {
            this.Host = Host;
            cmdkey = new Process
            {
                StartInfo =
            {
                FileName = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\system32\cmdkey.exe"),
                Arguments = $@"/generic:TERMSRV/{Host} /user:{UserName} /pass:{Password}",
                WindowStyle = ProcessWindowStyle.Hidden
            }
            };
            cmdkey.Start();
        }
    }

    public void Dispose()
    {
        if (Host != null)
        {
            var cmdkey = new Process
            {
                StartInfo =
            {
                FileName = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\system32\cmdkey.exe"),
                Arguments = $@"/delete:TERMSRV/{Host}",
                WindowStyle = ProcessWindowStyle.Hidden
            }
            };
            cmdkey.Start();
        }
    }
}
Ensconce answered 18/8, 2017 at 20:17 Comment(0)
T
1

most of the answers are incorrect, it still request password and this because execute different processes on the same process instance.

using command line works perfectly:

        string command = "/c cmdkey.exe /generic:" + ip 
        + " /user:" + user + " /pass:" + password + " & mstsc.exe /v " + ip;

        ProcessStartInfo info = new ProcessStartInfo("cmd.exe", command);
        info.WindowStyle = ProcessWindowStyle.Hidden;
        info.CreateNoWindow = true;

        Process proc = new Process();
        proc.StartInfo = info;
        proc.Start();
Taiga answered 30/9, 2019 at 7:19 Comment(2)
apparently (according to a non-answer posted as an answer) this is the same as the accepted answer. (I don't know).Caddish
almost, this is used only one process and execute 2 commands.Taiga

© 2022 - 2024 — McMap. All rights reserved.