Skip to content

How do I use user data to add a new user with RDP access to my Amazon EC2 instance?

10 minute read
0

I want to add another user that can connect to my Amazon Elastic Compute Cloud (Amazon EC2) Windows instance with Remote Desktop Protocol (RDP).

Short description

To create a new local user with RDP permissions that can connect to your EC2 instance, use PowerShell commands in the instance's User data field. If you launch a new instance, then the user data automatically runs during the launch. To configure user data on an existing instance, you must stop and start the instance. For more information, see User data execution.

Important: Don't hardcode passwords into the user data for production instances. If you hardcode passwords, then they're visible in plaintext in the Amazon EC2 console and to anyone with ec2:DescribeInstanceAttributes permissions. Instead, it's a best practice to use AWS Secrets Manager or Parameter Store, a capability of AWS Systems Manager, to store passwords. For pricing details, see AWS Secrets Manager pricing and AWS Systems Manager pricing. Only hardcode passwords for instances in test environments.

Resolution

(Existing instances only) Configure your instance for a stop and start

Note: When you stop and start an instance, the instance's public IP address changes. It's a best practice to use an Elastic IP address to route external traffic to your instance instead of a public IP address. If you use Amazon Route 53, then you might need to update the Route 53 DNS records when the public IP address changes. A stop and start is different from an instance reboot. For more information, see How EC2 instance stop and start works.

Before you stop and start your instance, take the following actions:

Use Secrets Manager or Parameter Store to manage new users

Secrets Manager provides automatic rotation and enhanced security features. It's a best practice to use Secrets Manager to manage passwords for production instances. Or, use Parameter Store to store passwords.

Configure Secrets Manager or Parameter Store

Complete the following steps:

  1. To use Secrets Manager, create a secret and configure the following settings:
    For Secret type, choose Other type of secret.
    Under Key/value pairs, enter password for Key and your user's password for Value.
    For Secret name, enter ec2/windows/rdp-user-password.
    -or-
    To use Parameter Store, create a parameter and configure the following settings:
    For Name, enter /ec2/windows/rdp-user-password.
    For Type, select SecureString.
    For Value, enter your secure password.
  2. For Secrets Manager, create the following AWS Identity and Access Management (IAM) policy:
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "secretsmanager:GetSecretValue"
          ],
          "Resource": "arn:aws:secretsmanager:REGION:ACCOUNT-ID:secret:ec2/windows/rdp-user-password-*"
        }
      ]
    }
    
    Note: Replace REGION with your AWS Region and ACCOUNT-ID with your AWS account ID. If you encrypted your secret with a customer managed AWS Key Management Service (AWS KMS) key, then add kms:Decrypt permissions.
    For Parameter Store, create the following IAM policy:
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "ssm:GetParameter",
            "ssm:GetParameters"
          ],
          "Resource": "arn:aws:ssm:REGION:ACCOUNT-ID:parameter/ec2/windows/rdp-user-password"
        },
        {
          "Effect": "Allow",
          "Action": [
            "kms:Decrypt"
          ],
          "Resource": "arn:aws:kms:REGION:ACCOUNT-ID:key/KEY-ID"
        }
      ]
    }
    Note: Replace REGION with your Region and ACCOUNT-ID with your account ID. Also, replace KEY-ID with your AWS KMS key ID. You can use a custom key or the default aws/ssm key.
  3. Create an IAM role that's name EC2-RDP-Role to allow the instance to retrieve the secret or parameter. It's a best practice to create the role when you launch the instance. To use an existing instance, create the role, and then attach it to the instance. For instructions, see To attach an IAM role to an instance on Attach an IAM role to an instance.
    Note: For the permissions policy, use the IAM policy that you created.

Add the PowerShell script to the user data

To update the user data at launch, use the launch instance wizard to launch the instance and configure the following settings:

  • Under Advanced details, select EC2-RDP-Role for IAM instance profile.
  • Under User data, enter the following PowerShell script based on whether you used Secrets Manager or Parameter Store.
    Secrets Manager:
    <powershell>
    # Import the AWS PowerShell module
    Import-Module AWSPowerShell
    
    # Retrieve the secret from Secrets Manager
    $secretName = "ec2/windows/rdp-user-password"
    $region = "us-east-1"  # Replace with your AWS Region
    
    try {
        # Get the secret value
        $secretValue = Get-SECSecretValue -SecretId $secretName -Region $region
    
        # Parse the secret (assumes JSON format with "password" key)
        $secretObject = $secretValue.SecretString | ConvertFrom-Json
        $passwordString = $secretObject.password
    
        # Convert to SecureString
        $securePassword = ConvertTo-SecureString -String $passwordString -AsPlainText -Force
    
        # Create the new local user
        $user = New-LocalUser -AccountNeverExpires:$true `
                              -Password $securePassword `
                              -Name "RDPUser" `
                              -FullName "Local RDP User" `
                              -Description "RDP user created via Secrets Manager"
    
        # Add user to required groups
        Add-LocalGroupMember -Group "Remote Desktop Users" -Member $user
        Add-LocalGroupMember -Group "Administrators" -Member $user
    
        Write-Host "User RDPUser created successfully using Secrets Manager"
    }
    catch {
        Write-Error "Failed to create user: $_"
        exit 1
    }
    </powershell>
    
    Note: Replace us-east-1 with your Region. If the user doesn't require administrator access, then remove Add-LocalGroupMember -Group "Administrators.
    Parameter Store:
    <powershell>
    # Import the AWS PowerShell module
    Import-Module AWSPowerShell
    
    # Retrieve the parameter from Parameter Store
    $parameterName = "/ec2/windows/rdp-user-password"
    $region = "us-east-1"  # Replace with your AWS Region
    
    try {
        # Get the parameter value with decryption
        $parameter = Get-SSMParameter -Name $parameterName -WithDecryption $true -Region $region
    
        # Extract the password value
        $passwordString = $parameter.Value
    
        # Convert to SecureString
        $securePassword = ConvertTo-SecureString -String $passwordString -AsPlainText -Force
    
        # Create the new local user
        $user = New-LocalUser -AccountNeverExpires:$true `
                              -Password $securePassword `
                              -Name "RDPUser" `
                              -FullName "Local RDP User" `
                              -Description "RDP user created via Parameter Store"
    
        # Add user to required groups
        Add-LocalGroupMember -Group "Remote Desktop Users" -Member $user
        Add-LocalGroupMember -Group "Administrators" -Member $user
    
        Write-Host "User RDPUser created successfully using Parameter Store"
    }
    catch {
        Write-Error "Failed to create user: $_"
        exit 1
    }
    </powershell>
    Note: Replace us-east-1 with your Region. If the user doesn't require administrator access, then remove Add-LocalGroupMember -Group "Administrators.

To add the PowerShell script to an existing instance, configure Amazon EC2 to use the updated user data at the next start. Then, update the instance user data with the preceding PowerShell script with the <persist>true</persist> line at the end of the script.

Hardcode passwords into test environments

Important: The following method stores passwords in plaintext. Use this method only for temporary testing or development instances that you terminate immediately after the test. Don't use this method for production environments.

Update your instance's user data

Configure Amazon EC2 to use the updated user data at the next start. Then, update the instance user data with the following PowerShell script:

<powershell>$user = New-LocalUser -AccountNeverExpires:$true -Password ( ConvertTo-SecureString -AsPlainText -Force 'ExampleP@ssword!') -Name "RDPUser" -FullName "Local RDPUser" -Description "Local Administrator"
Add-LocalGroupMember -Group "Administrators" -Member $user   
Add-LocalGroupMember -Group "Remote Desktop Users" -Member $user   
</powershell>  
<persist>true</persist>

Note: The preceding example script creates a new local user that's named RDPUser with the ExampleP@ssword! password. The account is set to enabled, doesn't expire, and includes a brief description. The script adds the user to both the Administrators group and the Remote Desktop Users group. You must include access to the Remote Desktop Users group. If the user doesn't require administrator access, then remove Add-LocalGroupMember -Group "Administrators" -Member $user.

Verify that Amazon EC2 created the user account

To confirm that Amazon EC2 created the user account, use Session Manager, a capability of AWS Systems Manager to connect to the instance. Then, run the one of the following commands:

Get-LocalUser -Name "RDPUser"  

-or-

Get-WmiObject -Class Win32_UserAccount -Filter "LocalAccount='True'" |Select Name, Status, Disabled | select-string -AllMatches RDPUser

If you activated WinRM on the instance, then complete the following steps to create New-PSSession on remote instance:

  1. Run the following command to store the existing administrator credentials:
    $password = ConvertTo-SecureString "Administrator_Password" -AsPlainText -Force  
    $cred = New-PSCredential -UserName "Administrator" -Password $password  
    Note: Replace Administrator_Password with your administrator password.
  2. Run the following command to create a remote session:
    $session = New-PSSession -ComputerName "ip-address-of-instance" -Credential $cred  
    Note: Replace ip-address-of-instance with the instance IP address.
  3. Run the following command to verify that the new user exists on the remote instance:
    Invoke-Command -Session $session -ScriptBlock {  
        Get-LocalUser -Name "RDPUser"  
    }  
    Note: Replace RDPUser with your user account name.
  4. Run the following command to end the PSSession session:
    Remove-PSSession $session
    For more information, see New-PSSession on the Microsoft website.

Troubleshoot issues

To identify issues, test the script on a local computer. Also, test the script on another instance with a similar configuration, such as the same operating system (OS), subnets, and IAM roles. These tests help you identify whether the issue is at the instance or user data level.

Troubleshoot issues where the user account wasn't created

Take the following actions:

  • If you use Secrets Manager or Parameter Store, then verify that you attached the IAM role to the instance.
    Note: To view the attached instance role, open the Amazon EC2 console, and then choose Instances. Then, choose your instance to view the instance details.
  • Verify that the IAM role has the required permissions.
  • View the user data execution logs at C:\ProgramData\Amazon\EC2-Windows\Launch\Log\UserdataExecution.log to check for execution errors that you must troubleshoot.
  • Run one of the following commands to check the instance metadata and access to user data:
    route print
    -or-
    invoke-webrequest http://169.254.169.254/latest/meta-data/
    If you receive a response that isn't a 200 response, then troubleshoot user data script issues or instance metadata issues.

Troubleshoot access denied issues when Amazon EC2 retrieves the secret or parameter

Take the following actions

  • Verify that the secret or parameter name matches exactly.
    Note: Secrets and parameters are case-sensitive.
  • Verify that the IAM role has the required permissions for the secret or parameter's Amazon Resource Name (ARN).
  • (Secrets Manager only) Verify that the secret exists in the same Region as your instance.
  • (Parameter Store only) Verify that you have kms:Decrypt permissions for the AWS KMS key.
AWS OFFICIALUpdated 4 months ago