Posted On August 22, 2020

PowerShell: Gather All Guess VM of All Hyper-V Clusters in the Domain

kimconnect 0 comments
blog.KimConnect.com >> Codes , Virtualization >> PowerShell: Gather All Guess VM of All Hyper-V Clusters in the Domain
# getAllVms.ps1

$clusterName='*'

function includeRSAT{
    $ErrorActionPreference='stop'
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    #$rsatWindows7x32='https://download.microsoft.com/download/4/F/7/4F71806A-1C56-4EF2-9B4F-9870C4CFD2EE/Windows6.1-KB958830-x86-RefreshPkg.msu'
    $rsatWindows7x64='https://download.microsoft.com/download/4/F/7/4F71806A-1C56-4EF2-9B4F-9870C4CFD2EE/Windows6.1-KB958830-x64-RefreshPkg.msu'
    $rsatWindows81='https://download.microsoft.com/download/1/8/E/18EA4843-C596-4542-9236-DE46F780806E/Windows8.1-KB2693643-x64.msu'
    $rsat1709 = "https://download.microsoft.com/download/1/D/8/1D8B5022-5477-4B9A-8104-6A71FF9D98AB/WindowsTH-RSAT_WS_1709-x64.msu"
    $rsat1803 = "https://download.microsoft.com/download/1/D/8/1D8B5022-5477-4B9A-8104-6A71FF9D98AB/WindowsTH-RSAT_WS_1803-x64.msu"
    $rsatWs2016 = "https://download.microsoft.com/download/1/D/8/1D8B5022-5477-4B9A-8104-6A71FF9D98AB/WindowsTH-RSAT_WS2016-x64.msu"
  
    # This command does not work on Windows 2012R2
    #$releaseId=(Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name ReleaseId).ReleaseId
    #Get-ItemProperty : Property ReleaseId does not exist at path HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows
    #NT\CurrentVersion.
    #At line:1 char:2
    #+ (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Na ...
    #+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    #    + CategoryInfo          : InvalidArgument: (ReleaseId:String) [Get-ItemProperty], PSArgumentException
    #    + FullyQualifiedErrorId : System.Management.Automation.PSArgumentException,Microsoft.PowerShell.Commands.GetItemPropertyCommand
  
    $releaseId=(Get-Item "HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion").GetValue('ReleaseID')
    $osVersion=[System.Environment]::OSVersion.Version
    [double]$osVersionMajorMinor="$($osVersion.Major).$($osVersion.Minor)"  
    $osName=(Get-WmiObject Win32_OperatingSystem).Name
    #$osType=switch ((Get-CimInstance -ClassName Win32_OperatingSystem).ProductType){
    #    1 {'client'}
    #    2 {'domaincontroller'}
    #    3 {'memberserver'}
    #    }
  
    $windowsVersion=(Get-CimInstance Win32_OperatingSystem).Version
  
    switch ($releaseId){
        1607{write-host 'Windows Server 2016 Release 1607 detected';$link=$rsatWs2016;break}
        1709{write-host 'Windows Server 2016 Release 1709 detected';$link=$rsat1709;break}
        1803{write-host 'Windows Server 2016 Release 1803 detected';$link=$rsat1803}
    }
      
    switch ($osVersionMajorMinor){
        {$_ -eq 6.0}{write-host 'Windows Server 2008 or Windows Vista detected';$link=$rsat1709;break}
        {$_ -eq 6.1}{write-host 'Windows Server 2008 R2 or Windows 7 detected';$link=$rsatWindows7x64;break}
        {$_ -eq 6.2}{write-host 'Windows Server 2012 or Windows 8.1 detected';$link=$rsatWindows81;break}
        {$_ -eq 6.3}{write-host 'Windows Server 2012 R2 detected';$link=$rsatWindows81}
    }
 
    if (!(Get-Module -ListAvailable -Name ActiveDirectory -EA SilentlyContinue)){
        Write-host "Prerequisite checks: module ActiveDirectory NOT currently available on this system. Please wait while the program adds that plugin..."
        try{
            # If OS is Windows Server, then install RSAT using a different method
            if ($osName -match "^Microsoft Windows Server") {
                # This sequence has confirmed to be valid on Windows Server 2008 R2 and above
                Write-Verbose "Importing Windows Feature: RSAT-AD-PowerShell"
                Import-Module ServerManager
                Add-WindowsFeature RSAT-AD-PowerShell
                }
            else{
                Write-Verbose "This sequence targets Windows Client versions"
                $destinationFile= ($ENV:USERPROFILE) + "\Downloads\" + (split-path $link -leaf)
                Write-Host "Downloading RSAT from $link..."
                Start-BitsTransfer -Source $link -Destination $destinationFile
                $fileCheck=Get-AuthenticodeSignature $destinationFile
                if($fileCheck.status -ne "valid") {write-host "$destinationFile is not valid. Please try again...";break}
                $wusaCommand = $destinationFile + " /quiet"
                Write-host "Installing RSAT - please wait..."
                Start-Process -FilePath "C:\Windows\System32\wusa.exe" -ArgumentList $wusaCommand -Wait
                }
            return $true
            }
        catch{
            write-warning "$($error[0].Exception)"
            return $false
            }
    }else{
        Write-host "Prerequisite checks: module ActiveDirectory IS currently available on this system." -ForegroundColor Green
        return $true
        }
}

function getAllVms([string[]]$clusterName,$verbose=$true){
    
    if(!$clusterName -or $clusterName -eq '*'){
        $result=@()
        $domains=(Get-ADForest).Name|%{(Get-ADForest -Identity $_).Name}        
        foreach ($domain in $domains){
            write-host "Collecting all Hyper-V Clusters in $domain. This may take a while, depending on cluster sizes."
            $allClusters=(get-cluster -domain $domain).Name
            if($verbose){
                $elapsed=[math]::round($timer.Elapsed.TotalMinutes,2)
                write-host "Minutes elapsed $elapsed`: cluster names collected"
                }
            $nodes=$allClusters|%{try{Get-ClusterGroup -Cluster $_ -ea SilentlyContinue|?{$_.GroupType -eq 'VirtualMachine'}}catch{}}
            if($verbose){
                $elapsed=[math]::round($timer.Elapsed.TotalMinutes,2)
                write-host "Minutes elapsed $elapsed`: Node and VM names collected for $domain"
                }
            $result+=$nodes
            }
        return $result
    }else{
        $nodes=$clusterName|%{Get-ClusterGroup -Cluster $_ -ea SilentlyContinue}|?{$_.GroupType -eq 'VirtualMachine'}
        if($verbose){
            $elapsed=[math]::round($timer.Elapsed.TotalMinutes,2)
            write-host "Minutes elapsed $elapsed`: Node and VM names collected for $domain"
            }
        return $nodes
        }
    
}

getAllVms $clusterName

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Post

Python Module: Datetime

Datetime Programs often include dates and time to perform interactive greetings, calculate age, stamping backups,…

PowerShell: Connect to Office 365 Exchange Online

function disconnectExchangeOnline{ <# manually check sessions PS C:\Windows\system32> Get-PSSession Id Name ComputerName ComputerType State ConfigurationName…

How to Clone VMWare Virtual Machine using CLI

1. SSH into the ESXi host to perform VM cloning via Command Line Interface (CLI)…
Other project: DragonCoin.com