# listHyperVHostsInForests.ps1
# Version: 0.02

function listHyperVHostsInForests{
    # Ensure that AD management module is available for PS Session
    if (!(get-module -name "ActiveDirectory") ){
        Add-WindowsFeature RSAT-AD-PowerShell | out-null;
        import-module -name "ActiveDirectory" -DisableNameChecking | out-null;
        }

    function List-hyperVHosts {            
      [cmdletbinding()]            
      param(
  	    [string]$forest
      )            
      try {            
       Import-Module ActiveDirectory -ErrorAction Stop            
      } catch {            
       Write-Warning "Failed to import Active Directory module. Cannot continue. Aborting..."            
       break;
      }            

      $domains=(Get-ADForest -Identity $forest).Domains 
      foreach ($domain in $domains){
      #"$domain`: `n"
      [string]$dc=(get-addomaincontroller -DomainName $domain -Discover -NextClosestSite).HostName
      try {             
       $hyperVs = Get-ADObject -Server $dc -Filter 'ObjectClass -eq "serviceConnectionPoint" -and Name -eq "Microsoft Hyper-V"' -ErrorAction Stop;
      } catch {            
       "Failed to query $dc of $domain";         
      }            
      foreach($hyperV in $hyperVs) {            
         $x = $hyperV.DistinguishedName.split(",")            
         $HypervDN = $x[1..$x.Count] -join ","  
      
         if ( !($HypervDN -match "CN=LostAndFound")) {     
         $computer = Get-ADComputer -Id $HypervDN -Prop *
         $thisObject = New-Object PSObject -Prop (
             @{
                 hostname = $computer.Name
                 operatingSystem = $($computer.operatingSystem)
                 })
             $thisObject
             }           
        }
       }
    }

    function listForests{
	    $GLOBAL:forests=Get-ADForest | select Name;
	    if ($forests.length -gt 1){
		    #for ($i=0;$i -lt $forests.length;$i++){$forests[$i].Name;}
		    $forests | %{$_.Name;}
	    }else{
		    $forests.Name;
	    }
    }
	listForests|%{List-HyperVHosts $_}|sort
}

function getNetworkMtu($servers){
    $results=@()
    foreach ($server in $servers){
    try{
        $session=new-pssession $server -ErrorAction SilentlyContinue
        if($session){
            $result=invoke-command -session $session -scriptblock{
                #return (Get-NetIPInterface|?{($_.AddressFamily -eq "IPv4") -and ($_.NlMtu -lt 10000)} | select interfacealias,NlMtu)
                Get-NetIPInterface|?{($_.AddressFamily -eq "IPv4") -and ($_.NlMtu -lt 10000)} | select @{name='computerName';expression={$env:computername}},interfaceAlias,@{name='mtu';expression={$_.NlMtu}}
                }} 
            $results+=$result
            Remove-PSSession $session
            }
    catch{
        continue
        }
    }
    $results|Select-Object -Property * -ExcludeProperty RunspaceID,PSComputername|ft|out-string|write-host
}

$hyperVHosts=listHyperVHostsInForests
getNetworkMtu $hyperVHosts.hostname