├── Create-Lab-Public.ps1 ├── Enable-PowerCLI.ps1 ├── LICENSE ├── README.md └── yggdrasil.json /Create-Lab-Public.ps1: -------------------------------------------------------------------------------- 1 | #region Start 2 | $credentials = "$($env:USERPROFILE)\ravello-credentials.csv" 3 | 4 | $obj = Import-Csv -Path $credentials -UseCulture 5 | $sPswd = ConvertTo-SecureString -String $obj.Pswd -AsPlainText -Force 6 | $cred = New-Object System.Management.Automation.PSCredential ($obj.User, $sPswd) 7 | 8 | $sConn = @{ 9 | Credential = $cred 10 | } 11 | $connect = Connect-Ravello @sConn 12 | #endregion 13 | 14 | #region Payload 15 | $lab = Get-Content yggdrasil.json | Out-String | ConvertFrom-Json 16 | 17 | Write-Host "`r`r" 18 | Get-Date -Format 'hh:mm:ss' 19 | 20 | # Upload ISOs 21 | $lab.ISO | %{ 22 | if(!(Get-RavelloDiskImage -DiskImageName $_.Filename)) 23 | { 24 | Import-Ravello -IsoPath "$($_.Path,$_.Filename -join '\')" -Confirm:$false 25 | $doc = "**$($_.Label)**: uploaded $(Get-Date -Format 'yyyyMMdd-hhmm') by $($env:USERNAME) from $($env:COMPUTERNAME)" 26 | Get-RavelloDiskImage -DiskImageName $_.Filename | New-RavelloDiskImageDocumentation -Documentation $doc -Confirm:$false 27 | } 28 | } 29 | 30 | # Create the Application 31 | $lab.Lab | %{ 32 | $app = Get-RavelloApplication -ApplicationName $_.LabName 33 | 34 | # Remove previous instance when Force 35 | if($app -and [Convert]::ToBoolean($_.Force)) 36 | { 37 | Remove-RavelloApplication -ApplicationId $app.id -Confirm:$false 38 | $app = $null 39 | Write-Host 'Removed previous instance of application ' -NoNewline 40 | Write-Host -ForegroundColor Green "$($_.LabName)" 41 | } 42 | 43 | if(!$app) 44 | { 45 | Write-Host 'Creating Application ' -NoNewline 46 | Write-Host -ForegroundColor Green "$($_.LabName)" 47 | 48 | $order = @() 49 | $sApp = @{ 50 | ApplicationName = $_.LabName 51 | Description = $_.LabDescription 52 | Confirm = $false 53 | } 54 | $doc = "**$($_.Labname)**: created on $(Get-Date -Format 'yyyyMMdd-hhmm') by $($env:USERNAME) from $($env:COMPUTERNAME)`r" 55 | 56 | # Create Application and add Documentation 57 | $app = New-RavelloApplication @sApp 58 | $app | New-RavelloApplicationDocumentation -Documentation $doc -Confirm:$false | Out-Null 59 | 60 | # Add the VMs 61 | $lab.VM | where{$_.LabName -eq $app.name} | %{ 62 | Write-Host "`tAdding VM $($_.VmName)..." -NoNewline 63 | $sAddVm = @{ 64 | ApplicationId = $app.id 65 | ImageName = $_.Image 66 | NewVmName = $_.VmName 67 | NewVmDescription = $_.VmDescription 68 | Confirm = $false 69 | } 70 | $newLine = "- **$($_.VmName)**: added to $($app.name) from $($_.Image)" + 71 | " on $(Get-Date -Format 'yyyyMMdd-hhmm') by $($env:USERNAME) from $($env:COMPUTERNAME)" 72 | $doc = (Get-RavelloApplicationDocumentation -ApplicationId $app.id) + "`r$($newLine)" 73 | Add-RavelloApplicationVm @sAddVm | Set-RavelloApplicationDocumentation -Documentation $doc -Confirm:$false | Out-Null 74 | 75 | # Adjust VM 76 | if($_.NumCpu -or $_.MemorySize -or $_.Hostname) 77 | { 78 | $sVM = @{ 79 | ApplicationId = $app.id 80 | VmName = $_.VmName 81 | Confirm = $false 82 | } 83 | if($_.NumCpu) 84 | { 85 | $sVM.Add('NumCpu',$_.NumCpu) 86 | } 87 | if($_.MemorySize) 88 | { 89 | $sVM.Add('MemorySize',$_.MemorySize) 90 | $sVM.Add('MemorySizeUnit',$_.MemoryUnit) 91 | } 92 | if($_.Hostname) 93 | { 94 | $sVM.Add('Hostnames',$_.Hostname) 95 | } 96 | Set-RavelloApplicationVm @sVM | Out-Null 97 | } 98 | 99 | # Additional HD on VM 100 | if($_.HD) 101 | { 102 | foreach($hd in $_.HD){ 103 | $sVM = @{ 104 | ApplicationId = $app.id 105 | VmName = $_.VmName 106 | Confirm = $false 107 | DiskSize = $hd.HDSize 108 | DiskSizeUnit = $hd.HDUnit 109 | } 110 | Set-RavelloApplicationVmDisk @sVM | Out-Null 111 | } 112 | } 113 | 114 | # Add/Remove Services 115 | if($_.RDP -or $_.SSH) 116 | { 117 | $sVM = @{ 118 | ApplicationId = $app.id 119 | VmName = $_.VmName 120 | Confirm = $false 121 | } 122 | if($_.RDP) 123 | {$sVM.Add('Rdp',[Convert]::ToBoolean($_.RDP))} 124 | if($_.SSH) 125 | {$sVM.Add('Ssh',[Convert]::ToBoolean($_.SSH))} 126 | Set-RavelloApplicationVmService @sVM | Out-Null 127 | } 128 | 129 | # Connect the ISO 130 | $sIso = @{ 131 | ApplicationId = $app.id 132 | VmName = $_.VmName 133 | DiskImageName = &{ 134 | foreach($iso in $lab.ISO){ 135 | if($iso.Label -eq $_.ISO){$iso.FileName} 136 | }} 137 | Confirm = $false 138 | } 139 | Set-RavelloApplicationVmIso @sIso | Out-Null 140 | 141 | # Add to Order table 142 | $order += New-Object PSObject -Property @{ 143 | Group = $_.Order 144 | VM = $_.VmName 145 | Delay = $_.OrderDelay 146 | } 147 | 148 | Write-Host -ForegroundColor Green 'done!' 149 | } 150 | 151 | # Publish the Application 152 | if(!(Test-RavelloApplicationPublished -ApplicationName $_.Labname)) 153 | { 154 | Publish-RavelloApplication -ApplicationName $_.Labname -OptimizationLevel PERFORMANCE_OPTIMIZED -Confirm:$false | Out-Null 155 | } 156 | 157 | # Set the start order 158 | $order = $order | Group-Object -Property Group | Sort-Object -Property Name | %{ 159 | New-Object PSObject -Property @{ 160 | Name = "Group$($_.Group[0].Group)" 161 | DelaySeconds = $_.Group[0].Delay 162 | VM = $_.Group | Select-Object -ExpandProperty VM 163 | } 164 | } 165 | New-RavelloApplicationOrderGroup -ApplicationId $app.id -StartOrder $order | Out-Null 166 | Write-Host 'Done' 167 | } 168 | else 169 | { 170 | # Warning when no Force 171 | Write-Host 'Application ' -NoNewline 172 | Write-Host -ForegroundColor Green "$($_.LabName)" -NoNewline 173 | Write-Host ' already exists.' 174 | Write-Host 'Use the ' -NoNewline 175 | Write-Host -ForegroundColor Red 'Force' -NoNewline 176 | Write-Host ' option to overwrite!' 177 | } 178 | } 179 | 180 | Get-Date -Format 'hh:mm:ss' 181 | #endregion 182 | 183 | #region Stop 184 | Disconnect-Ravello -Confirm:$false 185 | #endregion 186 | -------------------------------------------------------------------------------- /Enable-PowerCLI.ps1: -------------------------------------------------------------------------------- 1 | <#PSScriptInfo 2 | .DESCRIPTION 3 | Autoloader script for VMware PowerCLI 4 | .VERSION 5 | 1.0.0 6 | .GUID 7 | 47bef1e2-4587-449b-a336-64c42979c9cc 8 | .AUTHOR 9 | Luc Dekens @LucD22 10 | .TAGS 11 | VMware PowerCLI 12 | .PROJECTURI 13 | https://github.com/lucdekens/Scripts/blob/master/Enable-PowerCLI.ps1 14 | #> 15 | 16 | Function Enable-PowerCLI{ 17 | <# 18 | .SYNOPSIS 19 | Load PowerCLI modules and PSSnapins 20 | .DESCRIPTION 21 | This function will load all requested PowerCLI 22 | modules and PSSnapins. 23 | The function will, depending on the installed PowerCLI version, 24 | determine what needs to be loaded. 25 | .NOTES 26 | Author: Luc Dekens 27 | .PARAMETER Cloud 28 | Switch to indicate if the Cloud related cmdlets shall be loaded 29 | .PARAMETER InitScript 30 | The PowerCLI PSSnapin have associated initialisation scripts. 31 | This switch will indicate if that script needs to be executed or not. 32 | .EXAMPLE 33 | PS> Enable-PowerCLI 34 | .EXAMPLE 35 | PS> Enable-PowerCLI -Cloud 36 | #> 37 | 38 | [CmdletBinding()] 39 | param( 40 | [Switch]$Cloud, 41 | [Switch]$InitScript 42 | ) 43 | 44 | $PcliPssnapin = @{ 45 | 'VMware.VimAutomation.License' = @(2548067) 46 | 'VMware.DeployAutomation' =@(2548067,3056836,3205540,3737840) 47 | 'VMware.ImageBuilder' = @(2548067,3056836,3205540,3737840) 48 | } 49 | 50 | $PcliModule = @{ 51 | 'VMware.VimAutomation.Core' = @(2548067,3056836,3205540,3737840) 52 | 'VMware.VimAutomation.Vds' = @(2548067,3056836,3205540,3737840) 53 | 'VMware.VimAutomation.Cloud' = @(2548067,3056836,3205540,3737840) 54 | 'VMware.VimAutomation.PCloud' = @(2548067,3056836,3205540,3737840) 55 | 'VMware.VimAutomation.Cis.Core' = @(2548067,3056836,3205540,3737840) 56 | 'VMware.VimAutomation.Storage' = @(2548067,3056836,3205540,3737840) 57 | 'VMware.VimAutomation.HA' = @(2548067,3056836,3205540,3737840) 58 | 'VMware.VimAutomation.vROps' = @(3056836,3205540,3737840) 59 | 'VMware.VumAutomation' = @(3056836,3205540,3737840) 60 | 'VMware.VimAutomation.License' = @(3056836,3205540,3737840) 61 | } 62 | 63 | # 32- or 64-bit process 64 | $procArch = (Get-Process -Id $pid).StartInfo.EnvironmentVariables["PROCESSOR_ARCHITECTURE"] 65 | if($procArch -eq 'x86'){ 66 | $regPath = 'HKLM:\Software\VMware, Inc.\VMware vSphere PowerCLI' 67 | } 68 | else{ 69 | $regPath = 'HKLM:\Software\WOW6432Node\VMware, Inc.\VMware vSphere PowerCLI' 70 | } 71 | 72 | # Check if PowerCLI (regular or Tenant) is installed 73 | if(!(Test-Path -Path $regPath)) 74 | { 75 | $regPath = $regPath.Replace('VMware vSphere PowerCLI','VMware vSphere PowerCLI for Tenants') 76 | if(!(Test-Path -Path $regPath)) 77 | { 78 | Throw 'Can not find a PowerCLI installation!' 79 | } 80 | } 81 | 82 | # Get build 83 | $buildKey = 'InstalledBuild' 84 | Try{ 85 | $pcliBuild = Get-ItemProperty -Path $regPath -Name $buildKey | 86 | Select -ExpandProperty $buildKey -ErrorAction Stop 87 | } 88 | Catch{ 89 | Throw "PowerCLI doesn't seem to be installed on this system!" 90 | } 91 | 92 | # Get installation path 93 | $installPathKey = 'InstallPath' 94 | Try{ 95 | $pcliInstallPath = Get-ItemProperty -Path $regPath -Name $installPathKey | 96 | Select -ExpandProperty $installPathKey -ErrorAction Stop 97 | } 98 | Catch{ 99 | Throw "PowerCLI doesn't seem to be installed on this system!" 100 | } 101 | 102 | # Load modules 103 | if($pcliBuild -ge 2548067) 104 | { 105 | $loadedModule = Get-Module -Name VMware* -ErrorAction SilentlyContinue | %{$_.Name} 106 | if($loadedModule -and $pcliBuild -ge 3737840) 107 | { 108 | $loadedModule = $loadedModule | where{$_ -notmatch 'Common$|SDK$'} 109 | } 110 | 111 | $targetModule = $PcliModule.GetEnumerator() | where{$_.Value -contains $pcliBuild} | %{$_.Key} 112 | $targetModule = $targetModule | where{$loadedModule -notcontains $_} 113 | if(!$Cloud) 114 | { 115 | $targetModule = $targetModule | where{$_ -notmatch 'Cloud'} 116 | } 117 | if($targetModule) 118 | { 119 | $targetModule | where{$loadedModule -notcontains $_.Name} | %{ 120 | Import-Module -Name $_ -Verbose:$false 121 | } 122 | } 123 | } 124 | 125 | # Load PSSnapin 126 | $loadedSnap = Get-PSSnapin -Name VMware* -ErrorAction SilentlyContinue | %{$_.Name} 127 | if($pcliBuild -ge 3737840) 128 | { 129 | $loadedSnap = $loadedSnap | where{$_ -notmatch 'Core$'} 130 | } 131 | 132 | $targetSnap = $PcliPssnapin.GetEnumerator() | where{$_.Value -contains $pcliBuild} | %{$_.Key} 133 | $targetSnap = $targetSnap | where{$loadedSnap -notcontains $_} 134 | if(!$Cloud) 135 | { 136 | $targetSnap = $targetSnap | where{$_ -notmatch 'Cloud'} 137 | } 138 | if($targetSnap) 139 | { 140 | $targetSnap | where{$loadedSnap -notcontains $_} | %{ 141 | Add-PSSnapin -Name $_ -Verbose:$false 142 | 143 | # Run initialisation script 144 | if($InitScript) 145 | { 146 | $filePath = "{0}Scripts\Initialize-{1}.ps1" -f $pcliInstallPath,$_.ToString().Replace(".", "_") 147 | if (Test-Path $filePath) { 148 | & $filePath 149 | } 150 | } 151 | } 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 lucdekens 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Scripts 2 | Collection of my scripts 3 | 4 | Universal PowerCLI Loader (see http://www.lucd.info/2016/05/05/universal-powercli-loader/) 5 | - Enable-PowerCLI.ps1 6 | 7 | Create a Ravello Lab (see http://www.lucd.info/2016/02/01/ravello-powershell-module-lab-setup) 8 | - Create-Lab-Public.ps1 9 | - Yggdrasil.json 10 | -------------------------------------------------------------------------------- /yggdrasil.json: -------------------------------------------------------------------------------- 1 | { 2 | "Lab": [ 3 | { 4 | "LabName": "Yggdrasil", 5 | "LabDescription": "vEng Test Environment", 6 | "Force": "true" 7 | } 8 | ], 9 | "Iso": [ 10 | { 11 | "Label": "W2K12R2", 12 | "Filename": "en_windows_server_2012_r2_x64_dvd_2707946.iso", 13 | "Path": "R:\\Homelab\\MSDN\\W2K12R2U1" 14 | }, 15 | { 16 | "Label": "W10", 17 | "Filename": "en_windows_10_enterprise_version_1511_x64_dvd_7224901.iso", 18 | "Path": "R:\\Homelab\\MSDN\\W10" 19 | }, 20 | { 21 | "Label": "VCSA", 22 | "Filename": "VMware-VCSA-all-6.0.0-3343019.iso", 23 | "Path": "R:\\Homelab\\VMware\\6.0\\vCenter" 24 | }, 25 | { 26 | "Label": "ESXi", 27 | "Filename": "VMware-VMvisor-Installer-201601001-3380124.x86_64.iso", 28 | "Path": "R:\\Homelab\\VMware\\6.0\\ESXi" 29 | } 30 | ], 31 | "VM": [ 32 | { 33 | "LabName": "Yggdrasil", 34 | "VmName": "DC1", 35 | "VmDescription": "Domain Controller", 36 | "Image": "Empty", 37 | "ISO": "W2K12R2", 38 | "NumCpu": "", 39 | "MemorySize": "", 40 | "MemoryUnit": "", 41 | "HD": [ 42 | { 43 | "HDSize": "50", 44 | "HDUnit": "GB" 45 | } 46 | ], 47 | "Hostname": "", 48 | "RDP": "true", 49 | "SSH": "false", 50 | "Order": "1", 51 | "OrderDelay": "300" 52 | }, 53 | { 54 | "LabName": "Yggdrasil", 55 | "VmName": "vCenter", 56 | "VmDescription": "vSphere vCenter (VCSA)", 57 | "Image": "Empty", 58 | "ISO": "VCSA", 59 | "NumCpu": "4", 60 | "MemorySize": "8", 61 | "MemoryUnit": "GB", 62 | "HD": [], 63 | "Hostname": "", 64 | "RDP": "true", 65 | "SSH": "false", 66 | "Order": "2", 67 | "OrderDelay": "300" 68 | }, 69 | { 70 | "LabName": "Yggdrasil", 71 | "VmName": "ESX1", 72 | "VmDescription": "ESXi 1", 73 | "Image": "Empty ESX", 74 | "ISO": "ESXi", 75 | "NumCpu": "4", 76 | "MemorySize": "8", 77 | "MemoryUnit": "GB", 78 | "HD": [], 79 | "Hostname": "ESX1", 80 | "RDP": "false", 81 | "SSH": "true", 82 | "Order": "1", 83 | "OrderDelay": "300" 84 | }, 85 | { 86 | "LabName": "Yggdrasil", 87 | "VmName": "ESX2", 88 | "VmDescription": "ESXi 2", 89 | "Image": "Empty ESX", 90 | "ISO": "ESXi", 91 | "NumCpu": "4", 92 | "MemorySize": "8", 93 | "MemoryUnit": "GB", 94 | "HD": [], 95 | "Hostname": "ESX2", 96 | "RDP": "false", 97 | "SSH": "true", 98 | "Order": "1", 99 | "OrderDelay": "300" 100 | }, 101 | { 102 | "LabName": "Yggdrasil", 103 | "VmName": "WS1", 104 | "VmDescription": "Workstation", 105 | "Image": "Empty", 106 | "ISO": "W10", 107 | "NumCpu": "", 108 | "MemorySize": "", 109 | "MemoryUnit": "", 110 | "HD": [ 111 | { 112 | "HDSize": "25", 113 | "HDUnit": "GB" 114 | }, 115 | { 116 | "HDSize": "25", 117 | "HDUnit": "GB" 118 | } 119 | ], 120 | "Hostname": "", 121 | "RDP": "true", 122 | "SSH": "false", 123 | "Order": "2", 124 | "OrderDelay": "300" 125 | }, 126 | { 127 | "LabName": "Yggdrasil", 128 | "VmName": "Pull", 129 | "VmDescription": "DSC Pull Server", 130 | "Image": "Empty", 131 | "ISO": "W2K12R2", 132 | "NumCpu": "", 133 | "MemorySize": "", 134 | "MemoryUnit": "", 135 | "HD2": "", 136 | "HD2Unit": "", 137 | "Hostname": "", 138 | "RDP": "true", 139 | "SSH": "false", 140 | "Order": "3", 141 | "OrderDelay": "0" 142 | }, 143 | { 144 | "LabName": "Yggdrasil", 145 | "VmName": "vEng", 146 | "VmDescription": "The vSphere Engine", 147 | "Image": "Empty", 148 | "ISO": "W2K12R2", 149 | "NumCpu": "", 150 | "MemorySize": "", 151 | "MemoryUnit": "", 152 | "HD2": "", 153 | "HD2Unit": "", 154 | "Hostname": "", 155 | "RDP": "true", 156 | "SSH": "false", 157 | "Order": "3", 158 | "OrderDelay": "0" 159 | } 160 | ] 161 | } 162 | --------------------------------------------------------------------------------