winReferenceFactory.psm1
|
<#
.Synopsis Powershell Module for build Windows reference images on Hyper-V host .DESCRIPTION Functions in this module: .EXAMPLE New-RefImage REFW10X64-001 .EXAMPLE Remove-RefImage REFW10X64-001 #> function Get-FactoryConfig { # Read Settings from XML [xml]$Global:Settings = Get-Content "$($PSScriptRoot)\winReferenceFactory.xml" $Global:SWitchName = $Global:Settings.Settings.HyperVHostNetwork $Global:VLANID = $Global:Settings.Settings.VLANID $Global:StartUpRAM = 1024*1024*1024*$Global:Settings.Settings.StartUpRAM $Global:VMLocation = $Global:Settings.Settings.HyperVStorage $Global:VHDSize = 1024*1024*1024*$Global:Settings.Settings.VHDSize $Global:HyperVISOFolder = $Global:Settings.Settings.HyperVISOFolder $Global:DeploymentShare = $Global:Settings.Settings.DeploymentShare $Global:TaskSequenceFolder = $Global:Settings.Settings.TaskSequenceFolder $Global:ReportFrom = $Global:Settings.Settings.ReportFrom $Global:ReportTo = $Global:Settings.Settings.ReportTo $Global:ReportSmtp = $Global:Settings.Settings.ReportSmtp } function New-AutoGenRefImages { Get-FactoryConfig #Connect to MDT: Add-PSSnapIn Microsoft.BDD.PSSnapIn -ErrorAction Stop Remove-PSDrive MDT -ErrorAction SilentlyContinue $Null = New-PSDrive -Name MDT -PSProvider MDTProvider -Root $Global:DeploymentShare -Force $MDTSettings = Get-ItemProperty MDT: $ISO = $MDTSettings.'Boot.x86.LiteTouchISOName' #Check if ISO exists $ISOFileExist = Test-Path "$($Global:DeploymentShare)\Boot\$($ISO)" -ErrorAction SilentlyContinue If (!$ISOFileExist) { Write-Output "Unable to find ISO, exit" exit } #Create Folders $Null = New-Item -Path $HyperVISOFolder -ItemType Directory -Force -ErrorAction SilentlyContinue #Copy the BootImage from MDTServer to Hyper-VHost Copy-Item "$($Global:DeploymentShare)\Boot\$($ISO)" $Global:HyperVISOFolder\ -Container -Force -ErrorAction Stop #Check if ISO exists $ISOFileExist = Test-Path ($Global:HyperVISOFolder + "\" + $ISO) -ErrorAction Stop If (!$ISOFileExist) { Write-Output "Unable to find ISO, exit" exit } #Check if VMSwitch on host exists $VMSwitchExist = Get-VMSwitch -Name $Global:SWitchName -ErrorAction SilentlyContinue If ($VMSwitchExist.Name -ne $Global:SWitchName) { Write-Output "Unable to find VMSwitch, exit" exit } #Create the VMs $RefTS = Get-ChildItem $Global:TaskSequenceFolder -Recurse Foreach ($TS in $RefTS) { #Set VMName to ID $VMName = $TS.ID #Check if VM exists $VMexist = Get-VM -Name $VMName -ErrorAction SilentlyContinue If ($VMexist.Name -eq $VMName) { Write-Output "VM already exist, exit" exit } $VM = New-VM �Name $VMname -Path $Global:VMLocation �MemoryStartupBytes $Global:StartUpRAM ` -SwitchName $Global:SWitchName -NewVHDPath "$Global:VMLocation\$VMName\Virtual Hard Disks\$VMName.vhdx" ` -NewVHDSizeBytes $Global:VHDSize ` Add-VMDvdDrive -VM $VM -Path ($Global:HyperVISOFolder + "\" + $ISO) #Set Get-VM -Name $VMName | Set-VMProcessor -CompatibilityForMigrationEnabled $True Get-VM -Name $VMName | Set-VMProcessor -Count 2 If ($Global:VLANID -and $Global:VLANID -ne "0") { Get-VM -Name $VMName | Get-VMNetworkAdapter | Set-VMNetworkAdapterVlan -Access -VlanId $VLANID } } if ($RefTS.Count -eq 1) { #Start one VM $VMName = $RefTS.ID Start-VM -Name $VMName Start-Sleep 60 $VM = Get-VM -Name $VMName $StartTime = Get-Date while ($VM.State -eq "Running") { Start-Sleep "120" $VM = Get-VM -Name $VMName } $EndTime = Get-Date $ElapsedTime = $EndTime - $StartTime If ($Global:ReportFrom -and $Global:ReportTo -and $Global:ReportSmtp) { Send-AutoGenReport $RefTS.Name $ElapsedTime $Global:ReportFrom $Global:ReportTo $Global:ReportSmtp } # Remove reference VM Remove-RefImage $VMName } else { #Start multiple VMs workflow Start-VMs { param( [System.Object[]]$RefTS, [string]$ReportFrom, [string]$ReportTo, [string]$ReportSmtp ) Foreach -parallel ($TS in $RefTS) { $VMName = $TS.ID Start-VM -Name $VMName Start-Sleep 60 $VM = Get-VM -Name $VMName $StartTime = Get-Date while ($VM.State -eq "Running") { Start-Sleep "120" $VM = Get-VM -Name $VMName } $EndTime = Get-Date $ElapsedTime = $EndTime - $StartTime If ($ReportFrom -and $ReportTo -and $ReportSmtp) { Send-AutoGenReport $TS.Name $ElapsedTime $ReportFrom $ReportTo $ReportSmtp } # Remove reference VM Remove-RefImage $VMName } } Start-VMs $RefTS $Global:ReportFrom $Global:ReportTo $Global:ReportSmtp } } function Remove-AutoGenRefImages { Get-FactoryConfig #Connect to MDT: $Null = Add-PSSnapIn Microsoft.BDD.PSSnapIn -ErrorAction SilentlyContinue Remove-PSDrive MDT -ErrorAction SilentlyContinue $Null = New-PSDrive -Name MDT -PSProvider MDTProvider -Root $Global:DeploymentShare -Force $MDTSettings = Get-ItemProperty MDT: $ISO = $MDTSettings.'Boot.x86.LiteTouchISOName' #Remove the VMs $RefTS = Get-ChildItem $Global:TaskSequenceFolder -Recurse Foreach ($TS in $RefTS) { #Set VMName to ID $VMName = $TS.ID #Check if VM exists $VMexist = Get-VM -Name $VMName -ErrorAction SilentlyContinue If ($VMexist.Name -eq $VMName) { Write-Output "Removing $VMName" $VMToRemove = Get-VM -Name $VMName $FolderPath = $VMToRemove.path if ($VMToRemove.state -eq "Running") {Stop-VM $VMToRemove -Force} $VMToRemove | Remove-VM -Force $FolderPath | Remove-Item -Force -Recurse } } } function New-RefImage { [CmdletBinding()] [OutputType([int])] Param ( [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ValueFromRemainingArguments=$false, Position=0)] [String]$TaskSequenceID ) Get-FactoryConfig #Connect to MDT: Add-PSSnapIn Microsoft.BDD.PSSnapIn -ErrorAction Stop Remove-PSDrive MDT -ErrorAction SilentlyContinue $Null = New-PSDrive -Name MDT -PSProvider MDTProvider -Root $Global:DeploymentShare -Force $MDTSettings = Get-ItemProperty MDT: $ISO = $MDTSettings.'Boot.x86.LiteTouchISOName' #Check if ISO exists $ISOFileExist = Test-Path "$($Global:DeploymentShare)\Boot\$($ISO)" -ErrorAction SilentlyContinue If (!$ISOFileExist) { Write-Output "Unable to find ISO, exit" exit } #Create Folders $null = New-Item -Path $HyperVISOFolder -ItemType Directory -Force -ErrorAction SilentlyContinue #Copy the BootImage from MDTServer to Hyper-VHost Copy-Item "$($Global:DeploymentShare)\Boot\$($ISO)" $Global:HyperVISOFolder\ -Container -Force -ErrorAction Stop #Check if ISO exists $ISOFileExist = Test-Path ($Global:HyperVISOFolder + "\" + $ISO) -ErrorAction Stop If (!$ISOFileExist) { Write-Output "Unable to find ISO, exit" exit } #Check if VMSwitch on host exists $VMSwitchExist = Get-VMSwitch -Name $Global:SWitchName -ErrorAction SilentlyContinue If ($VMSwitchExist.Name -ne $Global:SWitchName) { Write-Output "Unable to find VMSwitch, exit" exit } #Check if VM exists $VMexist = Get-VM -Name $VMName -ErrorAction SilentlyContinue If ($VMexist.Name -eq $VMName) { Write-Output "VM already exist, exit" exit } $VM = New-VM �Name $TaskSequenceID -Path $Global:VMLocation �MemoryStartupBytes $Global:StartUpRAM ` -SwitchName $Global:SWitchName ` -NewVHDPath "$Global:VMLocation\$TaskSequenceID\Virtual Hard Disks\$TaskSequenceID.vhdx" ` -NewVHDSizeBytes $Global:VHDSize Add-VMDvdDrive -VM $VM -Path ($Global:HyperVISOFolder + "\" + $ISO) #Set Get-VM -Name $TaskSequenceID | Set-VMProcessor -CompatibilityForMigrationEnabled $True -VM $VM Get-VM -Name $TaskSequenceID | Set-VMProcessor -Count 2 If ($Global:VLANID -ne "0") { Get-VM -Name $TaskSequenceID | Get-VMNetworkAdapter | Set-VMNetworkAdapterVlan -Access -VlanId $VLANID } } function Remove-RefImage { [CmdletBinding()] [OutputType([int])] Param ( [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ValueFromRemainingArguments=$false, Position=0)] [String]$VMName ) #Check if VM exists $VMexist = Get-VM -Name $VMName -ErrorAction SilentlyContinue If ($VMexist.Name -eq $VMName) { Write-Output "Removing $VMName" $VMToRemove = Get-VM -Name $VMName $FolderPath = $VMToRemove.path if ($VMToRemove.state -eq "Running") {Stop-VM $VMToRemove -Force} $VMToRemove | Remove-VM -Force $FolderPath | Remove-Item -Force -Recurse } } function Get-RefTaskSequence { Get-FactoryConfig #Connect to MDT: Add-PSSnapIn Microsoft.BDD.PSSnapIn -ErrorAction Stop Remove-PSDrive MDT -ErrorAction SilentlyContinue $Null = New-PSDrive -Name MDT -PSProvider MDTProvider -Root $Global:DeploymentShare -Force #Get TS $RefTS = Get-ChildItem $Global:TaskSequenceFolder -Recurse Foreach($TS in $RefTS) { New-Object PSObject -Property @{ TaskSequenceID = $TS.ID Name = $TS.Name Comments = $TS.Comments Version = $TS.Version Enabled = $TS.enable LastModified = $TS.LastModifiedTime } } } function Send-AutoGenReport($ImageName, $ElapsedTime, $ReportFrom, $ReportTo, $ReportSmtp) { $subject = "Image $ImageName" $encoding = [System.Text.Encoding]::UTF8 $hours = [math]::floor($ElapsedTime.TotalHours) $mins = [int]$ElapsedTime.TotalMinutes - $hours*60 $body = "Image [$ImageName] was builded at $hours h. $mins min." Send-MailMessage -From $ReportFrom -To $ReportTo -Subject $subject -SmtpServer $ReportSmtp -Encoding $encoding -BodyAsHtml $body } Export-ModuleMember -function * |