# 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
Categories: