· 9 years ago · Dec 09, 2016, 03:40 PM
1Function New-VMFromFile {
2 <#
3 .SYNOPSIS
4 Provisions VMs based on supplied parameters contained in .csv file
5
6 .DESCRIPTION
7 Provisions VMs based on supplied parameters contained in .csv file
8
9 .PARAMETER File
10 A file containing VMs with specified parameters. No default.
11
12 .PARAMETER Throttle
13 Number of asynchonous jobs that will run at a time. Default is 5.
14
15 .EXAMPLE FILE
16 VC,Environment,Cluster,Name,Description,Template,NumCPU,RAMSizeGB,Disk1SizeGB,Disk2SizeGB,Disk3SizeGB,Disk4SizeGB,Disk5SizeGB,NetworkName,Folder,ParentFolder
17 vcenter-name,Test,cluster-name,CNTV-01TEST01,A test server,Server Standard 2012 R2,4,8,60,0,0,0,0,network-name,Test,Developement/Testing
18
19 .EXAMPLE
20 New-VMFromFile -File "C:\Servers.csv"
21
22 #>
23 #Requires -Version 4.0
24 [cmdletbinding()]
25 Param (
26 [parameter(Mandatory=$true)]
27 [string]$File,
28
29 [parameter()]
30 [int]$Throttle = 5
31 )
32 Begin {
33 #Load file
34 $servers = Import-CSV -Path $File
35
36 #Function that will be used to process runspace jobs
37 Function Get-RunspaceData {
38 [cmdletbinding()]
39 param(
40 [switch]$Wait
41 )
42 Do {
43 $more = $false
44 Foreach($runspace in $runspaces) {
45 If ($runspace.Runspace.isCompleted) {
46 $runspace.powershell.EndInvoke($runspace.Runspace)
47 $runspace.powershell.dispose()
48 $runspace.Runspace = $null
49 $runspace.powershell = $null
50 $Script:i++
51 } ElseIf ($runspace.Runspace -ne $null) {
52 $more = $true
53 }
54 }
55 If ($more -AND $PSBoundParameters['Wait']) {
56 Start-Sleep -Milliseconds 100
57 }
58 #Clean out unused runspace jobs
59 $temphash = $runspaces.clone()
60 $temphash | Where {
61 $_.runspace -eq $Null
62 } | ForEach {
63 Write-Verbose ("Removing {0}" -f $_.computer)
64 $Runspaces.remove($_)
65 }
66 } while ($more -AND $PSBoundParameters['Wait'])
67 }
68
69 Write-Verbose ("Performing inital Administrator check")
70 $usercontext = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()
71 $IsAdmin = $usercontext.IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
72
73 #Main collection to hold all data returned from runspace jobs
74 $Script:report = @()
75
76 #Define hash table for Get-RunspaceData function
77 $runspacehash = @{}
78
79 #Define Scriptblock for runspaces
80 $scriptblock = {
81 Param (
82 $vc="vcenter-name",
83 $env="",
84 $cl="cluster-name",
85 $name="",
86 $desc="",
87 $template="Server Standard 2012 R2",
88 $cpu="4",
89 $ram="4",
90 $disk1="60",
91 $disk2="0",
92 $disk3="0",
93 $disk4="0",
94 $disk5="0",
95 $net="",
96 $fol="",
97 $pfol=""
98
99 )
100
101 Get-Module –ListAvailable VM* | Import-Module
102
103
104 #Check if connected to vCenter
105 if($global:DefaultVIServer.Name -ne $vc) {
106 Connect-VIServer $vc | Out-Null
107 }
108
109 #Check if VM already exists
110 if(Get-Vm -Name $vm.Name -ErrorAction SilentlyContinue) {
111 Write-Warning "I made it!"
112 break
113 }
114 else {
115 Write-Warning "Success!"
116 }
117
118 Disconnect-VIServer -Force -Confirm:$false
119
120
121 }
122
123 Write-Verbose ("Creating runspace pool and session states")
124 $sessionstate = [system.management.automation.runspaces.initialsessionstate]::CreateDefault()
125 $runspacepool = [runspacefactory]::CreateRunspacePool(1, $Throttle, $sessionstate, $Host)
126 $runspacepool.Open()
127
128 Write-Verbose ("Creating empty collection to hold runspace jobs")
129 $Script:runspaces = New-Object System.Collections.ArrayList
130 }
131 Process {
132 $totalcount = $servers.count
133 Write-Verbose ("Validating that current user is Administrator")
134 #Verify user is Administrator
135 If (-Not ($IsAdmin -OR $PSBoundParameters['Credential'])) {
136 Write-Warning ("You must be an Administrator to perform this action!")
137 break
138 }
139
140 ForEach ($vm in $servers) {
141 #Create the powershell instance and supply the scriptblock with the other parameters
142 $powershell = [powershell]::Create().AddScript($ScriptBlock)
143 $powershell.AddArgument($vm.VC) | Out-Null
144 $powershell.AddArgument($vm.Environment) | Out-Null
145 $powershell.AddArgument($vm.Cluster) | Out-Null
146 $powershell.AddArgument($vm.Name) | Out-Null
147 $powershell.AddArgument($vm.Description) | Out-Null
148 $powershell.AddArgument($vm.Template) | Out-Null
149 $powershell.AddArgument($vm.NumCPU) | Out-Null
150 $powershell.AddArgument($vm.RAMSizeGB) | Out-Null
151 $powershell.AddArgument($vm.Disk1SizeGB) | Out-Null
152 $powershell.AddArgument($vm.Disk2SizeGB) | Out-Null
153 $powershell.AddArgument($vm.Disk3SizeGB) | Out-Null
154 $powershell.AddArgument($vm.Disk4SizeGB) | Out-Null
155 $powershell.AddArgument($vm.Disk5SizeGB) | Out-Null
156 $powershell.AddArgument($vm.NetworkName) | Out-Null
157 $powershell.AddArgument($vm.Folder) | Out-Null
158 $powershell.AddArgument($vm.ParentFolder) | Out-Null
159
160 #Add the runspace into the powershell instance
161 $powershell.RunspacePool = $runspacepool
162
163 #Create a temporary collection for each runspace
164 $temp = "" | Select-Object PowerShell,Runspace,Computer
165 $Temp.Computer = $vm.Name
166 $temp.PowerShell = $powershell
167
168 #Save the handle output when calling BeginInvoke() that will be used later to end the runspace
169 $temp.Runspace = $powershell.BeginInvoke()
170 Write-Verbose ("Adding {0} collection" -f $temp.Computer)
171 $runspaces.Add($temp) | Out-Null
172
173 Write-Verbose ("Checking status of runspace jobs")
174 Get-RunspaceData @runspacehash
175 }
176 }
177 End {
178 Write-Verbose ("Finish processing the remaining runspace jobs: {0}" -f (@(($runspaces | Where {$_.Runspace -ne $Null}).Count)))
179 $runspacehash.Wait = $true
180 Get-RunspaceData @runspacehash
181
182 Write-Verbose ("Closing the runspace pool")
183 $runspacepool.close()
184 }
185}