<# .SYNOPSIS Configure and Install RPS nodes on a local Hyper-V. .DESCRIPTION Configure and Install RPS a local Hyper-V. .PARAMETER VMTemplateFilename Path to the '.vhdx' file which will serve as the Hyper-V VHDX template used to create VMs. If just a filename or relative path, the runbook will search for file in the /images folder under root. .PARAMETER RhelTemplateFilename Path to the '.vhdx' file which will serve as the Hyper-V VHDX template used to create Rhel VMs. .PARAMETER VhdFolderPath Path to a folder to store the .vhdx files used to create VMs. .PARAMETER ConfigFilename Name of file containing the RPS Configuration data. If file does not exist, a new configuration will be created and saved at the specified location. .PARAMETER NodeType Name of RPS Node to be installed. For example: 'All', 'Root', 'NOSC', 'TCN', 'SNE' .PARAMETER ComputerName Optional array of names of VMs to install. Omitting this value will install all VMs belonging to the Node. .PARAMETER SkipVmCreation Switch to indicate that the script should skip creating VMs in HyperV. .PARAMETER SkipDscPrep Switch to indicate that the script should skip setting LCM Encryption and copying DSC Modules. .PARAMETER SkipCopyContent Switch to indicate that the script should skip copying all content to the target content host VM. .PARAMETER SkipDscModuleCopy Switch to indicate that the script should skip copying all Dsc modules to the target VM. .PARAMETER SkipDscPublish Switch to indicate that the script should not publish a new Dsc configuration. .PARAMETER DeleteVMs Switch to indicate that the script should delete existing VMs and VHDs, if they exist. .PARAMETER CopyCdn Switch to indicate that the script should copy all Cdn content to the target VM. .PARAMETER Esxi Switch to indicate whether the hypervisor is Esxi (default is Hyper-V) .PARAMETER TaskMapName The name of the task map Install-RpsNode should execute for installation. Defaulted to Install-Rps .EXAMPLE Install-Rps -VMTemplateFilename 'C:\temp\images\rpsTemplate.vhdx' .EXAMPLE Install-Rps -VMTemplateFilename 'C:\rps\images\rpsTemplate.vhdx' -ConfigFilename 'C:\rps\rps.xml' .EXAMPLE Install-Rps -VMTemplateFilename 'C:\rps\images\WindowsServer2012R2_sysprepped.vhdx' -VhdFolderPath 'D:\Rps\VirtualDisks' .EXAMPLE Install-Rps -VMTemplateFilename 'C:\rps\images\rpsTemplate.vhdx' -ConfigFilename 'C:\rps\rps.xml' -NodeType Root -RhelTemplateFileName F:\rhel.vhdx #> [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $true, ParameterSetName = 'Virtual')] [ValidateScript( { Test-Path -Path $_ })] [String] $VMTemplateFilename, [Parameter(ParameterSetName = 'Virtual')] [ValidateScript( { Test-Path -Path $_ })] [String] $RhelTemplateFileName, [Parameter(ParameterSetName = 'Virtual')] [String] $VhdFolderPath, [Parameter()] [String] $ConfigFilename, [Parameter()] [String[]] $NodeType = 'All', [Parameter()] [string[]] $ComputerName, [Parameter()] [switch] $SkipVmCreation, [Parameter()] [switch] $SkipDscPrep, [Parameter()] [switch] $SkipCopyContent, [Parameter()] [switch] $SkipDscModuleCopy, [Parameter()] [switch] $SkipDscPublish, [Parameter()] [switch] $DeleteVMs, [Parameter()] [switch] $CopyCdn, [Parameter()] [switch] $Esxi, [Parameter()] [String] $TaskMapName = 'Install-Rps' ) Begin { $Error.Clear() } Process { $Global:InformationPreference = 'Continue' # Validation $rootPath = Split-Path -Path $PSScriptRoot -Parent $currentDateTime = Get-Date -uFormat '%m.%d.%Y-%H.%M.%S' $messageTemplate = 'Saving Configuration to {0}' # Unblock everything Get-ChildItem -Path $rootPath -Recurse | Unblock-File # Remove empty entries in $env:PSModulePath to avoid issues $env:PSModulePath = $env:PSModulePath.Split(';', [System.StringSplitOptions]::RemoveEmptyEntries) -join ';' if ($env:PSModulePath.Split(';') -notcontains "$rootPath\Modules") { $env:PSModulePath = $env:PSModulePath + ";$rootPath\Modules" } if ($env:PSModulePath.Split(';') -notcontains "$rootPath\DSC\Modules") { $env:PSModulePath = $env:PSModulePath + ";$rootPath\DSC\Modules" } Import-Module -Name Rps-Api, Rps-Utilities, Rps-Dsc, Rps-Installer, Rps-Encryption, Rps-Network, Rps-Virtualization, Rps-SeedData # Run as administrator validation if (-not (Test-IsAdmin)) { throw 'Non-elevated context detected. Please re-run as Administrator.' } try { if (-not $ConfigFilename) { $configurationPath = "$rootPath\Export\RpsConfiguration_${currentDateTime}.xml" } else { $configurationPath = $ConfigFileName $messageTemplate = 'Loading existing configuration from {0}' } Enter-RpsSession -Path $configurationPath Write-RpsLogItem -Level Information -Component Install -MessageTemplate $messageTemplate -Properties $configurationPath # Import seed data if not using export from previous install if (-not $ConfigFileName) { # Import Taskmaps & $PSScriptRoot\Configuration\Import-RpsTasks.ps1 -Path $rootPath\Runbooks # Import DSC Partials Import-DscPartial -ContentStorePath $rootPath $configParams = @{} if ($PSCmdlet.ParameterSetName -eq 'Virtual') { $configParams['VMTemplateFileName'] = $VMTemplateFilename if (-not $VhdFolderPath) { $VhdFolderPath = (Get-ChildItem $VMTemplateFilename).DirectoryName } if ($RhelTemplateFileName) { $configParams['RhelTemplateFileName'] = $RhelTemplateFileName } $configParams['VhdFolderPath'] = $VhdFolderPath } # Import Rps Target and Resource Item Types & $PSScriptRoot\Configuration\Import-RpsTypes.ps1 # Generate the CMDB data as needed & $PSScriptRoot\New-RpsNodeConfiguration.ps1 @configParams } # Install Node(s) $installParams = @{ ComputerName = $ComputerName SkipVmCreation = $SkipVmCreation SkipDscPrep = $SkipDscPrep SkipCopyContent = $SkipCopyContent SkipDscModuleCopy = $SkipDscModuleCopy SkipDscPublish = $SkipDscPublish DeleteVMs = $DeleteVMs CopyCdn = $CopyCdn Esxi = $Esxi ContentStorePath = $rootPath TaskMapName = $TaskMapName VMTemplateFilename = $VMTemplateFilename VhdFolderPath = $VhdFolderPath RhelTemplateFileName = $RhelTemplateFileName } $nodes = Resolve-RpsNode -NodeType $NodeType Install-RpsNode -NodeType $nodes @installParams $completionMessage = 'Installer completed' } catch { Write-RpsLogItem -Level Error -Component Install -MessageTemplate "Unexpected error in installation process, $_" $_ | Export-Clixml -Path "$PSScriptRoot\InstallException.xml" -Depth 5 -Force throw "Unexpected error in install: $_" } finally { # Exit RPS Session and save configuration if ($completionMessage) { Write-RpsLogItem -Level Information -Component Install -MessageTemplate $completionMessage } Exit-RpsSession -Commit -ErrorAction Ignore $Global:InformationPreference = 'SilentlyContinue' } }