Private/Connect-Hypervisor.ps1

function Connect-Hypervisor {
    <#
    .SYNOPSIS
        Abstraction function that handles connecting to either VMware vSphere or Microsoft Hyper-V.
    .DESCRIPTION
        Provides a unified connection interface for both VMware vSphere (via PowerCLI) and
        Microsoft Hyper-V (via the Hyper-V PowerShell module). For VMware, connects to
        vCenter/ESXi and returns a VIServer connection object. For Hyper-V, verifies
        module availability and host connectivity, returning a lightweight connection info object.
 
        Hyper-V does not use persistent connection objects like PowerCLI. Instead, each
        Hyper-V cmdlet accepts a -ComputerName parameter for remote hosts. This function
        validates that the Hyper-V module is available and the target host is reachable.
    .PARAMETER Server
        The hostname or IP address of the target hypervisor. For VMware, this is the
        vCenter Server or ESXi host. For Hyper-V, this is the Hyper-V host or 'localhost'.
    .PARAMETER Credential
        PSCredential for authentication. Used directly by Connect-VIServer for VMware.
        For remote Hyper-V hosts, used with Invoke-Command to verify connectivity.
    .PARAMETER Hypervisor
        The hypervisor type. Valid values: 'VMware', 'HyperV'. Default: 'VMware'.
    .EXAMPLE
        $conn = Connect-Hypervisor -Server vcenter.contoso.com -Hypervisor VMware
    .EXAMPLE
        $conn = Connect-Hypervisor -Server hyperv01.contoso.com -Hypervisor HyperV
    .EXAMPLE
        $conn = Connect-Hypervisor -Server localhost -Hypervisor HyperV
    .NOTES
        Author: Larry Roberts
        Part of the VM-AutoTagger module.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$Server,
        [PSCredential]$Credential,
        [ValidateSet('VMware', 'HyperV')]
        [string]$Hypervisor = 'VMware'
    )

    if ($Hypervisor -eq 'VMware') {
        $params = @{ Server = $Server; ErrorAction = 'Stop' }
        if ($Credential) { $params['Credential'] = $Credential }
        return Connect-VIServer @params
    }
    else {
        # Hyper-V uses -ComputerName for remote, no connection object needed
        # Verify connectivity
        if ($Server -eq 'localhost' -or $Server -eq $env:COMPUTERNAME -or $Server -eq '.') {
            # Local Hyper-V - just verify module is available
            Import-Module Hyper-V -ErrorAction Stop
            return [PSCustomObject]@{
                Server  = $Server
                Type    = 'HyperV-Local'
                Version = (Hyper-V\Get-VMHost -ErrorAction SilentlyContinue | Select-Object -First 1).Name
            }
        }
        else {
            # Remote Hyper-V
            Import-Module Hyper-V -ErrorAction Stop
            # Test remote connectivity
            $vmHost = Hyper-V\Get-VMHost -ComputerName $Server -ErrorAction Stop
            if ($Credential) {
                # For remote with credentials, test with Invoke-Command
                $testResult = Invoke-Command -ComputerName $Server -Credential $Credential -ScriptBlock { Hyper-V\Get-VMHost } -ErrorAction Stop
            }
            return [PSCustomObject]@{
                Server  = $Server
                Type    = 'HyperV-Remote'
                Version = $vmHost.Name
            }
        }
    }
}

function Disconnect-Hypervisor {
    <#
    .SYNOPSIS
        Disconnects from the hypervisor. Only relevant for VMware; Hyper-V has no persistent connection.
    .DESCRIPTION
        For VMware, disconnects from vCenter/ESXi using Disconnect-VIServer.
        For Hyper-V, this is a no-op since Hyper-V cmdlets do not use persistent connections.
    .PARAMETER Server
        The hypervisor server name to disconnect from.
    .PARAMETER Hypervisor
        The hypervisor type. Valid values: 'VMware', 'HyperV'. Default: 'VMware'.
    .EXAMPLE
        Disconnect-Hypervisor -Server vcenter.contoso.com -Hypervisor VMware
    .EXAMPLE
        Disconnect-Hypervisor -Server hyperv01 -Hypervisor HyperV # No-op
    .NOTES
        Author: Larry Roberts
        Part of the VM-AutoTagger module.
    #>

    [CmdletBinding()]
    param(
        [string]$Server,
        [string]$Hypervisor = 'VMware'
    )
    if ($Hypervisor -eq 'VMware') {
        Disconnect-VIServer -Server $Server -Confirm:$false -ErrorAction SilentlyContinue
    }
    # Hyper-V doesn't need disconnection
}