HVTools.psm1

# Import-Module "C:\repos\Posh-HVTools\HVTools"

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 = 'C:\Hyper-V\vhd\',
        [Parameter(Mandatory = $false,
        ValueFromPipelineByPropertyName = $true)]
        [switch]
        $AutomaticCheckPoints,
        [Parameter(Mandatory = $false,
        ValueFromPipelineByPropertyName = $true)]
        [int]
        $VlanId
    )
    begin {}
    process {
        if (!($Switchname)) {
            $xml = Get-XMLConfig
            $Switchname = $xml.config.Switchname
        }
        New-VM -Name $MachineName -Generation 2 -MemoryStartupBytes $RAM -SwitchName $Switchname -ComputerName $HVServer | Out-Null
        Set-VMProcessor -VMName $MachineName -Count $NumCPU -ComputerName $HVServer
        if ($NotDynamicRam) {
            Set-VM -VMName $MachineName -DynamicMemory -ComputerName $HVServer
        }
        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
        Add-VMHardDiskDrive -Path $VHD -VMName $MachineName -ComputerName $HVServer
        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 Find-HVMachine {
    Param(
        [Parameter(Mandatory = $true,
        ValueFromPipelineByPropertyName = $true)]
        [string]
        $MachineName,
        [Parameter(Mandatory = $false,
        ValueFromPipelineByPropertyName = $true)]
        [array]
        $HVServers
    )
    begin{}

    process{
        if (!($HVServers)) {
            $xml = Get-XMLConfig
            $HVServers = $xml.config.Servers.Server
        }
        foreach ($HVServer in $HVServers) {
            $Machine = get-vm -ComputerName $HVServer | Where-Object {$_.Name -eq $MachineName}
            if ($Machine) {
                return Get-HVMachineInfo -MachineName $Machine.Name -HVServer $HVServer
            }
        }
    }

    end {}
}
function Get-HVMachineInfo {
    Param(
        [Parameter(Mandatory = $true,
        ValueFromPipelineByPropertyName = $true)]
        [string]
        $MachineName,
        [Parameter(Mandatory = $false,
        ValueFromPipelineByPropertyName = $true)]
        [string]
        $HVServer,
        [Parameter(Mandatory = $false,
        ValueFromPipelineByPropertyName = $true)]
        [array]
        $HVServers
    )
    begin{}

    process {
        if (!($HVServer)) {
            $HVServer  = (Find-HVMachine -MachineName $MachineName -HVServers $HVServers).HVServer
        }
        $Mac = (get-vmnetworkAdapter -VMname $MachineName -ComputerName $HVServer).MacAddress -replace '(.{2})(?!$)', '$1:'
        $HVMachineInfo = get-vm -Name $MachineName -ComputerName $HVServer | Select-Object Name, State, CPUUsage,MemoryAssigned, Uptime, Status, Version, Generation
        $HVHostInfo = get-vmhost -ComputerName $HVServer | Select-Object ComputerName, LogicalProcessorCount, MemoryCapacity
        $MachineInfo = New-Object 'System.Collections.Generic.List[HVMachineInfo]'
        
        $Machine = [HVMachineInfo]::new(
            $HVMachineInfo.Name,
            $HVMachineInfo.State,
            $HVMachineInfo.CPUUsage,
            $HVMachineInfo.MemoryAssigned,
            $Mac,
            $HVMachineInfo.Uptime,
            $HVMachineInfo.Status,
            $HVMachineInfo.Version,
            $HVMachineInfo.Generation,
            $HVHostInfo.ComputerName,
            $HVHostInfo.LogicalProcessorCount,
            $HVHostInfo.MemoryCapacity
            # addera diskar här! 250304 LA
        )

        $MachineInfo.Add($Machine)
        return $MachineInfo
    }

    end {}
}
function Set-HVMachineBootDevice {
    Param(
        [Parameter(Mandatory = $true,
        ValueFromPipelineByPropertyName = $true)]
        [string]
        $MachineName,
        [Parameter(Mandatory = $true,
        ValueFromPipelineByPropertyName = $true)]
        [string]
        $HVServer,
        [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
    )
    begin{}

    process{
        if ($nic) {
            $BootDevice = Get-VMNetworkAdapter -VMName $MachineName -ComputerName $HVServer
        }
        if ($dvd) {
            $BootDevice = Get-VMDvdDrive -VMName $MachineName -ComputerName $HVServer
        }
        if ($File) {
            $BootDevice = (get-vmfirmware -VMName psd01 -ComputerName l21a888).BootOrder | Where-Object {$_.BootType -eq 'File'}   
        }
        Set-VMFirmware -VMName $MachineName -FirstBootDevice ($BootDevice) -ComputerName $HVServer
        get-vmfirmware -VMName $MachineName -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 {
        if (!($HVServer)) {
            $HVServer  = (Find-HVMachine -MachineName $MachineName -HVServers $HVServers).HVServer
        }
        Stop-VM -Name  $MachineName -ComputerName $HVServer -ErrorAction Ignore -WarningAction SilentlyContinue -Force | Out-Null

        $Disks = Get-VMHardDiskDrive -VMName $MachineName -ComputerName $HVServer
        foreach ($Disk in $Disks.Path) {
            $DiskSplit = $disk.split(':')
            $UNCPath = "\\$HVServer\$($DiskSplit[0])`$$($DiskSplit[1])"
            Write-Output "disk: $Disk"
            Write-Output "unc: $UNCPath"
            Remove-Item -Path $UNCPath -Force
        }
        remove-vm -Name $MachineName -ComputerName $HVServer -Force
    }

    end {}
}
function Get-UnassignedDiskDrive {
    Param(
        [Parameter(Mandatory = $true,
        ValueFromPipelineByPropertyName = $true)]
        [string]
        $DiskDrivePath,
        [Parameter(Mandatory = $false,
        ValueFromPipelineByPropertyName = $true)]
        [string]
        $HVServer,
        [Parameter(Mandatory = $false,
        ValueFromPipelineByPropertyName = $true)]
        [array]
        $HVServers
    )
    begin{}

    process {

        if (!($HVServers) -and !($HVServer)) {
            $xml = Get-XMLConfig
            $HVServers = $xml.config.Servers.Server
        }
        if (!($HVServers)) { $HVServers = $HVServer }
        $DiskArray = [System.Collections.ArrayList]@()

        foreach ($HVServer in $HVServers) {
            $DiskSplit = $DiskDrivePath.split(':')
            $UNCPath = "\\$HVServer\$($DiskSplit[0])`$$($DiskSplit[1])"
            $HardDrives = (get-childitem -Path $UNCPath).FullName
            foreach ($HardDrive in $HardDrives) {
                $DiskSplit = $HardDrive.split('$')
                $LocalDiskPath = "$($DiskSplit[0][-1]):$($DiskSplit[1])"
                $Outcome = "Not Assigned"
                [bool]$Match = $false
                   foreach ($vm in get-vm -ComputerName $HVServer) {
                    foreach ($VMDisk in (Get-VMHardDiskDrive -VMName $vm.name -ComputerName $HVServer).Path) {
                        if ($VMDisk -eq $LocalDiskPath -and !($Match)) {
                            $Outcome = $vm.Name
                            $Match = $true
                        }
                        Write-Output "compare: $LocalDiskPath $VMDisk $Match"
    
                        
                    }
    
                }
                $DiskArray.Add(@($LocalDiskPath, $Outcome)) | Out-Null

            }
        }
        Write-Output $DiskArray | ForEach-Object { "$($_[0]) - $($_[1])" }

    }

    end {}

}
function Get-XMLConfig {
    $xmlFilePath = Join-Path -Path $PSScriptRoot -ChildPath "HVparam.xml"
    Return [xml](Get-Content -Path $xmlFilePath)
}