HVTools.psm1
Function New-HVMachine { Param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string] $MachineName, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string] $HVServer, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [string] $RAM = [System.Int64]4GB, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [string] $Switchname, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [int] $NumCPU = 2, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [switch] $NotDynamicRam, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [int] $MemoryMinimum = 1468006400, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [string] $HDSize = [System.UInt64]32GB, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [string] $HDPath, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [switch] $AutomaticCheckPoints, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [int] $VlanId ) begin {} process { $xml = Get-XMLConfig if (!($Switchname)) { $Switchname = $xml.config.Switchname } if (!($HDPath)) { $HDPath = $xml.config.Diskpaths.Diskpath[0] } $ProgressValue = 20 Write-Progress -Activity "Creating" -Status "$ProgressValue% complete" -PercentComplete $ProgressValue New-VM -Name $MachineName -Generation 2 -MemoryStartupBytes $RAM -SwitchName $Switchname -ComputerName $HVServer | Out-Null $ProgressValue = 40 Write-Progress -Activity "Creating" -Status "$ProgressValue% complete" -PercentComplete $ProgressValue Set-VMProcessor -VMName $MachineName -Count $NumCPU -ComputerName $HVServer if ($NotDynamicRam) { Set-VM -VMName $MachineName -DynamicMemory -ComputerName $HVServer } $ProgressValue = 60 Write-Progress -Activity "Creating" -Status "$ProgressValue% complete" -PercentComplete $ProgressValue set-vm -VMName $MachineName -MemoryMinimumBytes $MemoryMinimum -ComputerName $HVServer $VHD = Join-Path -Path $HDPath -ChildPath "$MachineName.vhdx" New-VHD -Path $VHD -SizeBytes $HDSize -Dynamic -ComputerName $HVServer | Out-Null $ProgressValue = 80 Write-Progress -Activity "Creating" -Status "$ProgressValue% complete" -PercentComplete $ProgressValue Add-VMHardDiskDrive -Path $VHD -VMName $MachineName -ComputerName $HVServer $ProgressValue = 95 Write-Progress -Activity "Creating" -Status "$ProgressValue% complete" -PercentComplete $ProgressValue if (!($AutomaticCheckPoints)) { set-vm -VMName $MachineName -AutomaticCheckpointsEnabled:$false -ComputerName $HVServer } if ($VlanId) { get-vmnetworkAdapter -VMname $MachineName -ComputerName $HVServer | set-VMNetworkAdapterVlan -Access -VlanId $VlanId } Start-VM -VMName $MachineName -ComputerName $hvserver Start-Sleep -Seconds 2 stop-VM -VMName $MachineName -ComputerName $hvserver -Force Get-HVMachineInfo -MachineName $MachineName -HVServer $HVServer } end {} } function Get-HVMachineInfo { Param( [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [string] $MachineName = '', [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [array] $HVServers ) begin{} process { if (!($HVServers)) { $xml = Get-XMLConfig $HVServers = $xml.config.Servers.Server } [int]$ProgressValue = 0 [int]$ProgressPerHVServer = 100 / $HVServers.Count $MachineInfo = New-Object 'System.Collections.Generic.List[HVMachineInfo]' foreach ($HVServer in $HVServers) { $AllHV = get-vm -ComputerName $HVServer | Where-Object {$_.VMName -match $MachineName} [int]$AllHVCount = $AllHV.count if ($AllHVCount -ne 0) { [int]$ProgressPerHV =$ProgressPerHVServer / $AllHVCount foreach ($HVName in ($AllHV).Name) { Write-Progress -Activity "Processing" -Status "$ProgressValue% complete" -PercentComplete $ProgressValue $Mac = (get-vmnetworkAdapter -VMname $HVName -ComputerName $HVServer).MacAddress -replace '(.{2})(?!$)', '$1:' $HVMachineInfo = get-vm -Name $HVName -ComputerName $HVServer | Select-Object Name, State, CPUUsage, ProcessorCount, MemoryAssigned, Uptime, Status, Version, Generation $HVHostInfo = get-vmhost -ComputerName $HVServer | Select-Object ComputerName, LogicalProcessorCount, MemoryCapacity $Gen = $HVMachineInfo.Generation switch ($Gen) { "1" { $BootOrder = (Get-VMBios -VMName 'corp router-1' -ComputerName l22a888).StartupOrder } "2" { $BootOrder = (get-vmfirmware -VMName $HVName -ComputerName $HVServer).bootorder.BootType } } $HardDisk = (get-vmhardDiskDrive -VMName $HVName -ComputerName $HVServer).Path [bool]$HasCheckPoint = $false foreach ($EachHardDisk in $HardDisk) { if ((Get-VHD -Path $EachHardDisk -ComputerName $HVServer).ParentPath) { $HasCheckPoint = $true } } $Machine = [HVMachineInfo]::new( $HVMachineInfo.Name, $HVMachineInfo.State, $HVMachineInfo.CPUUsage, $HVMachineInfo.ProcessorCount, $HVMachineInfo.MemoryAssigned, $Mac, $HardDisk, $HasCheckPoint, $BootOrder, $HVMachineInfo.Uptime, $HVMachineInfo.Status, $HVMachineInfo.Version, $gen, $HVHostInfo.ComputerName, $HVHostInfo.LogicalProcessorCount, $HVHostInfo.MemoryCapacity ) $MachineInfo.Add($Machine) $ProgressValue += $ProgressPerHV } } } return $MachineInfo } end {} } function Set-HVMachineBootDevice { Param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string] $MachineName, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [string] $HVServer, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [array] $HVServers, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'NIC')] [switch] $nic, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DVD')] [switch] $dvd, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'File')] [switch] $File, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Floppy')] [switch] $Floppy ) begin{} process{ $HVServers = Get-HVServers -MachineName $MachineName -HVServer $HVServer -HVServers $HVServers foreach ($HVServer in $HVServers) { foreach ($Machine in (get-vm -ComputerName $HVServer | Where-Object {$_.Name -eq $MachineName})) { $FoundMachineName = $Machine.VMName switch ($machine.generation) { "1" { $StartupOrder = '' if ($nic) { $StartupOrder = @("LegacyNetworkAdapter", "Floppy", "CD", "IDE") } if ($dvd) { $StartupOrder = @("CD", "LegacyNetworkAdapter", "Floppy", "IDE") } if ($File) { $StartupOrder = @("IDE","LegacyNetworkAdapter", "Floppy", "CD") } if ($Floppy) { $StartupOrder = @("Floppy", "LegacyNetworkAdapter", "CD", "IDE") } Set-VMBios -VMName $FoundMachineName -ComputerName $HVServer -StartupOrder $StartupOrder Get-VMBios -VMName $FoundMachineName -ComputerName $HVServer } "2"{ if ($nic) { $BootDevice = Get-VMNetworkAdapter -VMName $FoundMachineName -ComputerName $HVServer } if ($dvd) { $BootDevice = Get-VMDvdDrive -VMName $FoundMachineName -ComputerName $HVServer } if ($File) { $BootDevice = (get-vmfirmware -VMName $FoundMachineName -ComputerName $HVServer).BootOrder | Where-Object {$_.BootType -eq 'File'} } Set-VMFirmware -VMName $FoundMachineName -FirstBootDevice ($BootDevice) -ComputerName $HVServer get-vmfirmware -VMName $FoundMachineName -ComputerName $HVServer | Select-Object -ExpandProperty BootOrder } } } } } end {} } function Remove-HVMachine { Param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string] $MachineName, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [string] $HVServer, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [array] $HVServers ) begin{} process { $HVServers = Get-HVServers -MachineName $MachineName -HVServer $HVServer -HVServers $HVServers [int]$ProgressValue = 0 Write-Progress -Activity "Processing" -Status "$ProgressValue% complete" -PercentComplete $ProgressValue # not yet in use! foreach ($HVServer in $HVServers) { Stop-VM -Name $MachineName -ComputerName $HVServer -ErrorAction Ignore -WarningAction SilentlyContinue -Force | Out-Null $Disks = Get-VMHardDiskDrive -VMName $MachineName -ComputerName $HVServer $DisksToRemove = @() foreach ($disk in $disks.path) { $DisksToRemove += $disk $vhd = (Get-VHD -Path $disk -ComputerName $HVServer).ParentPath if ($vhd) { $DisksToRemove += $vhd do { $vhd = (Get-VHD -Path $vhd -ComputerName $HVServer).ParentPath if ($vhd) { $DisksToRemove += $vhd } } while ($vhd) } } foreach ($disk in $DisksToRemove) { $DiskSplit = $disk.split(':') $UNCPath = "\\$HVServer\$($DiskSplit[0])`$$($DiskSplit[1])" Remove-Item -Path $UNCPath -Force } remove-vm -Name $MachineName -ComputerName $HVServer -Force } } end {} } function Get-HVUnassignedDiskDrive { Param( [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [string] $DiskDrivePath, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [array] $HVServers ) begin{} process { $xml = Get-XMLConfig if (!($HVServers)) { $HVServers = $xml.config.Servers.Server } if (!($DiskDrivePath)) { $DiskDrivePaths = $xml.config.Diskpaths.Diskpath } [int]$ProgressValue = 0 [int]$ProgressPerHVServer = 100 / $HVServers.Count $DiskInfo = New-Object 'System.Collections.Generic.List[DiskInfo]' foreach ($HVServer in $HVServers) { [int]$DiskDriveCount = 0 foreach ($DiskDrivePath in $DiskDrivePaths) { $DiskSplit = $DiskDrivePath.split(':') $UNCPath = "\\$HVServer\$($DiskSplit[0])`$$($DiskSplit[1])" if (Test-Path -Path $UNCPath) { $DiskDriveCount += 1 } } if ($DiskDriveCount -gt 0) { foreach ($DiskDrivePath in $DiskDrivePaths) { $DiskSplit = $DiskDrivePath.split(':') $UNCPath = "\\$HVServer\$($DiskSplit[0])`$$($DiskSplit[1])" if (Test-Path -Path $UNCPath) { $HardDrives = (get-childitem -Path $UNCPath).FullName $AllHV = get-vm -ComputerName $HVServer [int]$AllDiskCount = $HardDrives.count [int]$ProgressPerDisk = $ProgressPerHVServer / $AllDiskCount / $DiskDriveCount foreach ($HardDrive in $HardDrives) { Write-Progress -Activity "Processing" -Status "$ProgressValue% complete" -PercentComplete $ProgressValue $UNCDiskSplit = $HardDrive.split('$') $LocalDiskPath = "$($UNCDiskSplit[0][-1]):$($UNCDiskSplit[1])" $Outcome = "Not Assigned" [bool]$Match = $false foreach ($vm in $AllHV) { foreach ($VMDisk in (Get-VMHardDiskDrive -VMName $vm.name -ComputerName $HVServer).Path) { if ($VMDisk -eq $LocalDiskPath -and !($Match)) { $Outcome = $vm.Name $Match = $true } } } $ProgressValue += $ProgressPerDisk $Disk = [DiskInfo]::new( $HVServer, $LocalDiskPath, $Outcome ) $DiskInfo.add($Disk) } } } } } Return $DiskInfo } end {} } function Get-XMLConfig { $xmlFilePath = Join-Path -Path $PSScriptRoot -ChildPath "HVparam.xml" Return [xml](Get-Content -Path $xmlFilePath) } function Get-HVServers { Param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string] $MachineName, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [string] $HVServer, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [array] $HVServers ) if ($HVServer) { $HVServers = $HVServer } if (!($HVServers)) { $HVServers = Find-HVServers -MachineName $MachineName -ExactMatch } return $HVServers } Function Find-HVServers { Param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string] $MachineName, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [switch] $ExactMatch ) $xml = Get-XMLConfig $HVServers = $xml.config.Servers.Server $ReturnHVServers = @() [int]$ProgressValue = 0 [int]$ProgressPerHV = 100 / $HVServers.count [bool]$FoundMachine = $false foreach ($HVServer in $HVServers) { Write-Progress -Activity "Processing" -Status "$ProgressValue% complete" -PercentComplete $ProgressValue if ($ExactMatch) { $FoundMachine = get-vm -ComputerName $HVServer | Where-Object {$_.Name -eq $MachineName} } else { $FoundMachine = get-vm -ComputerName $HVServer | Where-Object {$_.Name -match $MachineName} } if ($FoundMachine) { $ReturnHVServers += $HVServer } $ProgressValue += $ProgressPerHV } return $ReturnHVServers } |