Rename ec2 hostname using userdata does not work - amazon-web-services

I am trying to rename the hostname to a specific one - TEAM-CNTNR using the user-data script but after the EC2 instance comes up online and I connect to it (via Session Manager), the hostname is the random one that EC2 service gives the instance such as EC2AMAZ-VHAGRNV.
This is my user-data script, am I missing something? This is my user-data script:
<powershell>
Import-Module ECSTools
[Environment]::SetEnvironmentVariable("ECS_ENABLE_AWSLOGS_EXECUTIONROLE_OVERRIDE", $TRUE, "Machine")
Initialize-ECSAgent -Cluster "${cluster_name}" -EnableTaskIAMRole -LoggingDrivers '["json-file","awslogs"]' -EnableTaskENI
# rename the instance hostname so that it works with the gMSA account
Rename-Computer -NewName "TEAM-CNTNR" -Force
## instance-domain-join code here. Omitted for brevity
# Perform the domain join
Add-Computer -DomainName "$domain_name.$domain_tld" -OUPath "OU=Computers,OU=enrcloud,DC=enr,DC=cloud" -ComputerName "$hostname" -Credential $credential -Passthru -Verbose -Restart
</powershell>
<runAsLocalSystem>true</runAsLocalSystem>

It was revealed to me that there is a NewName parameter that can be used that is part of the Add-Computer command that would:
join the machine to the new domain
and change its name at the same time
Add-Computer ... -NewName "MyComputer" ...
Reference: Microsoft site

Related

How can I install Oracle Database 18c XE into Windows docker container?

I'm not able to install Oracle Database 18c Express Edtition into a Windows docker container.
The Oracle silent setup (documented here) reports success, but no installation is being performed. The destination directory (C:\OracleXE\) is empty. And, of course, nothing is installed.
What am I doing wrong here?
This is my Dockerfile
# escape=`
FROM mcr.microsoft.com/windows:20H2
USER ContainerAdministrator
COPY / /O18c
WORKDIR /O18c
SHELL ["PowerShell", "-Command"]
RUN New-Item 'C:\db-data' -ItemType Directory; New-LocalUser -Name OracleAdministrator -NoPassword -UserMayNotChangePassword -AccountNeverExpires; Set-LocalUser -Name OracleAdministrator -PasswordNeverExpires:$True; $adm = (Get-LocalGroup | Where-Object {$_.Name.IndexOf('Admin') -eq 0}).Name; Add-LocalGroupMember -Group $adm -Member OracleAdministrator
USER OracleAdministrator
RUN ./Setup.exe /s /v"RSP_FILE=C:\O18c\XEInstall.rsp" /v"/L*v C:\O18c\setup.log" /v"/qn"
EXPOSE 1521 5550 3389
VOLUME C:\db-data
ENTRYPOINT PowerShell
This is my XEInstall.rsp file
#Do not leave any parameter with empty value
#Install Directory location, username can be replaced with current user
INSTALLDIR=C:\OracleXE\
#Database password, All users are set with this password, Remove the value once installation is complete
PASSWORD=foobar123!
#If listener port is set to 0, available port will be allocated starting from 1521 automatically
LISTENER_PORT=0
#If EM express port is set to 0, available port will be used starting from 5550 automatically
EMEXPRESS_PORT=0
#Specify char set of the database
CHAR_SET=AL32UTF8
This is my directory structure:
This is my docker build command:
docker build -f .\Dockerfile .\OracleXE184_Win64\
Apparently, the Oracle setup doesn't work with PowerShell.
When run with standard command prompt, setup installs fine.
This is my working Dockerfile
# escape=`
FROM mcr.microsoft.com/windows:20H2
USER ContainerAdministrator
COPY / /O18c
WORKDIR /O18c
RUN PowerShell -Command "New-Item 'C:\db-data' -ItemType Directory; New-LocalUser -Name OracleAdministrator -NoPassword -UserMayNotChangePassword -AccountNeverExpires; Set-LocalUser -Name OracleAdministrator -PasswordNeverExpires:$True; $adm = (Get-LocalGroup | Where-Object {$_.Name.IndexOf('Admin') -eq 0}).Name; Add-LocalGroupMember -Group $adm -Member OracleAdministrator;"
USER OracleAdministrator
RUN setup.exe /s /v"RSP_FILE=C:\O18c\XEInstall.rsp" /v"/L*v C:\O18c\setup.log" /v"/qn"
RUN PowerShell -Command "Get-ChildItem; Get-ChildItem \ -Attributes Directory;"
EXPOSE 1521 5550 3389
VOLUME C:\db-datado
ENTRYPOINT PowerShell

Powershell - Find instances without a tag associated

