Skip to content

Instantly share code, notes, and snippets.

Last active June 18, 2018 18:47
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
Quickly launch and preconfigure a Windows 2016 dev machine in AWS with spot pricing, from your mac
#!/bin/bash -ex
# Quickly launch and preconfigure a Windows 1803 dev machine in AWS with spot pricing, from your mac
usage=' --username irving --password Cod3Can! --ssh-key irving --subnet subnet-7fd06308 --security-group-id sg-8a0f82f5
NOTE: Due to a weird assumption in the UserData script, the password must be exactly 8 characters long and meet complexity requirements
NOTE2: Create a SECURITY_GROUP_ID that allows port 3389 from your IP address
NOTE3: Install Microsoft Remote Desktop 10 from the app store ( )
if [ $# -lt 5 ]; then
echo -e $usage
exit 1
# Argument parsing
while [[ $# -gt 1 ]]
case $key in
shift # past argument
shift # past argument
shift # past argument
shift # past argument
shift # past argument
echo -e $usage
exit 0
echo "Unknown option $1"
echo -e $usage
exit 1
shift # past argument or value
# Hack our own user-data file, because knife-ec2's lacks things that we need to revisit later:
# 1. hangs forever if you have a password longer than 8 characters, at a y/n prompt
# 2. doesn't add non-secure winrm port
# 3. need to hack path to install ChefDK upfront
cat > windows-user-data.txt <<EOF
# below two commands are known to fail for arbitrary reasons
try { winrm quickconfig -q }
catch {write-host "winrm quickconfig failed"}
try { Enable-PSRemoting -force}
catch {write-host "Enable-PSRemoting -force failed"}
write-host 'setting up WinRm';
winrm set winrm/config '@{MaxTimeoutms="1800000"}';
winrm set winrm/config/client/auth '@{Basic="true"}'; # per
winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="300"}';
winrm set winrm/config/service '@{AllowUnencrypted="true"}'; # per
winrm set winrm/config/service/auth '@{Basic="true"}'; # per
# needed for windows to manipulate centralized config files which live of a share. Such as AppFabric.
winrm set winrm/config/service/auth '@{CredSSP="true"}';
write-host 'Adding custom firewall rule for 5985 and 5986';
netsh advfirewall firewall add rule name="Windows Remote Management (HTTP-In)" dir=in action=allow enable=yes profile=any protocol=tcp localport=5985 remoteip=any;
netsh advfirewall firewall add rule name="WinRM HTTPS" protocol=TCP dir=in Localport=5986 remoteport=any action=allow localip=any remoteip=any profile=any enable=yes;
# Setting up "Known" user for bootstrapping.
write-host 'setting up secedit rule to disable complex passwords';
"[System Access]" | out-file c:\delete.cfg;
"PasswordComplexity = 0" | out-file c:\delete.cfg -append;
"[Version]" | out-file c:\delete.cfg -append;
'signature="$CHICAGO$"' | out-file c:\delete.cfg -append;
write-host 'changing secedit policy';
secedit /configure /db C:\Windows\security\new.sdb /cfg c:\delete.cfg /areas SECURITYPOLICY;
# TODO: probably need a better escaping system in the future
write-host 'Setting up "Known" user for bootstrapping.';
net user /add ${WINDOWS_USER} ${WINDOWS_PASSWORD} /yes;
write-host 'adding user to admins';
net localgroup Administrators /add ${WINDOWS_USER};
# Install chocolatey, habitat and dev tools
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString(''))
choco install habitat --yes
choco install git --yes
choco install visualstudiocode --yes
choco install googlechrome --yes
LATEST_AMI=$(aws ec2 describe-images \
--owners amazon \
--output text \
--query 'Images[*].{ID:ImageId, Name:Name}' \
--filters "Name=name,Values=Windows_Server-1803-English-Core-ContainersLatest-*" \
| sort -k 2 \
| tail -1 \
| awk '{print $1}')
MY_INSTANCEID=$(aws ec2 run-instances \
--image-id $LATEST_AMI \
--key-name $SSH_KEY \
--instance-type ${INSTANCE_TYPE} \
--subnet-id ${SUBNET} \
--security-group-ids ${SECURITY_GROUP_ID} \
--block-device-mappings DeviceName=/dev/sda1,Ebs="{VolumeSize=100,VolumeType=gp2}" \
--user-data file://windows-user-data.txt \
--ebs-optimized \
--tag-specifications ResourceType=instance,Tags="[{Key='Name',Value='$WINDOWS_USER-windows-dev'},{Key='X-Contact',Value='$WINDOWS_USER'}]" \
--instance-market-options MarketType=spot,SpotOptions="{SpotInstanceType=persistent,InstanceInterruptionBehavior=stop}" \
--output text --query "Instances[0].InstanceId")
# get the server's IP
MY_SERVER=$(aws ec2 describe-instances \
--instance-id $MY_INSTANCEID \
--query "Reservations[0].Instances[0].PublicIpAddress" \
--output text)
echo "Connecting you now to rdp:// on $MY_SERVER (after waiting 60 seconds)"
sleep 60
open "rdp://full%20address=s:${MY_SERVER}:3389&audiomode=i:2&authentication%20level=i:0&disable%20themes=i:1&screen%20mode%20id=i:1&username=s:${WINDOWS_USER}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment