How to persist credentials in a remote Powershell session?

Solution 1:

Due to how Windows handles authentication it is not possible to use CMDKEY to set credentials via a remote PowerShell session, it has to be done interactively when using CMDKEY.

To quote Don Jones from a thread looking for an answer similar to yours:

That's a limitation of the Cmdkey command – not really a PowerShell thing. But it's related to the way Remotig handles credentials. The remote session doesn't actually get a credential, it gets a delegated ticket, so there's no token to actually save. That's all by design, and not something you can reconfigure.

Solution 2:

You can use Sysinternal's PsExec.exe if you don't want to use the Scheduled Task. Normally, when you start a PowerShell session, it runs in the services process (you can confirm this by running query session command on the remote computer) instead of the local user which fails cmdkey.

To overcome this, we need to run cmdkey.exe in the local user's process which can be done by using PsExec.exe's -i flag which

Run the program so that it interacts with the desktop of the specified session on the remote system. If no session is specified the process runs in the console session.

Now, the challenge is to get the session id of the local user on the remote machine. I achieved this by running query session command which gives a list of sessions active on the machine. One of the possible solutions is -

$processId = Invoke-Command $session -ScriptBlock  {
param($user)
    $sessions = query session $user;
    return $sessions[1].split(" ", [System.StringSplitOptions]::RemoveEmptyEntries)[2];

} -ArgumentList ($user)

Here $user contains the username of the local user on the remote computer.

Once you get the session id, you can simply execute

PsExec \\<computer_name> -u <local_user_name> -p <password> -h -i $processId cmdkey.exe /generic:testtt /user:userr /pass:pass

Note:

  1. There can be better ways to get the session id of a user on the remote machine.
  2. Right now, while running PsExec, I am again making a connection with the remote system which can be avoided (I haven't tested).
  3. The user running the command should have admin access on the remote machine.