VMSyntheticKernelDebugging.psm1

#Requires -Modules Hyper-V
#Requires -Modules CimCmdlets

Function Modify-SystemSettings {
    [Diagnostics.CodeAnalysis.SuppressMessage('PSUseApprovedVerbs', '', Justification='Internal function')]
    [CmdletBinding(PositionalBinding=$false)]
    Param (
        [Parameter(Mandatory = $true)]
        $VMData
    )
    
    $CIMSerializer = [Microsoft.Management.Infrastructure.Serialization.CimSerializer]::Create()
    $VMDataSerialized = $CIMSerializer.Serialize($VMData, [Microsoft.Management.Infrastructure.Serialization.InstanceSerializationOptions]::None)
    $VMDataXML = [System.Text.Encoding]::Unicode.GetString($VMDataSerialized)

    $MgmtSvc = Get-CimInstance -Class "Msvm_VirtualSystemManagementService" `
                            -Namespace "root\virtualization\v2"

    Invoke-CimMethod -CimInstance $MgmtSvc -MethodName ModifySystemSettings @{SystemSettings = $VMDataXML} | Out-Null
}

Function Get-VMData {
    [CmdletBinding(PositionalBinding=$false)]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [Microsoft.HyperV.PowerShell.VirtualMachine]$VM
    )
    
    $VMData = Get-CimInstance -Namespace "root\virtualization\v2" `
                        -Class Msvm_VirtualSystemSettingData `
        | Where-Object -Property ConfigurationID -EQ $VM.Id
    
    Return $VMData
}

Function Enable-VMSyntheticKernelDebugging {
    [CmdletBinding(PositionalBinding=$false)]
    Param (
        [Parameter(ParameterSetName = "VM", Mandatory = $true, ValueFromPipeline = $true)]
        [Microsoft.HyperV.PowerShell.VirtualMachine]$VM,
        [Parameter(ParameterSetName = "VMName", Mandatory = $true, ValueFromPipeline = $true)]
        [String]$VMName,
        [Parameter(Mandatory = $true)]
        [ValidateRange(49152, 65535)]
        [Int]$DebugPort
    )

    If ($VMName -NE "") {
        $VM = Get-VM -VMName $VMName
    }

    $VMData = Get-VMData -VM $VM

    $VMData.DebugPort = $DebugPort
    $VMData.DebugPortEnabled = 1

    Modify-SystemSettings -VMData $VMData

    Return $VM
}

Function Disable-VMSyntheticKernelDebugging {
    [CmdletBinding(PositionalBinding=$false)]
    Param (
        [Parameter(ParameterSetName = "VM", Mandatory = $true, ValueFromPipeline = $true)]
        [Microsoft.HyperV.PowerShell.VirtualMachine]$VM,
        [Parameter(ParameterSetName = "VMName", Mandatory = $true, ValueFromPipeline = $true)]
        [String]$VMName
    )

    If ($VMName -NE "") {
        $VM = Get-VM -VMName $VMName
    }
    
    $VMData = Get-VMData -VM $VM

    $VMData.DebugPortEnabled = 0

    Modify-SystemSettings -VMData $VMData

    Return $VM
}

Function Get-VMSyntheticKernelDebugging {
    [CmdletBinding(PositionalBinding=$false)]
    Param (
        [Parameter(ParameterSetName = "VM", Mandatory = $true, ValueFromPipeline = $true)]
        [Microsoft.HyperV.PowerShell.VirtualMachine]$VM,
        [Parameter(ParameterSetName = "VMName", Mandatory = $true, ValueFromPipeline = $true)]
        [String]$VMName
    )

    If ($VMName -NE "") {
        $VM = Get-VM -VMName $VMName
    }

    $VMData = Get-VMData -VM $VM
    
    Return @{"VM" = $VM; "DebugPortEnabled" = $VMData.DebugPortEnabled; "DebugPort" = $VMData.DebugPort}
}