SDVM.psm1
<#
.NOTES This contains functions for deploying various virtual machines to the virtualization infrastructure. #> Function Get-SDRebootStatus { <# .DESCRIPTION This function checks the status of a sever to determine if it has finished rebooting. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [String] $VM ) Start-Sleep -Seconds 60 while (-not(Test-Connection $VM -Count 1 -quiet)) { "Waiting for $VM to reboot" } else { "$VM is back online!" } } Function New-SDVM { <# .DESCRIPTION This Function deployes a base Windows Server 2022 OVA to the cluster and addes it to the domain if you specifiy it to. .PARAMETER addDomain This is a boolean value that is set to true for $false If set to True it will add the machine to the domain after it is deployed. By default this is false. .PARAMETER ipAddress This specifies the IP address of the VM in CIDR notation eg. (10.1.8.5/26) This is a required parameter .PARAMETER core Boolean value that specifies if the server should be deployed as a windows core server. .PARAMETER vmName String value that specifies the name for the VM .PARAMETER nonvSAN Boolean value that specifies if the VM ashould be deployed on the fixed host vs the vSAN cluster. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [Boolean] $addDomain = $false, # Parameter help description [Parameter(Mandatory = $true)] [string] $ipAddress, # Parameter help description [Parameter(Mandatory = $true)] [System.Boolean] $core = $true, # Parameter help description [Parameter(Mandatory = $true)] [string] $vmName, # Parameter help description [Parameter()] [System.Boolean] $nonvSAN = $false ) if ($nonvSAN -eq $true) { $vmHost = Get-Cluster -Name $site-FixedHosts | Get-VMHost | Where-Object { $_.ConnectionState -eq "Connected" } | Get-Random $datastore = Get-Datacenter -VMHost $vmHost | where-object { $_.Name -match "Fixed" } } elseif ($nonvSAN -eq $false) { $vmHost = Get-Cluster -Name $site-vSAN | Get-VMHost | Where-Object { $_.ConnectionState -eq "Connected" } | Get-Random $datastore = Get-Datacenter -Name $site-vSAN-Data } if ($core -eq $true) { Import-vApp –Source $global:ovas.winsrv22core -Location $vmHost -Datastore $datastore -Name $vmName -Force } else { Import-vApp –Source $global:ovas.winsrv22 -Location $vmHost -Datastore $datastore -Name $vmName -Force } } Function New-SDDCConfig { #Install roles required for Active Directory Install-windowsfeature -Name AD-Domain-Services -IncludeManagementTools #reboot sercver to complete install of roles Restart-Computer -Force #Wait For Server to come back Get-SDRebootStatus -VM $vmName #Get VM object from vmName $vm = Get-VM -Name $vmName #Create new Disk for AD 120GB New-SDNVMeDrive -vmName $vmName -Size 120 #Format disk function Format-SDDisk -vmName $vmName -label "ADDS" #Promote the Domain Controller Invoke-Command { Install-ADDSDomainController -DomainName $domainName -Credential (Get-Credential) ` -InstallDNS:$true -SysvolPath E:\SYSVOL -LogPath E:\LOGS -DatabasePath E:\AD_DB ` -SafeModeAdministratorPassword $ADSAFEPASS -SiteName $site } -ComputerName "$vmName.$domainName" #Wait For Server to come back Get-SDRebootStatus -VM $vmName $osInfo = Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName "$vmName.$domainName" if ($osInfo.ProductType -eq 2) { Write-Host "Completed DC Deployment" } elseif ($osInfo.ProductType -eq 3) { Write-Host "Deployment Failed" } } Function New-SDDHCPConfig { #Install roles required for Active Directory Install-windowsfeature -Name DHCP-Server -IncludeManagementTools #reboot sercver to complete install of roles Restart-Computer -Force #Wait For Server to come back Get-SDRebootStatus -VM $vmName Add-DhcpServerInDC -DnsName $vmName.$domainName -IPAddress $ipAddress } Function Format-SDDisk { <# .DESCRIPTION This Function Finds the new DIsk with a RAW format and Initalizes it with the GPT patition style It will then format the disk to NTFS and assign the drive label based off the input from the parameter Label. .PARAMETER vmName This is the name of the VM that this function will execut against. .PARAMETER label This is the volume label that will apply to the new disk. #> [CmdletBinding()] param ( # Name of the VM [Parameter()] [String] $vmName, # Label for the Volume [Parameter(Mandatory = $true)] [String] $label ) Invoke-Command -ScriptBlock { Get-Disk | Where-object -property partitionstyle -eq ‘raw’ | Initialize-Disk -PartitionStyle GPT -PassThru | New-Partition -DriveLetter E -UseMaximumSize | Format-Volume -FileSystem NTFS -NewFileSystemLabel $label -Confirm:$false } -ComputerName $vmName.$domainName } Function New-SDHRZN { <# .DESCRIPTION This Function configures Horizon on a Server and provisions it as either the first Server or a replica server. .PARAMETER replica This is a Boolean for determining if it is a replica. Optional Parameter default value is false .PARAMETER server Name of server to deploy horizon on. #> [CmdletBinding()] param ( [Parameter()] [System.Boolean] $replica = $false, # Server Name to deploy on [Parameter(Mandatory = $true)] [String] $server ) #Sets the Server name with the domain name $fqdn = "$server.$domainName" #Execute FIPS Check on remote server and Create Deploy Directory Invoke-Command -ScriptBlock { #Check if FIPS is ENabled on System $fipsKey = (Get-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Lsa\FipsAlgorithmPolicy\") if ($fipsKey.Enabled = 0) { #Enable FIPS Mode Set-ItemProperty -Path $fipsKey -Name "Enabled" -Value 1 } New-Item -ItemType Directory -Path C:\Deploy } -ComputerName $fqdn $hrznExe = \StackDeploy\Software\Horizon-Server-$global:sdhrznversion.exe #Copy Installer to Remote Server Copy-Item $hrznExe -Destination "\\$server.$domainName\c$\Deploy\HRZN.exe" #Install Server based if it is first or a replica if ($replica -eq $false) { #Specifies it is standard Install $instanceType = 1 #Installer Arguments $installerArgs = '/s /v' + '"/qn VDM_SERVER_INSTANCE_TYPE=' + ` $instanceType + ' VDM_INITIAL_ADMIN_SID=' + $hrznADGroupSID + ` ' VDM_IP_PROTOCOL_USAGE=IPv4 FWCHOICE=1 DEPLOYMENT_TYPE=GENERAL VDM_FIPS_ENABLED=1' #Start Installation on remote Host Invoke-Command -ScriptBlock { Start-Process C:\Deploy\HRZN.EXE -ArgumentList $installerArgs } -ComputerName $fqdn } elseif ($replica -eq $true) { #Specifies it is a Replica Install $instanceType = 2 #Installer Arguments $installerArgs = '/s /v' + '"/qn VDM_SERVER_INSTANCE_TYPE=' + ` $instanceType + ' VDM_INITIAL_ADMIN_SID=' + $hrznADGroupSID + ` ' VDM_IP_PROTOCOL_USAGE=IPv4 FWCHOICE=1 DEPLOYMENT_TYPE=GENERAL VDM_FIPS_ENABLED=1 ADAM_PRIMARY_NAME=' + "$site-HRZN-001v.$domainName" #Start Installation on remote Host Invoke-Command -ScriptBlock { Start-Process C:\Deploy\HRZN.EXE -ArgumentList $installerArgs } -ComputerName $fqdn } } Function New-SDMECM { $MECMTemplate = (Get-Content 'C:\StackDeploy\Templates\MECM_PRI.ini') $MECMTemplate[4] = $MECMTemplate[4].Replace('$MECMKey', $MECMKey) $MECMTemplate[5] = $MECMTemplate[5].Replace('$site', $site) $MECMTemplate[6] = $MECMTemplate[6].Replace('$site', $site) $MECMTemplate[8] = $MECMTemplate[8].Replace('$fqdn', $fqdn) $MECMTemplate[14] = $MECMTemplate[14].Replace('$fqdn', $fqdn) $MECMTemplate[16] = $MECMTemplate[16].Replace('$fqdn', $fqdn) $MECMTemplate[21] = $MECMTemplate[21].Replace('$fqdn', $fqdn) $MECMTemplate[24] = $MECMTemplate[24].Replace('$casfqdn', $casfqdn) $MECMTemplate[25] = $MECMTemplate[25].Replace('$site', $site) $MECMTemplate | Out-File "C:\StackDeploy\Templates\$site-mecm.ini" $sqlInstaller = 'C:\deploy\SQL\setup.exe' $sqlArgs = '/ACTION=install /QS /INSTANCENAME=MSSQLSERVER /SUPPRESSPRIVACYSTATEMENTNOTICE' + ` "/IACCEPTSQLSERVERLICENSETERMS /FEATURES=SQLENGINE /SQLSYSADMINACCOUNTS=$domainName\MECM_SQLAdmin /SQLCOLLATION=SQL_Latin1_General_CP1_CS_AS" + ` "/SQLSVCACCOUNT=$domainName\$site.msa.mecmsql" #Install SQL Invoke-Command -ScriptBlock { Start-process $sqlInstaller -ArgumentList $sqlArgs -Wait } -ComputerName $fqdn } #EXPORT MODULE MEMBERS Export-ModuleMember Get-SDRebootStatus Export-ModuleMember New-SDVM Export-ModuleMember New-SDDCConfig Export-ModuleMember New-SDDHCPConfig Export-ModuleMember Format-SDDisk Export-ModuleMember New-SDHRZN |