Skip to content

Instantly share code, notes, and snippets.

@sebug
Created August 28, 2016 13:15
Show Gist options
  • Save sebug/2ba53d51cc778034af5dbe146109dbfc to your computer and use it in GitHub Desktop.
Save sebug/2ba53d51cc778034af5dbe146109dbfc to your computer and use it in GitHub Desktop.
#!/usr/local/bin/python
from subprocess import call
from subprocess import Popen
from subprocess import PIPE
import re
import winrm
import sys
import time
settings = {
"manage_ovf": "/Users/you/packer-virtualbox-iso-1468762258.ovf",
"ad_ovf": "/Users/you/packer-virtualbox-iso-1468684516.ovf",
"internal_network_name": "adintnet",
"adserver_name": "core-2012r2-active-directory",
"manage_name": "server-2012r2-manage-ad",
"ad_server_ip": "192.168.0.225",
"ad_server_computername": "DC",
"domainname": "sandbox.local",
"netbiosname": "SANDBOX",
"manage_ad_ip": "192.168.0.110",
"manage_ad_computername": "ADMANAGE"
}
def vm_dict(line):
vm_line_re = re.compile('"(?P<name>[^"]+)" \\{(?P<id>[^}]+)\\}')
p = vm_line_re.match(line)
if p == None:
return None
return {
"name": p.group('name'),
"id": p.group('id')
}
def list_vms():
vm_list = Popen(["VBoxManage","list","vms"], stdin=PIPE, stdout=PIPE)
out, err = vm_list.communicate(input='\n'.encode())
lines = out.split('\n')
return [vm_dict(l) for l in lines if vm_dict(l) != None]
def list_running_vms():
vm_list = Popen(["VBoxManage","list","runningvms"], stdin=PIPE, stdout=PIPE)
out, err = vm_list.communicate(input='\n'.encode())
lines = out.split('\n')
return [vm_dict(l) for l in lines if vm_dict(l) != None]
def is_running(vm_name):
running_vms = list_running_vms()
matching_vms = [vm for vm in running_vms if vm["name"] == vm_name]
return any(matching_vms)
def start_vm(vm_name):
p = Popen(["VBoxManage","startvm",vm_name], stdin=PIPE, stdout=PIPE)
out, err = p.communicate(input='\n'.encode())
def vm_exists(vm_name):
vms = list_vms()
results = [vm for vm in vms if vm["name"] == vm_name]
return any(results)
def import_vm(ovf_path,name):
vm_import = Popen(["VBoxManage","import",ovf_path,"--vsys","0","--vmname",name], stdin=PIPE, stdout=PIPE)
out, err = vm_import.communicate(input='\n'.encode())
print out
def vm_info(vm_name):
info = Popen(["VBoxManage","showvminfo",vm_name], stdin=PIPE, stdout=PIPE)
out, err = info.communicate(input='\n'.encode())
setting_re = re.compile('(?P<key>[^:]+):\\s*(?P<value>.+)')
lines = out.split('\n')
result = {}
for line in lines:
m = setting_re.match(line)
if m:
result[m.group('key')] = m.group('value')
return result
def forward_winrm_port(vm_name,external_port):
p = Popen(["VBoxManage","modifyvm",vm_name,"--natpf1","guestwinrm,tcp,127.0.0.1," + str(external_port) + ",,5985"], stdin=PIPE, stdout=PIPE)
out, err = p.communicate(input='\n'.encode())
print out
def set_up_internal_network(vmname,internal_network_name):
create_nic2 = Popen(["VBoxManage","modifyvm",vmname,"--nic2","intnet"],
stdin=PIPE, stdout=PIPE)
out, err = create_nic2.communicate(input='\n'.encode())
print out
set_network_name = Popen(["VBoxManage","modifyvm",vmname,"--intnet2",internal_network_name], stdin=PIPE, stdout=PIPE)
out, err = set_network_name.communicate(input='\n'.encode())
print out
def session_for_port(server_port, username = '', password = ''):
if username == '':
username = settings["username"]
if password == '':
password = settings['password']
return winrm.Session('127.0.0.1:' + str(server_port), auth=(username,password))
def get_windows_features(server_port):
s = session_for_port(server_port)
r = s.run_ps("Get-WindowsFeature | Select Name, Installed")
lines = r.std_out.split('\r\n')
feature_re = re.compile('(?P<featurename>\S+)\s+(?P<installed>(False|True))')
result = {}
for l in lines:
m = feature_re.match(l)
if m:
result[m.group('featurename')] = m.group('installed') == 'True'
return result
def install_ad(server_port):
print "Installing AD features"
s = session_for_port(server_port)
r = s.run_ps("""Add-WindowsFeature "RSAT-AD-Tools"
Start-Job -Name addFeature -ScriptBlock {
Add-WindowsFeature "AD-Domain-Services" -IncludeAllSubFeature -IncludeManagementTools
Add-WindowsFeature "DNS" -IncludeAllSubFeature -IncludeManagementTools
Add-WindowsFeature "GPMC" -IncludeAllSubFeature -IncludeManagementTools
}
Wait-Job -Name addFeature""")
print r.std_out
def has_joined_ad_domain(server_port):
s = session_for_port(server_port)
r = s.run_ps('Get-ADDomain')
return r.status_code == 0
def internal_ip_address(server_port):
s = session_for_port(server_port)
r = s.run_ps('Get-NetIPAddress -AddressFamily IPv4 -InterfaceAlias "Ethernet 2" | Select -ExpandProperty IPAddress')
return r.std_out.split('\n')[0]
def change_ip_address(server_port, address):
print "Changing IP address to " + address
s = session_for_port(server_port)
r = s.run_ps('$internalAdapter = Get-NetAdapter -Name "Ethernet 2"\r\n' +
'$ipaddress = "' + address + '"\r\n' +
'$ipprefix = 24\r\n' +
'$ipgw = "192.168.0.1"\r\n' +
'$ipdns = "' + settings["ad_server_ip"] + '"\r\n' +
'$ipif = $internalAdapter.ifIndex\r\n' +
'New-NetIPAddress -IPAddress $ipaddress -PrefixLength $ipprefix -InterfaceIndex $ipif -DefaultGateway $ipgw')
print r.std_out
print r.std_err
def get_computer_name(server_port):
s = session_for_port(server_port)
r = s.run_ps('$env:computername')
return r.std_out.strip()
def change_computer_name(server_port, computername):
print "Changing computer name to " + computername
s = session_for_port(server_port)
r = s.run_ps('Rename-Computer -NewName ' + computername + ' -force')
print r.std_out
print r.std_err
s.run_ps('Restart-Computer')
time.sleep(60)
def create_forest(server_port):
s = session_for_port(server_port)
cmd = '$domainname="' + settings["domainname"] + '"\n'
cmd += '$netbiosName="' + settings["netbiosname"] + '"\n'
cmd += 'Import-Module ADDSDeployment\n'
cmd += '$pwd=ConvertTo-SecureString "' + settings["password"] + '" '
cmd += '-AsPlainText -Force\n'
cmd += 'Install-ADDSForest -CreateDnsDelegation:$false '
cmd += '-DatabasePath "C:\Windows\NTDS" '
cmd += '-DomainMode "Win2012" '
cmd += '-DomainName $domainName '
cmd += '-DomainNetbiosName $netbiosName '
cmd += '-ForestMode "Win2012" '
cmd += '-InstallDns:$true '
cmd += '-LogPath "C:\Windows\NTDS" '
cmd += '-NoRebootOnCompletion:$false '
cmd += '-SysvolPath "C:\Windows\SYSVOL" '
cmd += '-Force:$true -SafeModeAdministratorPassword $pwd'
print "Installing AD Forest"
r = s.run_ps(cmd)
print r.std_out
print r.std_err
def join_domain(server_port):
print 'Joining domain ' + settings["netbiosname"]
s = session_for_port(server_port)
cmd = '$pwd=ConvertTo-SecureString "' + settings["password"] + '" '
cmd += '-AsPlainText -Force\n'
cmd += '$credential = New-Object System.Management.Automation.PSCredential("' + settings["netbiosname"] + '\\' + settings["username"] + '", $pwd)\n'
cmd += 'Add-Computer -DomainName ' + settings["netbiosname"] + ' -Credential $credential -force\n'
r = s.run_ps(cmd)
print r.std_out
print r.std_err
s.run_ps('Restart-Computer')
time.sleep(60)
def get_dns_client_server_address(server_port):
s = session_for_port(server_port)
r = s.run_ps('Get-DnsClientServerAddress -AddressFamily IPv4 -InterfaceIndex (Get-NetAdapter -Name "Ethernet 2").InterfaceIndex | Select -ExpandProperty ServerAddresses')
return r.std_out.strip()
def set_dns_client_server_address(server_port, address):
s = session_for_port(server_port)
r = s.run_ps('Set-DnsClientServerAddress -InterfaceIndex (Get-NetAdapter -Name "Ethernet 2").InterfaceIndex -ServerAddress ' + address)
def main():
print "Setting up Active Directory Lab"
ad_server_port = 5986
manage_ad_port = 5987
settings["username"] = sys.argv[1]
settings["password"] = sys.argv[2]
if (not vm_exists(settings["adserver_name"])):
import_vm(settings["ad_ovf"],settings["adserver_name"])
if (not vm_exists(settings["manage_name"])):
import_vm(settings["manage_ovf"],settings["manage_name"])
if (vm_info(settings["adserver_name"])["NIC 2"] == "disabled"):
set_up_internal_network(settings["adserver_name"],settings["internal_network_name"])
if (vm_info(settings["manage_name"])["NIC 2"] == "disabled"):
set_up_internal_network(settings["manage_name"],settings["internal_network_name"])
if ("NIC 1 Rule(1)" not in vm_info(settings["adserver_name"])):
forward_winrm_port(settings["adserver_name"],ad_server_port)
if (not is_running(settings["adserver_name"])):
start_vm(settings["adserver_name"])
time.sleep(60) # I'd say that's about as long as it takes the machine to boot up
if (not get_windows_features(ad_server_port)['RSAT-AD-Tools']):
install_ad(ad_server_port)
time.sleep(60)
if (internal_ip_address(ad_server_port).strip() != settings["ad_server_ip"]):
change_ip_address(ad_server_port, settings["ad_server_ip"])
if (get_computer_name(ad_server_port) != settings["ad_server_computername"]):
change_computer_name(ad_server_port, settings["ad_server_computername"])
if (not has_joined_ad_domain(ad_server_port)):
create_forest(ad_server_port)
if ("NIC 1 Rule(1)" not in vm_info(settings["manage_name"])):
forward_winrm_port(settings["manage_name"],manage_ad_port)
if (not is_running(settings["manage_name"])):
start_vm(settings["manage_name"])
time.sleep(60)
if (internal_ip_address(manage_ad_port).strip() != settings["manage_ad_ip"]):
change_ip_address(manage_ad_port, settings["manage_ad_ip"])
if (get_computer_name(manage_ad_port) != settings["manage_ad_computername"]):
change_computer_name(manage_ad_port, settings["manage_ad_computername"])
current_address = get_dns_client_server_address(manage_ad_port)
if (current_address != settings["ad_server_ip"]):
set_dns_client_server_address(manage_ad_port, settings["ad_server_ip"])
if (not has_joined_ad_domain(manage_ad_port)):
join_domain(manage_ad_port)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment