From 4bde98ff08f2258ce738503c48391d26d6903d72 Mon Sep 17 00:00:00 2001 From: Chris Long Date: Sat, 13 Mar 2021 20:12:24 -0800 Subject: [PATCH] Adding Exchange for Azure and ESXi --- Azure/Ansible/detectionlab.yml | 6 + Azure/Ansible/inventory.yml | 4 + Azure/Ansible/roles/exchange/tasks/main.yml | 136 ++++++++++++++++++++ Azure/Terraform/locals.tf | 1 + Azure/Terraform/main.tf | 85 ++++++++++++ Azure/Terraform/outputs.tf | 8 ++ Azure/Terraform/variables.tf | 6 + ESXi/ansible/detectionlab.yml | 6 + ESXi/ansible/inventory.yml | 3 + ESXi/ansible/roles/dc/tasks/main.yml | 2 +- ESXi/ansible/roles/exchange/tasks/main.yml | 136 ++++++++++++++++++++ ESXi/ansible/roles/wef/tasks/main.yml | 2 +- ESXi/ansible/roles/win10/tasks/main.yml | 2 +- ESXi/main.tf | 30 +++++ ESXi/outputs.tf | 8 ++ ESXi/variables.tf | 6 + Vagrant/scripts/install-exchange.ps1 | 45 ++++--- 17 files changed, 466 insertions(+), 20 deletions(-) create mode 100644 Azure/Ansible/roles/exchange/tasks/main.yml create mode 100644 ESXi/ansible/roles/exchange/tasks/main.yml diff --git a/Azure/Ansible/detectionlab.yml b/Azure/Ansible/detectionlab.yml index c6ee0d494..6b3b3cd60 100644 --- a/Azure/Ansible/detectionlab.yml +++ b/Azure/Ansible/detectionlab.yml @@ -16,3 +16,9 @@ - win10 - common tags: win10 + +- hosts: exchange + roles: + - exchange + - common + tags: exchange \ No newline at end of file diff --git a/Azure/Ansible/inventory.yml b/Azure/Ansible/inventory.yml index 6e6fdad3b..39907024a 100644 --- a/Azure/Ansible/inventory.yml +++ b/Azure/Ansible/inventory.yml @@ -12,3 +12,7 @@ win10: hosts: z.z.z.z: +#exchange: + #hosts: + #w.w.w.w: + diff --git a/Azure/Ansible/roles/exchange/tasks/main.yml b/Azure/Ansible/roles/exchange/tasks/main.yml new file mode 100644 index 000000000..634d73cfc --- /dev/null +++ b/Azure/Ansible/roles/exchange/tasks/main.yml @@ -0,0 +1,136 @@ +--- + +- name: Hostname -> EXCHANGE + win_hostname: + name: EXCHANGE + register: res + +- name: Reboot + win_reboot: + when: res.reboot_required + +- name: Set HostOnly IP Address + win_shell: "If (-not(get-netipaddress | where {$_.IPAddress -eq '192.168.38.106'})) {$adapter = (get-netadapter | where {$_.MacAddress -eq '00-50-56-A1-B4-C5'}).Name; New-NetIPAddress –InterfaceAlias $adapter –AddressFamily IPv4 -IPAddress 192.168.38.106 –PrefixLength 24 -DefaultGateway 192.168.38.1 } Else { Write-Host 'IP Address Already Created.' }" + +- name: Set HostOnly DNS Address + win_shell: "$adapter = (get-netadapter | where {$_.MacAddress -eq '00-50-56-A1-B4-C5'}).Name; Set-DnsClientServerAddress -InterfaceAlias $adapter -ServerAddresses 192.168.38.102,8.8.8.8" + +- name: Install git + win_chocolatey: + name: git + state: present + +- name: Check if existing DetectionLab directory + win_stat: + path: 'c:\DetectionLab' + register: dir + +- name: Git clone Detectionlab + win_shell: git clone https://github.com/clong/DetectionLab.git + args: + chdir: 'c:\' + when: not dir.stat.exists + +- name: Copy scripts to c:\vagrant + win_shell: Copy-Item -Recurse c:\DetectionLab\Vagrant c:\vagrant + +- name: Join the Domain + win_shell: .\\provision.ps1 + args: + chdir: 'c:\vagrant\scripts' + register: exchange_join_domain + changed_when: "'HasSucceeded : True' in exchange_join_domain.stdout" + +- debug: msg="{{ exchange_join_domain.stdout_lines }}" + +- name: Reboot After Joining the Domain + win_reboot: + msg: "Joining the domain. Rebooting..." + pre_reboot_delay: 5 + reboot_timeout: 600 + post_reboot_delay: 60 + +- name: Install Exchange Prereqs + win_shell: .\\install-exchange.ps1 + args: + chdir: 'c:\vagrant\scripts' + register: exchange_prereqs + changed_when: "'A reboot is required to continue installation of exchange.' in exchange_prereqs.stdout" + +- name: Reboot After Installing Exchange PreReqs + win_reboot: + msg: "Exchange Prereqs installed. Rebooting..." + pre_reboot_delay: 5 + reboot_timeout: 600 + post_reboot_delay: 60 + +- name: Download Exchange ISO and Mount It + win_shell: .\\install-exchange.ps1 + args: + chdir: 'c:\vagrant\scripts' + register: download_exchange_iso + +- name: Prepare Schema + win_package: + path: E:\Setup.exe + arguments: >- + /IAcceptExchangeServerLicenseTerms + /PrepareSchema + product_id: '{CD981244-E9B8-405A-9026-6AEB9DCEF1F1}' + vars: + ansible_become: yes + ansible_become_method: runas + ansible_become_user: WINDOMAIN.local\Administrator + ansible_become_password: vagrant + register: prepare_schema + changed_when: "prepare_schema.rc == 0" + +- name: Prepare AD + win_package: + path: E:\Setup.exe + arguments: >- + /IAcceptExchangeServerLicenseTerms + /PrepareAD + /OrganizationName: DetectionLab + product_id: '{CD981244-E9B8-405A-9026-6AEB9DCEF1F1}' + vars: + ansible_become: yes + ansible_become_method: runas + ansible_become_user: WINDOMAIN.local\Administrator + ansible_become_password: vagrant + register: prepare_ad + changed_when: "prepare_ad.rc == 0" + +- name: Install Exchange + win_package: + path: E:\Setup.exe + arguments: >- + /IAcceptExchangeServerLicenseTerms + /Mode:Install + /Role:Mailbox + product_id: '{CD981244-E9B8-405A-9026-6AEB9DCEF1F1}' + vars: + ansible_become: yes + ansible_become_method: runas + ansible_become_user: WINDOMAIN.local\Administrator + ansible_become_password: vagrant + register: install_exchange + changed_when: "install_exchange.rc == 0" + +- name: Reboot after Exchange Installation + win_reboot: + msg: "Exchange installed. Rebooting..." + pre_reboot_delay: 5 + reboot_timeout: 600 + post_reboot_delay: 60 + +- name: Clear Event Logs + win_shell: "wevtutil el | Select-String -notmatch \"Microsoft-Windows-LiveId\" | Foreach-Object {wevtutil cl \"$_\"}" + +- name: Configure EXCHANGE with raw Commands + win_shell: "{{ item }}" + with_items: + - "wevtutil el | Select-String -notmatch \"Microsoft-Windows-LiveId\" | Foreach-Object {wevtutil cl \"$_\"}" + - "Set-SmbServerConfiguration -AuditSmb1Access $true -Force" + + diff --git a/Azure/Terraform/locals.tf b/Azure/Terraform/locals.tf index d6b5ebc10..90bed8aef 100644 --- a/Azure/Terraform/locals.tf +++ b/Azure/Terraform/locals.tf @@ -4,4 +4,5 @@ locals { ata_url = "https://${azurerm_public_ip.wef-publicip.ip_address}" guacamole_url = "http://${azurerm_public_ip.logger-publicip.ip_address}:8080/guacamole" velociraptor_url = "https://${azurerm_public_ip.logger-publicip.ip_address}:9999" + exchange_url = "https://${azurerm_public_ip.exchange-publicip.ip_address}" } diff --git a/Azure/Terraform/main.tf b/Azure/Terraform/main.tf index 1d0f9cce0..d08e74984 100644 --- a/Azure/Terraform/main.tf +++ b/Azure/Terraform/main.tf @@ -366,6 +366,33 @@ resource "azurerm_public_ip" "win10-publicip" { } } +resource "azurerm_network_interface" "exchange-nic" { + count = var.create_exchange_server ? 1 : 0 + name = "exchange-nic" + location = var.region + resource_group_name = azurerm_resource_group.detectionlab.name + + ip_configuration { + name = "myNicConfiguration" + subnet_id = azurerm_subnet.detectionlab-subnet.id + private_ip_address_allocation = "Static" + private_ip_address = "192.168.38.106" + public_ip_address_id = azurerm_public_ip.exchange-publicip.id + } +} + +resource "azurerm_public_ip" "exchange-publicip" { + count = var.create_exchange_server ? 1 : 0 + name = "exchange-public-ip" + location = var.region + resource_group_name = azurerm_resource_group.detectionlab.name + allocation_method = "Static" + + tags = { + role = "exchange" + } +} + resource "azurerm_virtual_machine" "dc" { name = "dc.windomain.local" location = var.region @@ -479,6 +506,64 @@ resource "azurerm_virtual_machine" "wef" { } } +resource "azurerm_virtual_machine" "exchange" { + count = var.create_exchange_server ? 1 : 0 + name = "exchange.windomain.local" + location = var.region + resource_group_name = azurerm_resource_group.detectionlab.name + network_interface_ids = [azurerm_network_interface.exchange-nic.id] + vm_size = "Standard_D3_v2" + + delete_os_disk_on_termination = true + + storage_image_reference { + publisher = "MicrosoftWindowsServer" + offer = "WindowsServer" + sku = "2016-Datacenter" + version = "latest" + } + + os_profile { + computer_name = "exchange" + admin_username = "vagrant" + admin_password = "Vagrant123" + custom_data = local.custom_data_content + } + + os_profile_windows_config { + provision_vm_agent = true + enable_automatic_upgrades = false + + # Auto-Login's required to configure WinRM + additional_unattend_config { + pass = "oobeSystem" + component = "Microsoft-Windows-Shell-Setup" + setting_name = "AutoLogon" + content = "Vagrant123true1vagrant" + } + + # Unattend config is to enable basic auth in WinRM, required for the provisioner stage. + # https://github.com/terraform-providers/terraform-provider-azurerm/blob/master/examples/virtual-machines/provisioners/windows/files/FirstLogonCommands.xml + additional_unattend_config { + pass = "oobeSystem" + component = "Microsoft-Windows-Shell-Setup" + setting_name = "FirstLogonCommands" + content = file("${path.module}/files/FirstLogonCommands.xml") + } + } + + storage_os_disk { + name = "OsDiskWef" + caching = "ReadWrite" + create_option = "FromImage" + managed_disk_type = "Standard_LRS" + } + + tags = { + role = "exchange" + } +} + resource "azurerm_virtual_machine" "win10" { name = "win10.windomain.local" location = var.region diff --git a/Azure/Terraform/outputs.tf b/Azure/Terraform/outputs.tf index d7b5b388e..8a0a4170b 100644 --- a/Azure/Terraform/outputs.tf +++ b/Azure/Terraform/outputs.tf @@ -18,6 +18,10 @@ output "win10_public_ip" { value = azurerm_public_ip.win10-publicip.ip_address } +output "exchange_public_ip" { + value = azurerm_public_ip.exchange-publicip.ip_address +} + output "ata_url" { value = local.ata_url } @@ -37,3 +41,7 @@ output "guacamole_url" { output "velociraptor_url" { value = local.velociraptor_url } + +output "exchange_url" { + value = local.velociraptor_url +} \ No newline at end of file diff --git a/Azure/Terraform/variables.tf b/Azure/Terraform/variables.tf index 9cdfe4d07..b07dee09a 100644 --- a/Azure/Terraform/variables.tf +++ b/Azure/Terraform/variables.tf @@ -39,4 +39,10 @@ variable "external_dns_servers" { description = "Configure lab to allow external DNS resolution" type = list(string) default = ["8.8.8.8"] +} + +variable "create_exchange_server" { + description = "If set to true, adds an additional host that installs exchange" + type = bool + default = false } \ No newline at end of file diff --git a/ESXi/ansible/detectionlab.yml b/ESXi/ansible/detectionlab.yml index 4323bcfe3..6146eaf21 100644 --- a/ESXi/ansible/detectionlab.yml +++ b/ESXi/ansible/detectionlab.yml @@ -21,3 +21,9 @@ - win10 - common tags: win10 + +- hosts: exchange + roles: + - exchange + - common + tags: exchange diff --git a/ESXi/ansible/inventory.yml b/ESXi/ansible/inventory.yml index 46f3205ef..c61f3bd11 100644 --- a/ESXi/ansible/inventory.yml +++ b/ESXi/ansible/inventory.yml @@ -21,3 +21,6 @@ win10: hosts: 192.168.3.204: +exchange: + hosts: + 192.168.3.206: diff --git a/ESXi/ansible/roles/dc/tasks/main.yml b/ESXi/ansible/roles/dc/tasks/main.yml index 1578cc565..752b17228 100644 --- a/ESXi/ansible/roles/dc/tasks/main.yml +++ b/ESXi/ansible/roles/dc/tasks/main.yml @@ -10,7 +10,7 @@ when: res.reboot_required - name: Set HostOnly IP Address - win_shell: "$adapter = (get-netadapter | where {$_.MacAddress -eq '00-50-56-A1-B1-C4'}).Name; New-NetIPAddress –InterfaceAlias $adapter –AddressFamily IPv4 -IPAddress 192.168.38.102 –PrefixLength 24 -DefaultGateway 192.168.38.1" + win_shell: "If (-not(get-netipaddress | where {$_.IPAddress -eq '192.168.38.102'})) {$adapter = (get-netadapter | where {$_.MacAddress -eq '00-50-56-A1-B1-C4'}).Name; New-NetIPAddress –InterfaceAlias $adapter –AddressFamily IPv4 -IPAddress 192.168.38.102 –PrefixLength 24 -DefaultGateway 192.168.38.1 } Else { Write-Host 'IP Address Already Created.' }" - name: Set DNS Address win_shell: "$adapter = (get-netadapter | where {$_.MacAddress -eq '00-50-56-A1-B1-C4'}).Name; Set-DnsClientServerAddress -InterfaceAlias $adapter -ServerAddresses 127.0.0.1,8.8.8.8" diff --git a/ESXi/ansible/roles/exchange/tasks/main.yml b/ESXi/ansible/roles/exchange/tasks/main.yml new file mode 100644 index 000000000..634d73cfc --- /dev/null +++ b/ESXi/ansible/roles/exchange/tasks/main.yml @@ -0,0 +1,136 @@ +--- + +- name: Hostname -> EXCHANGE + win_hostname: + name: EXCHANGE + register: res + +- name: Reboot + win_reboot: + when: res.reboot_required + +- name: Set HostOnly IP Address + win_shell: "If (-not(get-netipaddress | where {$_.IPAddress -eq '192.168.38.106'})) {$adapter = (get-netadapter | where {$_.MacAddress -eq '00-50-56-A1-B4-C5'}).Name; New-NetIPAddress –InterfaceAlias $adapter –AddressFamily IPv4 -IPAddress 192.168.38.106 –PrefixLength 24 -DefaultGateway 192.168.38.1 } Else { Write-Host 'IP Address Already Created.' }" + +- name: Set HostOnly DNS Address + win_shell: "$adapter = (get-netadapter | where {$_.MacAddress -eq '00-50-56-A1-B4-C5'}).Name; Set-DnsClientServerAddress -InterfaceAlias $adapter -ServerAddresses 192.168.38.102,8.8.8.8" + +- name: Install git + win_chocolatey: + name: git + state: present + +- name: Check if existing DetectionLab directory + win_stat: + path: 'c:\DetectionLab' + register: dir + +- name: Git clone Detectionlab + win_shell: git clone https://github.com/clong/DetectionLab.git + args: + chdir: 'c:\' + when: not dir.stat.exists + +- name: Copy scripts to c:\vagrant + win_shell: Copy-Item -Recurse c:\DetectionLab\Vagrant c:\vagrant + +- name: Join the Domain + win_shell: .\\provision.ps1 + args: + chdir: 'c:\vagrant\scripts' + register: exchange_join_domain + changed_when: "'HasSucceeded : True' in exchange_join_domain.stdout" + +- debug: msg="{{ exchange_join_domain.stdout_lines }}" + +- name: Reboot After Joining the Domain + win_reboot: + msg: "Joining the domain. Rebooting..." + pre_reboot_delay: 5 + reboot_timeout: 600 + post_reboot_delay: 60 + +- name: Install Exchange Prereqs + win_shell: .\\install-exchange.ps1 + args: + chdir: 'c:\vagrant\scripts' + register: exchange_prereqs + changed_when: "'A reboot is required to continue installation of exchange.' in exchange_prereqs.stdout" + +- name: Reboot After Installing Exchange PreReqs + win_reboot: + msg: "Exchange Prereqs installed. Rebooting..." + pre_reboot_delay: 5 + reboot_timeout: 600 + post_reboot_delay: 60 + +- name: Download Exchange ISO and Mount It + win_shell: .\\install-exchange.ps1 + args: + chdir: 'c:\vagrant\scripts' + register: download_exchange_iso + +- name: Prepare Schema + win_package: + path: E:\Setup.exe + arguments: >- + /IAcceptExchangeServerLicenseTerms + /PrepareSchema + product_id: '{CD981244-E9B8-405A-9026-6AEB9DCEF1F1}' + vars: + ansible_become: yes + ansible_become_method: runas + ansible_become_user: WINDOMAIN.local\Administrator + ansible_become_password: vagrant + register: prepare_schema + changed_when: "prepare_schema.rc == 0" + +- name: Prepare AD + win_package: + path: E:\Setup.exe + arguments: >- + /IAcceptExchangeServerLicenseTerms + /PrepareAD + /OrganizationName: DetectionLab + product_id: '{CD981244-E9B8-405A-9026-6AEB9DCEF1F1}' + vars: + ansible_become: yes + ansible_become_method: runas + ansible_become_user: WINDOMAIN.local\Administrator + ansible_become_password: vagrant + register: prepare_ad + changed_when: "prepare_ad.rc == 0" + +- name: Install Exchange + win_package: + path: E:\Setup.exe + arguments: >- + /IAcceptExchangeServerLicenseTerms + /Mode:Install + /Role:Mailbox + product_id: '{CD981244-E9B8-405A-9026-6AEB9DCEF1F1}' + vars: + ansible_become: yes + ansible_become_method: runas + ansible_become_user: WINDOMAIN.local\Administrator + ansible_become_password: vagrant + register: install_exchange + changed_when: "install_exchange.rc == 0" + +- name: Reboot after Exchange Installation + win_reboot: + msg: "Exchange installed. Rebooting..." + pre_reboot_delay: 5 + reboot_timeout: 600 + post_reboot_delay: 60 + +- name: Clear Event Logs + win_shell: "wevtutil el | Select-String -notmatch \"Microsoft-Windows-LiveId\" | Foreach-Object {wevtutil cl \"$_\"}" + +- name: Configure EXCHANGE with raw Commands + win_shell: "{{ item }}" + with_items: + - "wevtutil el | Select-String -notmatch \"Microsoft-Windows-LiveId\" | Foreach-Object {wevtutil cl \"$_\"}" + - "Set-SmbServerConfiguration -AuditSmb1Access $true -Force" + + diff --git a/ESXi/ansible/roles/wef/tasks/main.yml b/ESXi/ansible/roles/wef/tasks/main.yml index 287318ee1..9592e646b 100644 --- a/ESXi/ansible/roles/wef/tasks/main.yml +++ b/ESXi/ansible/roles/wef/tasks/main.yml @@ -11,7 +11,7 @@ # This needs to be made idempodent - name: Set HostOnly IP Address - win_shell: "$adapter = (get-netadapter | where {$_.MacAddress -eq '00-50-56-A1-B4-C4'}).Name; New-NetIPAddress –InterfaceAlias $adapter –AddressFamily IPv4 -IPAddress 192.168.38.103 –PrefixLength 24 -DefaultGateway 192.168.38.1" + win_shell: "If (-not(get-netipaddress | where {$_.IPAddress -eq '192.168.38.103'})) {$adapter = (get-netadapter | where {$_.MacAddress -eq '00-50-56-A1-B4-C4'}).Name; New-NetIPAddress –InterfaceAlias $adapter –AddressFamily IPv4 -IPAddress 192.168.38.103 –PrefixLength 24 -DefaultGateway 192.168.38.1 } Else { Write-Host 'IP Address Already Created.' }" # This needs to be made idempodent - name: Set HostOnly DNS Address diff --git a/ESXi/ansible/roles/win10/tasks/main.yml b/ESXi/ansible/roles/win10/tasks/main.yml index 0cd704a98..8c4948e3e 100644 --- a/ESXi/ansible/roles/win10/tasks/main.yml +++ b/ESXi/ansible/roles/win10/tasks/main.yml @@ -10,7 +10,7 @@ when: res.reboot_required - name: Set HostOnly IP Address - win_shell: "$adapter = (get-netadapter | where {$_.MacAddress -eq '00-50-56-A2-B1-C4'}).Name; New-NetIPAddress –InterfaceAlias $adapter –AddressFamily IPv4 -IPAddress 192.168.38.104 –PrefixLength 24 -DefaultGateway 192.168.38.1" + win_shell: "If (-not(get-netipaddress | where {$_.IPAddress -eq '192.168.38.104'})) {$adapter = (get-netadapter | where {$_.MacAddress -eq '00-50-56-A2-B1-C4'}).Name; New-NetIPAddress –InterfaceAlias $adapter –AddressFamily IPv4 -IPAddress 192.168.38.104 –PrefixLength 24 -DefaultGateway 192.168.38.1 } Else { Write-Host 'IP Address Already Created.' }" - name: Set HostOnly DNS Address win_shell: "$adapter = (get-netadapter | where {$_.MacAddress -eq '00-50-56-A2-B1-C4'}).Name; Set-DnsClientServerAddress -InterfaceAlias $adapter -ServerAddresses 192.168.38.102,8.8.8.8" diff --git a/ESXi/main.tf b/ESXi/main.tf index 215a93e2f..60b2b55f9 100644 --- a/ESXi/main.tf +++ b/ESXi/main.tf @@ -121,6 +121,36 @@ resource "esxi_guest" "wef" { guest_shutdown_timeout = 30 } +resource "esxi_guest" "exchange" { + # See https://blog.gruntwork.io/terraform-tips-tricks-loops-if-statements-and-gotchas-f739bbae55f9#0223 for explanation about count + count = var.create_exchange_server ? 1 : 0 + guest_name = "exchange" + disk_store = var.esxi_datastore + guestos = "windows9srv-64" + + boot_disk_type = "thin" + + memsize = "8192" + numvcpus = "4" + resource_pool_name = "/" + power = "on" + clone_from_vm = "WindowsServer2016" + # This is the network that bridges your host machine with the ESXi VM + network_interfaces { + virtual_network = var.vm_network + mac_address = "00:50:56:a1:b2:c5" + nic_type = "e1000" + } + # This is the local network that will be used for 192.168.38.x addressing + network_interfaces { + virtual_network = var.hostonly_network + mac_address = "00:50:56:a1:b4:c5" + nic_type = "e1000" + } + guest_startup_timeout = 45 + guest_shutdown_timeout = 30 +} + resource "esxi_guest" "win10" { guest_name = "win10" disk_store = var.esxi_datastore diff --git a/ESXi/outputs.tf b/ESXi/outputs.tf index 1ed51db1c..4012c94db 100644 --- a/ESXi/outputs.tf +++ b/ESXi/outputs.tf @@ -22,6 +22,14 @@ output "wef_ips" { value = esxi_guest.wef.ip_address } +output "exchange_interfaces" { + value = esxi_guest.exchange.network_interfaces +} + +output "exchange_ips" { + value = esxi_guest.exchange.ip_address +} + output "win10_interfaces" { value = esxi_guest.win10.network_interfaces } diff --git a/ESXi/variables.tf b/ESXi/variables.tf index 052bc0761..f4ad7c0b9 100644 --- a/ESXi/variables.tf +++ b/ESXi/variables.tf @@ -30,3 +30,9 @@ variable "vm_network" { variable "hostonly_network" { default = "HostOnly Network" } + +variable "create_exchange_server" { + description = "If set to true, adds an additional host that installs exchange" + type = bool + default = false +} diff --git a/Vagrant/scripts/install-exchange.ps1 b/Vagrant/scripts/install-exchange.ps1 index 0b5ff5d36..1f999237a 100644 --- a/Vagrant/scripts/install-exchange.ps1 +++ b/Vagrant/scripts/install-exchange.ps1 @@ -28,8 +28,8 @@ Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) [+] Attempting to install Microsoft e Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) [+] Please note, you will have to reboot and re-run this script after the prerequisites have been installed." Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) [+] Failure to reboot will cause the Exchange installation to fail." -# Warn the user if less than 4GB of memory -If ($physicalMemory -lt 4000000000) { +# Warn the user if less than 8GB of memory +If ($physicalMemory -lt 8000000000) { Write-Host "It is STRONGLY recommended that you provide this host with 4GB+ of memory before continuing or it is highly likely that it will run out of memory while installing Exchange." $ignore = Read-Host "Type 'ignore' to continue anyways, otherwise this script will exit." If ($ignore -ne "ignore") { @@ -153,19 +153,18 @@ If (-not(Test-Path c:\exchange_prereqs_complete.txt)) { # Create a file so this script knows to skip pre-req installation upon next run. New-Item -Path "c:\exchange_prereqs_complete.txt" -ItemType "file" Write-Host "A reboot is required to continue installation of exchange." - $reboot = Read-Host "Would you like to reboot now? [y/n]" - If ($reboot -eq "y") { - Write-Host "Rebooting in 3 seconds..." - Start-Sleep -Seconds 3 - shutdown /r /t 1 - exit - } Else { - Write-Host "Okay, exiting." - exit - } + # $reboot = Read-Host "Would you like to reboot now? [y/n]" + # If ($reboot -eq "y") { + # Write-Host "Rebooting in 3 seconds..." + # Start-Sleep -Seconds 3 + # shutdown /r /t 1 + # exit + # } Else { + # Write-Host "Okay, exiting." + # exit + # } } Else { Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) It appears the Exchange prerequisites have been installed already. Continuing installation..." - Remove-Item "c:\exchange_prereqs_complete.txt" -Force } If (-not (Test-Path $exchangeFolder)) { @@ -174,7 +173,7 @@ If (-not (Test-Path $exchangeFolder)) { Set-Location -Path $exchangeFolder -# Download and install Exchange +# Download Exchange ISO and mount it $ProgressPreference = 'SilentlyContinue' If (-not (Test-Path $exchangeISOPath)) { Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Downloading the Exchange 2016 ISO..." @@ -184,10 +183,22 @@ If (-not (Test-Path $exchangeISOPath)) { } If (-not (Test-Path "E:\Setup.EXE")) { Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Mounting the Exchange 2016 ISO..." - Mount-DiskImage -ImagePath $exchangeISOPath + if (Mount-DiskImage -ImagePath $exchangeISOPath) { + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) ISO mounted successfully." + } +} Else { + Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) The Exchange ISO was already mounted. Moving On." } -If (Test-Path "E:\Setup.exe") { +################################### +## DEBUGGING STUFF ## +################################### +## Probably a good idea to add some code to see if this script is being run manually or by ansible or not +## Or maybe just split this into two separate scripts - prereq install + exchange install +# (Get-CimInstance win32_process -Filter "ProcessID=$PID" | ? { $_.processname -eq "pwsh.exe" }) | select commandline +# https://stackoverflow.com/questions/9738535/powershell-test-for-noninteractive-mode + +<# If (Test-Path "E:\Setup.exe") { Start-Process cmd.exe -ArgumentList "/k", "e:\setup.exe", "/PrepareSchema", "/IAcceptExchangeServerLicenseTerms" -Credential $credential -Wait Start-Process cmd.exe -ArgumentList "/k", "e:\setup.exe", "/PrepareAD", "/OrganizationName:`"Detection Lab`"", "/IAcceptExchangeServerLicenseTerms" -Credential $credential -Wait Start-Process cmd.exe -ArgumentList "/k", "e:\setup.exe", "/Mode:Install", "/Role:Mailbox", "/IAcceptExchangeServerLicenseTerms" -Credential $credential -Wait @@ -195,5 +206,5 @@ If (Test-Path "E:\Setup.exe") { Else { Write-Host "$('[{0:HH:mm}]' -f (Get-Date)) Something went wrong downloading or mounting the ISO..." } - + #>