Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save mikedougherty/20f4cfc5ec560315d65e849dc9b15b67 to your computer and use it in GitHub Desktop.

Select an option

Save mikedougherty/20f4cfc5ec560315d65e849dc9b15b67 to your computer and use it in GitHub Desktop.
# Forked from https://gist.github.com/masterzen/6714787, thank you
#
# Windows AMIs don't have WinRM enabled by default -- this script will enable WinRM
# AND install 7-zip, curl and .NET 4 if its missing.
# Then use the EC2 tools to create a new AMI from the result, and you have a system
# that will execute user-data as a PowerShell script after the instance fires up!
# This has been tested on Windows 2008 SP2 64bits AMIs provided by Amazon
#
# Inject this as user-data of a Windows 2008 AMI, like this (edit the adminPassword to your needs):
#
# <powershell>
# Set-ExecutionPolicy Unrestricted
# icm $executioncontext.InvokeCommand.NewScriptBlock((New-Object Net.WebClient).DownloadString('https://gist.githubusercontent.com/mikedougherty/20f4cfc5ec560315d65e849dc9b15b67/raw/')) -ArgumentList "adminPassword"
# </powershell>
#
param(
[Parameter(Mandatory=$true)]
[string]
$AdminPassword
)
Start-Transcript -Path 'c:\bootstrap-transcript.txt' -Force
Set-StrictMode -Version Latest
Set-ExecutionPolicy Unrestricted
$log = 'c:\Bootstrap.txt'
while (($AdminPassword -eq $null) -or ($AdminPassword -eq ''))
{
$AdminPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR((Read-Host "Enter a non-null / non-empty Administrator password" -AsSecureString)))
}
$systemPath = [Environment]::GetFolderPath([Environment+SpecialFolder]::System)
$sysNative = [IO.Path]::Combine($env:windir, "sysnative")
#http://blogs.msdn.com/b/david.wang/archive/2006/03/26/howto-detect-process-bitness.aspx
$Is32Bit = (($Env:PROCESSOR_ARCHITECTURE -eq 'x86') -and ($Env:PROCESSOR_ARCHITEW6432 -eq $null))
Add-Content $log -value "Is 32-bit [$Is32Bit]"
# move to home, PS is incredibly complex :)
cd $Env:USERPROFILE
Set-Location -Path $Env:USERPROFILE
[Environment]::CurrentDirectory=(Get-Location -PSProvider FileSystem).ProviderPath
#change admin password
net user Administrator $AdminPassword
Add-Content $log -value "Changed Administrator password"
$client = new-object System.Net.WebClient
#chocolatey - standard one line installer doesn't work on Core b/c Shell.Application can't unzip
Invoke-Expression ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))
Add-Content $log -value "Installed Chocolatey"
SetX Path "${Env:Path};C:\ProgramData\chocolatey\bin;C:\ProgramData\chocolatey\tools" /m
$Env:Path += ';C:\ProgramData\chocolatey\bin;C:\ProgramData\chocolatey\tools'
#.net 4
if ((Test-Path "${Env:windir}\Microsoft.NET\Framework\v4.0.30319") -eq $false)
{
&choco install -y dotnet4.0
Add-Content $log -value "Found that .NET4 was not installed and downloaded / installed"
}
#configure powershell to use .net 4
$config = @'
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!-- http://msdn.microsoft.com/en-us/library/w4atty68.aspx -->
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" />
<supportedRuntime version="v2.0.50727" />
</startup>
</configuration>
'@
if (Test-Path "${Env:windir}\SysWOW64\WindowsPowerShell\v1.0\powershell.exe")
{
$config | Set-Content "${Env:windir}\SysWOW64\WindowsPowerShell\v1.0\powershell.exe.config"
Add-Content $log -value "Configured 32-bit Powershell on x64 OS to use .NET 4"
}
if (Test-Path "${Env:windir}\system32\WindowsPowerShell\v1.0\powershell.exe")
{
$config | Set-Content "${Env:windir}\system32\WindowsPowerShell\v1.0\powershell.exe.config"
Add-Content $log -value "Configured host OS specific Powershell at ${Env:windir}\system32\ to use .NET 4"
}
#7zip
&choco install -y 7zip.commandline
Add-Content $log -value "Installed 7-zip"
#vc 2010 redstributable
&choco install -y vcredist2010
Add-Content $log -value "Installed VC++ 2010"
#vc 2008 redstributable
&choco install -y vcredist2008
Add-Content $log -value "Installed VC++ 2008"
&choco install -y curl
Add-Content $log -value "Installed Curl"
&choco install -y vim
Add-Content $log -value "Installed Vim text editor"
&choco install -y puppet
&sc.exe config puppet start=auto
Add-Content $log -value "Installed Puppet"
icm $executioncontext.InvokeCommand.NewScriptBlock((New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/ansible/ansible/dd4c56e4d68664e4a50292aa19ea61b15c92287c/examples/scripts/ConfigureRemotingForAnsible.ps1')) -ArgumentList "-CertValidityDays 3650 -SkipNetworkProfileCheck"
&winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="8192"}'
&winrm set winrm/config '@{MaxTimeoutms="3600000"}'
Add-Content $log -value "Ran winrm setup"
&netsh advfirewall firewall add rule profile=any name="Allow SMB" dir=in localport=445 protocol=TCP action=allow
Add-Content $log -value "Ran firewall config to allow incoming smb"
&netsh advfirewall firewall add rule profile=any name="Allow RDP" dir=in localport=3389 protocol=TCP action=allow
Add-Content $log -value "Ran firewall config to allow incoming rdp"
#run SMRemoting script to enable event log management, etc - available only on R2
$remotingScript = [IO.Path]::Combine($systemPath, 'Configure-SMRemoting.ps1')
if (-not (Test-Path $remotingScript)) { $remotingScript = [IO.Path]::Combine($sysNative, 'Configure-SMRemoting.ps1') }
Add-Content $log -value "Found Remoting Script: [$(Test-Path $remotingScript)] at $remotingScript"
if (Test-Path $remotingScript)
{
. $remotingScript -force -enable
Add-Content $log -value 'Ran Configure-SMRemoting.ps1'
}
#wait a bit, it's windows after all
Start-Sleep -m 10000
#Write-Host "Press any key to reboot and finish image configuration"
#[void]$host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
Restart-Computer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment