AWSTemplateFormatVersion: '2010-09-09'
Description: This example template describes an Amazon EC2 Systems Manager document.
  It contains a sample script that can be used to join an EC2 instance to an Active
  Directory domain.
Parameters:
  DNSParameterStore:
    AllowedPattern: (?!^([aA][wW][sS]|[sS][sS][mM]))(?=^[-a-zA-Z0-9_.]*$).*
    ConstraintDescription: please specify a valid Parameter Store name.
    Description: 'Please specify the name of the Parameter Store to use: maximum =
      1024 characters.'
    MaxLength: '1024'
    MinLength: '1'
    Type: String
  DomainJoinPasswordParameterStore:
    AllowedPattern: (?!^([aA][wW][sS]|[sS][sS][mM]))(?=^[-a-zA-Z0-9_.]*$).*
    ConstraintDescription: please specify a valid Parameter Store name.
    Description: 'Please specify the name of the Parameter Store to use: maximum =
      1024 characters.'
    MaxLength: '1024'
    MinLength: '1'
    Type: String
  DomainJoinUserNameParameterStore:
    AllowedPattern: (?!^([aA][wW][sS]|[sS][sS][mM]))(?=^[-a-zA-Z0-9_.]*$).*
    ConstraintDescription: please specify a valid Parameter Store name.
    Description: 'Please specify the name of the Parameter Store to use: maximum =
      1024 characters.'
    MaxLength: '1024'
    MinLength: '1'
    Type: String
  DomainNameParameterStore:
    AllowedPattern: (?!^([aA][wW][sS]|[sS][sS][mM]))(?=^[-a-zA-Z0-9_.]*$).*
    ConstraintDescription: please specify a valid Parameter Store name.
    Description: 'Please specify the name of the Parameter Store to use: maximum =
      1024 characters.'
    MaxLength: '1024'
    MinLength: '1'
    Type: String
Resources:
  Document:
    Type: AWS::SSM::Document
    Properties:
      Content:
        description: Run a PowerShell script to domain join a Windows instance securely
        mainSteps:
        - action: aws:runPowerShellScript
          inputs:
            runCommand:
            - '# Example PowerShell script to domain join a Windows instance securely'
            - ''
            - $ErrorActionPreference = 'Stop'
            - ''
            - try{
            - '    # Parameter names'
            - !Sub '    $dnsParameterStore = ''${DNSParameterStore}'''
            - !Sub '    $domainNameParameterStore = ''${DomainNameParameterStore}'''
            - !Sub '    $domainJoinUserNameParameterStore = ''${DomainJoinUserNameParameterStore}'''
            - !Sub '    $domainJoinPasswordParameterStore = ''${DomainJoinPasswordParameterStore}'''
            - ''
            - '    # Retrieve configuration values from parameters'
            - '    $ipdns = (Get-SSMParameterValue -Name $dnsParameterStore).Parameters[0].Value'
            - '    $domain = (Get-SSMParameterValue -Name $domainNameParameterStore).Parameters[0].Value'
            - '    $username = $domain + ''\'' + (Get-SSMParameterValue -Name $domainJoinUserNameParameterStore).Parameters[0].Value'
            - '    $password = (Get-SSMParameterValue -Name $domainJoinPasswordParameterStore
              -WithDecryption $True).Parameters[0].Value | ConvertTo-SecureString
              -asPlainText -Force'
            - ''
            - '    # Create a System.Management.Automation.PSCredential object'
            - '    $credential = New-Object System.Management.Automation.PSCredential($username,
              $password)'
            - ''
            - '    # Determine the name of the Network Adapter of this machine'
            - '    $networkAdapter = Get-WmiObject Win32_NetworkAdapter -Filter "AdapterType
              = ''Ethernet 802.3''"'
            - '    $networkAdapterName = ($networkAdapter | Select-Object -First 1).NetConnectionID'
            - ''
            - '    # Set up the IPv4 address of the AD DNS server as the first DNS
              server on this machine'
            - '    netsh.exe interface ipv4 add dnsservers name="$networkAdapterName"
              address=$ipdns index=1'
            - ''
            - '    # Join the domain and reboot'
            - '    Add-Computer -DomainName $domain -Credential $credential'
            - '    Restart-Computer -Force'
            - '}'
            - catch [Exception]{
            - '    Write-Host $_.Exception.ToString()'
            - '    Write-Host ''Command execution failed.'''
            - '    $host.SetShouldExit(1)'
            - '}'
          name: runPowerShellWithSecureString
        schemaVersion: '2.0'
      DocumentType: Command
Outputs:
  DocumentName:
    Description: The name of the Document.
    Export:
      Name: !Sub '${AWS::StackName}-Document'
    Value: !Ref 'Document'