I have spent a long time on this getting nowhere and cannot find an answer on the web.
I am looking for a PowerShell script that will return EC2 Instances without tag called 'backup' associated with it.
Each Backup tag has a value but right now I am just looking for instances which do not have the tag. Any help would be greatly appreciated.
Thanks
This returns the EC2 Instance objects without a tag named Backup in a specific region:
Import-Module AWSPowershell
$instances = (Get-EC2Instance -Region $region -Credential $cred).Instances
$EC2Tags = Get-EC2Tag -Region $region -Credential $cred |
Where {$_.Key -eq 'Backup' -and $_.ResourceType -EQ 'Instance'}
$instances | Where {$_.InstanceID -NotIn $EC2Tags.ResourceID}

Pull Server names and ip address and see if they're live

I am looking to run a PowerShell script that will pull all servers from AD, show me the FQDN and IP address as well as tell me if the server is pinging.
I have a couple of scripts that do certain parts but would like to get something all in one and am having a hard time doing it.
Ping a list of servers:
$ServerName = Get-Content "c:\temp\servers.txt"
foreach ($Server in $ServerName) {
if (test-Connection -ComputerName $Server -Count 2 -Quiet ) {
"$Server is Pinging "
} else {
"$Server not pinging"
}
}
I also have a script to pull all servers from AD which shows server name, FQDN, and OS version:
Import-Module ActiveDirectory
Get-ADComputer -Filter {OperatingSystem -like '*Windows Server*'} -Properties * |
select Name, DNSHostName, OperatingSystem
Any help in getting a script to show me all servers in my environment with FQDN, IP address and if there live would be appreciated.
You should only choose desired properties with the -Property argument and not pull everything through network with *. Also quotes should be used with -Filter, not braces.
You can add a calculated property to Select-Object and get the value from Test-NetConnection:
Get-ADComputer -Filter "OperatingSystem -like '*Windows Server*'" -Properties dnshostname, operatingsystem |
Select-Object name, dnshostname, operatingsystem, `
#{n="PingSucceeded";e={(Test-NetConnection $_.name).PingSucceeded}}

EC2 User data - Disable it after all conditions are met in user data

I'm trying to rename hostname and add to AD of a spot instance. It is a simple powershell script. I've read the docs that by default user data will be disable after it gets executed once and if <persist>true</persist> is used it will not be disabled.
I think I saw somewhere this(enabling to be run at each startup) is done via taskscheduler but can't find the link.
Can someone point me to the task scheduler job or the way to manually disable the userdata once my if conditions are met.
<powershell>
Set-ExecutionPolicy unrestricted -Force
$instanceName = "test-name5"
$username = "domain\username"
$password = "password" | ConvertTo-SecureString -AsPlainText -Force
$cred = New-Object -typename System.Management.Automation.PSCredential($username, $password)
Start-Sleep -s 5
$hostname = hostname
$domain = (Get-WmiObject win32_computersystem).Domain
if (!($hostname -eq $instanceName)){
Rename-Computer -NewName $instanceName -restart -force
}Elseif (!($domain -eq 'my.domain.local')){
Start-Sleep -s 5
Add-Computer -DomainName my.domain.local -OUPath "OU=Windows,OU=QAServers,OU=Servers,DC=my,DC=domain,DC=local" -Credential $cred -Force -Restart -erroraction 'stop'
}Else {
####code to disable the running of userdata once above conditions
are met####
}
</powershell>
<persist>true</persist>
It's worth reading the ec2config-service documentation, as the setting you want is referenced in there.
You want the Ec2HandleUserData setting, which is configured in the Config.xml.
Powershell can easily update this setting:
$path = 'C:\Program Files\Amazon\Ec2ConfigService\Settings\config.xml'
$xml = [xml](Get-Content $path)
$state = $xml.Ec2ConfigurationSettings.Plugins.Plugin | where {$_.Name -eq 'Ec2HandleUserData'}
$state.State = 'Disabled'
$xml.Save($path)
I use this code when creating custom AMI's to re-enable userdata handling ($state.State = 'Enabled').
EDIT: The above is for ec2config not ec2launch which is what the OP is using. I'd missed this originally.
I this case I think you need to change the way your script runs, rather than use <persist> and then try to disable its functionality, I would remove the persist tag and call InitializeInstance.ps1 –Schedule (documentation link) in your if for the conditions you want the userdata to re-run:
if ($hostname -ne $instanceName) {
& C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1 -Schedule
Rename-Computer -NewName $instanceName -Restart -Force
}
elseif ($domain -ne 'my.domain.local') {
& C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1 -Schedule
Add-Computer -DomainName aws.macmillan.local -OUPath "OU=Windows,OU=QAServers,OU=Servers,DC=my,DC=domain,DC=local" -Credential $cred -Force -Restart -ErrorAction 'stop'
}
As I said in the comments of the previous answer, I had 3 options and since I found the aws scheduled task I went with the last option. Answering my own question since it'll be easy to spot the code.
<powershell>
Set-ExecutionPolicy unrestricted -Force
#Enter instance hostname here
$instanceName = "test-name8"
$username = "domain\username"
#Using ssm parameter store to avoid having the password in plaintext
$password = (Get-SSMParameterValue -Name AD-Password -WithDecryption $True -Region us-east-1).Parameters[0].Value | ConvertTo-SecureString -asPlainText -Force
Start-Sleep -s 3
$cred = New-Object -typename System.Management.Automation.PSCredential($username, $password)
Start-Sleep -s 5
$hostname = hostname
$domain = (Get-WmiObject win32_computersystem).Domain
if ($hostname -ne $instanceName){
Rename-Computer -NewName $instanceName -restart -force
}Elseif ($domain -ne 'my.domain.local'){
Start-Sleep -s 5
Add-Computer -DomainName my.domain.local -OUPath "OU=Windows,OU=QAServers,OU=Servers,DC=my,DC=domain,DC=local" -Credential $cred -Force -Restart -erroraction 'stop'
}Else {
Disable-ScheduledTask -TaskName "Amazon Ec2 Launch - Userdata Execution"
Unregister-ScheduledTask -TaskName "Amazon Ec2 Launch - Userdata Execution"
}
</powershell>
<persist>true</persist>
note: a role that has ssm policies must be attached while launching the server for this ssm parameter command to work.
I was solving similar issue and I had to change Windows Server 2016 hostname and enroll it to Elastic Server Fleet. Also I could not allow instance to be rebooted. I used this code to solve this.
NB. I understand that it is not direct way of doing this and has numerous drawbacks, but in my circumstances goal was achieved without negative impact.
<powershell>
$ComputerName = "MyPCRandomName"
Set-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -name "Hostname" -value $ComputerName
elastic-agent enroll --enrollment-token 123 --url=321
</powershell>

Environment Variables in newest AWS EC2 instance

I am trying to get ENVIRONMENT Variables into the EC2 instance (trying to run a django app on Amazon Linux AMI 2018.03.0 (HVM), SSD Volume Type ami-0ff8a91507f77f867 ). How do you get them in the newest version of amazon's linux, or get the logging so it can be traced.
user-data text (modified from here):
#!/bin/bash
#trying to get a file made
touch /tmp/testfile.txt
cat 'This and that' > /tmp/testfile.txt
#trying to log
echo 'Woot!' > /home/ec2-user/user-script-output.txt
#Trying to get the output logged to see what is going wrong
exec > >(tee /var/log/user-data.log|logger -t user-data ) 2>&1
#trying to log
echo "XXXXXXXXXX STARTING USER DATA SCRIPT XXXXXXXXXXXXXX"
#trying to store the ENVIRONMENT VARIABLES
PARAMETER_PATH='/'
REGION='us-east-1'
# Functions
AWS="/usr/local/bin/aws"
get_parameter_store_tags() {
echo $($AWS ssm get-parameters-by-path --with-decryption --path ${PARAMETER_PATH} --region ${REGION})
}
params_to_env () {
params=$1
# If .Ta1gs does not exist we assume ssm Parameteres object.
SELECTOR="Name"
for key in $(echo $params | /usr/bin/jq -r ".[][].${SELECTOR}"); do
value=$(echo $params | /usr/bin/jq -r ".[][] | select(.${SELECTOR}==\"$key\") | .Value")
key=$(echo "${key##*/}" | /usr/bin/tr ':' '_' | /usr/bin/tr '-' '_' | /usr/bin/tr '[:lower:]' '[:upper:]')
export $key="$value"
echo "$key=$value"
done
}
# Get TAGS
if [ -z "$PARAMETER_PATH" ]
then
echo "Please provide a parameter store path. -p option"
exit 1
fi
TAGS=$(get_parameter_store_tags ${PARAMETER_PATH} ${REGION})
echo "Tags fetched via ssm from ${PARAMETER_PATH} ${REGION}"
echo "Adding new variables..."
params_to_env "$TAGS"
Notes -
What i think i know but am unsure
the user-data script is only loaded when it is created, not when I stop and then start mentioned here (although it also says [i think outdated] that the output is logged to /var/log/cloud-init-output.log )
I may not be starting the instance correctly
I don't know where to store the bash script so that it can be executed
What I have verified
the user-data text is on the instance by ssh-ing in and curl http://169.254.169.254/latest/user-data shows the current text (#!/bin/bash …)
What Ive tried
editing rc.local directly to export AWS_ACCESS_KEY_ID='JEFEJEFEJEFEJEFE' … and the like
putting them in the AWS Parameter Store (and can see them via the correct call, I just can't trace getting them into the EC2 instance without logs or confirming if the user-data is getting run)
putting ENV variables in Tags and importing them as mentioned here:
tried outputting the logs to other files as suggested here (Not seeing any log files in the ssh instance or on the system log)
viewing the System Log on the aws webpage to see any errors/logs via selecting the instance -> 'Actions' -> 'Instance Settings' -> 'Get System Log' (not seeing any commands run or log statements [only 1 unrelated word of user])