Diag-V.psm1
<#
.Synopsis Evaluates if local device is a member of a cluster or a standalone server .DESCRIPTION Evaluates several factors to determine if device is a member of a cluster or acting as a standalone server. The cluster service is evaluated, and if present the cluster nodes will be tested to determine if the local device is a member. If the cluster service is not running the cluster registry location is evaluated to determine if the server's cluster membership status. .EXAMPLE Test-IsACluster Returns boolean if local device is part of a cluster .OUTPUTS System.Boolean .NOTES Author: Jake Morrison - @jakemorrison - http://techthoughts.info/ The design of this function intends the function to be run on the device that is being evaluated .COMPONENT Diag-V - https://github.com/techthoughts2/Diag-V .LINK http://techthoughts.info/diag-v/ #> function Test-IsACluster { [CmdletBinding()] param () #------------------------------- #assume device is not a cluster [bool]$clusterEval = $false $nodes = $null $clusterCheck = $null $clusterNodeNames = $null #------------------------------- $hostName = $env:COMPUTERNAME Write-Verbose -Message "HostName is: $hostName" Write-Verbose -Message 'Verifying presence of cluster service...' $clusterCheck = Get-Service -Name ClusSvc -ErrorAction SilentlyContinue if ($null -ne $clusterCheck) { Write-Verbose -Message 'Cluster Service found.' Write-Verbose -Message 'Checking cluster service status...' if ($clusterCheck.Status -eq "Running") { Write-Verbose -Message 'Cluster serivce running.' Write-Verbose -Message 'Evaluating cluster nodes...' $nodes = Get-ClusterNode -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name if ($null -ne $nodes) { Write-Verbose -Message 'Cluster nodes detected. Evaluating if this device is among them...' foreach ($node in $nodes) { if ($hostName -eq $node) { $clusterEval = $true Write-Verbose -Message 'Hostname was found among cluster nodes.' Write-Verbose -Message "Cluster evaluation: $clusterEval" }#if_hostname else { Write-Verbose -Message 'Hostname was not found among cluster nodes.' }#else_hostname }#foreach_node Write-Verbose -Message 'Cluster node evaulation complete.' }#if_nodes_null else { Write-Verbose -Message 'No cluster nodes were found. This is not a cluster.' Write-Verbose -Message "Cluster evaluation: $clusterEval" }#else_nodes_null }#if_clusterServiceRunning else { Write-Verbose -Message 'Cluster service is not running. Cluster cmdlets not possible. Switching to registry evaluation...' $clusterRegistryPath = 'HKLM:\SYSTEM\CurrentControlSet\Services\ClusSvc\Parameters' $clusterNodeNames = Get-ItemProperty -Path $clusterRegistryPath -ErrorAction SilentlyContinue | Select-Object -ExpandProperty NodeNames -ErrorAction Stop if ($null -ne $clusterNodeNames) { foreach ($node in $clusterNodeNames) { if ($clusterNodeNames -eq $hostName) { $clusterEval = $true Write-Verbose -Message 'Hostname was found in cluster registy settings' Write-Verbose -Message "Cluster evaluation: $clusterEval" }#if_hostname else { Write-Verbose -Message 'Hostname was not found in cluster registry settings.' }#else_hostname }#foreach_node }#if_nodeNames else { Write-Verbose -Message 'No cluster names were returned from the registy. This is not a cluster.' Write-Verbose -Message "Cluster evaluation: $clusterEval" }#else_nodeNames }#else_clusterServiceRunning }#clusterServiceCheck else { Write-Verbose -Message 'No cluster service was found.' Write-Verbose -Message "Cluster evaluation: $clusterEval" }#clusterServiceCheck return $clusterEval }#Test-IsACluster <# .Synopsis Tests if PowerShell Session is running as Admin .DESCRIPTION Evaluates if current PowerShell session is running under the context of an Administrator .EXAMPLE Test-RunningAsAdmin This will verify if the current PowerShell session is running under the context of an Administrator .OUTPUTS System.Boolean .NOTES Author: Jake Morrison - @jakemorrison - http://techthoughts.info/ .COMPONENT Diag-V - https://github.com/techthoughts2/Diag-V .LINK http://techthoughts.info/diag-v/ #> function Test-RunningAsAdmin { [CmdletBinding()] Param() $result = $false #assume the worst try { Write-Verbose -Message "Testing if current PS session is running as admin..." $eval = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if ($eval -eq $true) { Write-Verbose -Message "PS Session is running as Administrator." $result = $true }#if_eval else { Write-Verbose -Message "PS Session is NOT running as Administrator" }#else_eval }#try_security_principal catch { Write-Verbose -Message "Error encountering evaluating runas status of PS session" Write-Error $_ }#catch_security_principal return $result } <# .EXTERNALHELP Diag-V-help.xml #> function Get-AllVHD { [CmdletBinding()] param ( [Parameter(Mandatory = $false, HelpMessage = 'No formatting of return object')] [switch]$NoFormat, [Parameter(Mandatory = $false, HelpMessage = 'PSCredential object for storing provided creds')] [pscredential]$Credential ) Write-Verbose -Message 'Processing pre-checks. This may take a few seconds...' $adminEval = Test-RunningAsAdmin if ($adminEval -eq $true) { $vmCollection = @() $clusterEval = Test-IsACluster if ($clusterEval -eq $true) { Write-Verbose -Message 'Cluster detected. Executing cluster appropriate diagnostic...' Write-Verbose -Message 'Getting all cluster nodes in the cluster...' $nodes = Get-ClusterNode -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name if ($null -ne $nodes) { Write-Warning -Message 'Getting VM Information. This can take a few moments...' Foreach ($node in $nodes) { $rawVM = $null $connTest = $false if ($env:COMPUTERNAME -ne $node) { Write-Verbose -Message "Performing connection test to node $node ..." $connTest = Test-NetConnection -ComputerName $node -InformationLevel Quiet }#if_local else { Write-Verbose -Message 'Local device.' $connTest = $true }#else_local if ($connTest -ne $false) { Write-Verbose -Message 'Connection succesful.' Write-Verbose -Message "Getting VM Information from node $node..." try { if ($Credential -and $env:COMPUTERNAME -ne $node) { $rawVM = Get-VM -ComputerName $node -Credential $Credential -ErrorAction Stop }#if_Credential else { $rawVM = Get-VM -ComputerName $node -ErrorAction Stop }#else_Credential }#try_Get-VM catch { Write-Warning "An issue was encountered getting VM information from $node :" Write-Error $_ return }#catch_Get-VM if ($rawVM) { Write-Verbose -Message 'Processing VM return data...' ##################################### foreach ($vm in $rawVM) { #_____________________________________________________________ $vmname = "" $vmname = $vm.VMName #resets $object = New-Object -TypeName PSObject Write-Verbose -Message "Retrieving VHD information for VM: $vmname" try { if ($Credential -and $env:COMPUTERNAME -ne $node) { $rawVHD = Get-VHD -ComputerName $node -VMId $VM.VMId -Credential $Credential -ErrorAction Stop }#if_Credential else { $rawVHD = Get-VHD -ComputerName $node -VMId $VM.VMId -ErrorAction Stop }#else_Credential }#try_Get-VHD catch { Write-Warning -Message "An error was encountered getting VHD information for: $vmname" }#catch_Get-VHD $object | Add-Member -MemberType NoteProperty -name Name -Value $vmname -Force foreach ($vhd in $rawVHD) { Write-Verbose -Message 'Processing VHD.' #________________ $vhdType = '' $size = 0 $maxSize = 0 $path = '' $object = New-Object -TypeName PSObject #________________ ##################################################### $vhdType = $vhd.VhdType [int]$size = $vhd.filesize / 1gb [int]$maxSize = $vhd.size / 1gb $path = $vhd.Path $object | Add-Member -MemberType NoteProperty -name Host -Value $node -Force $object | Add-Member -MemberType NoteProperty -name Name -Value $vmname -Force $object | Add-Member -MemberType NoteProperty -name VhdType -Value $vhdType -Force $object | Add-Member -MemberType NoteProperty -name 'Size(GB)' -Value $size -Force $object | Add-Member -MemberType NoteProperty -name 'MaxSize(GB)' -Value $maxSize -Force $object | Add-Member -MemberType NoteProperty -name Path -Value $path -Force $vmCollection += $object ##################################################### $currentS += $size $potentialS += $maxSize ##################################################### }#foreachVHD #_____________________________________________________________ Write-Verbose -Message 'VM Information processed.' #_____________________________________________________________ $vmCollection += $object #_____________________________________________________________ }#foreachVM }#if_rawVM else { Write-Verbose "No VMs were returned from $node" }#else_rawVM }#if_connection else { Write-Warning -Message "Connection test to $node unsuccesful." }#else_connection }#foreach_Node if ($vmCollection -ne '') { ##################################### $object = New-Object -TypeName PSObject $object | Add-Member -MemberType NoteProperty -name 'TotalVHD(GB)' -Value $currentS -Force $object | Add-Member -MemberType NoteProperty -name 'TotalPotentialVHD(GB)' -Value $potentialS -Force $vmCollection += $object ##################################### }#if_nullCheck }#if_nodeNULLCheck else { Write-Warning -Message 'Device appears to be configured as a cluster but no cluster nodes were returned by Get-ClusterNode' return }#else_nodeNULLCheck }#if_cluster else { Write-Verbose -Message 'Standalone server detected. Executing standalone diagnostic...' Write-Verbose -Message 'Getting VM Information...' try { $rawVM = Get-VM -ErrorAction Stop }#try_Get-VM catch { Write-Warning 'An issue was encountered getting VM information:' Write-Error $_ return }#catch_Get-VM if ($rawVM) { Write-Verbose -Message 'Processing VM return data...' ##################################### $currentS = 0 $potentialS = 0 foreach ($vm in $rawVM) { #_____________________________________________________________ $vmname = "" $vmname = $vm.VMName #resets $object = New-Object -TypeName PSObject Write-Verbose -Message "Retrieving VHD information for VM: $vmname" try { $rawVHD = Get-VHD -VMId $VM.VMId -ErrorAction Stop }#try_Get-VHD catch { Write-Warning -Message "An error was encountered getting VHD information for: $vmname" }#catch_Get-VHD $object | Add-Member -MemberType NoteProperty -name Name -Value $vmname -Force foreach ($vhd in $rawVHD) { Write-Verbose -Message 'Processing VHD.' #________________ $vhdType = '' $size = 0 $maxSize = 0 $path = '' $object = New-Object -TypeName PSObject #________________ ##################################################### $vhdType = $vhd.VhdType [int]$size = $vhd.filesize / 1gb [int]$maxSize = $vhd.size / 1gb $path = $vhd.Path $object | Add-Member -MemberType NoteProperty -name Name -Value $vmname -Force $object | Add-Member -MemberType NoteProperty -name VhdType -Value $vhdType -Force $object | Add-Member -MemberType NoteProperty -name 'Size(GB)' -Value $size -Force $object | Add-Member -MemberType NoteProperty -name 'MaxSize(GB)' -Value $maxSize -Force $object | Add-Member -MemberType NoteProperty -name Path -Value $path -Force $vmCollection += $object ##################################################### $currentS += $size $potentialS += $maxSize ##################################################### }#foreachVHD #_____________________________________________________________ Write-Verbose -Message 'VM Information processed.' #_____________________________________________________________ $vmCollection += $object #_____________________________________________________________ }#foreachVM ##################################### $object = New-Object -TypeName PSObject $object | Add-Member -MemberType NoteProperty -name 'TotalVHD(GB)' -Value $currentS -Force $object | Add-Member -MemberType NoteProperty -name 'TotalPotentialVHD(GB)' -Value $potentialS -Force $vmCollection += $object ##################################### }#if_rawVM else { Write-Verbose -Message 'No VMs were found on this device.' }#else_rawVM }#clusterEval }#administrator check else { Write-Warning -Message 'Not running as administrator. No further action can be taken.' return }#administrator check if ($NoFormat) { $final = $vmCollection }#if_NoFormat else { $final = $vmCollection | Format-Table }#else_NoFormat return $final }#Get-AllVHD <# .EXTERNALHELP Diag-V-help.xml #> function Get-BINSpaceInfo { [CmdletBinding()] param ( [Parameter(Mandatory = $true, HelpMessage = 'StorageSavings for calculating space savings, VMInfo for VM BIN configuration information')] [ValidateSet('StorageSavings', 'VMInfo')] [string]$InfoType, [Parameter(Mandatory = $false, HelpMessage = 'PSCredential object for storing provided creds')] [pscredential]$Credential ) Write-Verbose -Message 'Processing pre-checks. This may take a few seconds...' $adminEval = Test-RunningAsAdmin if ($adminEval -eq $true) { $vmCollection = @() $objCollection = @() $vmMemory = 0 $clusterEval = Test-IsACluster if ($clusterEval -eq $true) { Write-Verbose -Message 'Cluster detected. Executing cluster appropriate diagnostic...' Write-Verbose -Message 'Getting all cluster nodes in the cluster...' $nodes = Get-ClusterNode -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name if ($null -ne $nodes) { Write-Warning -Message 'Getting VM Information. This can take a few moments...' Foreach ($node in $nodes) { $rawVM = $null $connTest = $false if ($env:COMPUTERNAME -ne $node) { Write-Verbose -Message "Performing connection test to node $node ..." $connTest = Test-NetConnection -ComputerName $node -InformationLevel Quiet }#if_local else { Write-Verbose -Message 'Local device.' $connTest = $true }#else_local if ($connTest -ne $false) { Write-Verbose -Message 'Connection succesful.' Write-Verbose -Message "Getting VM Information from node $node..." try { if ($Credential -and $env:COMPUTERNAME -ne $node) { $rawVM = Get-VM -ComputerName $node -Credential $Credential -ErrorAction Stop }#if_Credential else { $rawVM = Get-VM -ComputerName $node -ErrorAction Stop }#else_Credential }#try_Get-VM catch { Write-Warning "An issue was encountered getting VM information from $node :" Write-Error $_ return }#catch_Get-VM if ($rawVM) { $object = New-Object -TypeName PSObject Write-Verbose -Message 'Processing VM return data...' ##################################### foreach ($vm in $rawVM) { #_____________________________________________________________ $vmname = "" $vmname = $vm.name Write-Verbose -Message "Retrieving information for VM: $vmname" if ($vm.AutomaticStopAction -eq "Save") { $vmMemory += [math]::round($vm.MemoryAssigned / 1GB, 0) } #_____________________________________________________________ Write-Verbose -Message 'VM Information processed.' #_____________________________________________________________ }#foreachVM $vmCollection += $rawVM $computerName = $vm | Select-Object -ExpandProperty ComputerName $object | Add-Member -MemberType NoteProperty -name ComputerName -Value $node -Force $object | Add-Member -MemberType NoteProperty -name StorageSavings -Value "$vmMemory GB" -Force $objCollection += $object ##################################### }#if_rawVM else { Write-Verbose "No VMs were returned from $node" }#else_rawVM }#if_connection else { Write-Warning -Message "Connection test to $node unsuccesful." }#else_connection }#foreach_Node }#if_nodeNULLCheck else { Write-Warning -Message 'Device appears to be configured as a cluster but no cluster nodes were returned by Get-ClusterNode' return }#else_nodeNULLCheck }#if_cluster else { $object = New-Object -TypeName PSObject Write-Verbose -Message 'Standalone server detected. Executing standalone diagnostic...' Write-Verbose -Message 'Getting VM Information...' try { $rawVM = Get-VM -ErrorAction Stop }#try_Get-VM catch { Write-Warning 'An issue was encountered getting VM information:' Write-Error $_ return }#catch_Get-VM if ($rawVM) { Write-Verbose -Message 'Processing VM return data...' ##################################### foreach ($vm in $rawVM) { #_____________________________________________________________ $vmname = "" $vmname = $vm.name Write-Verbose -Message "Retrieving information for VM: $vmname" if ($vm.AutomaticStopAction -eq "Save") { $vmMemory += [math]::round($vm.MemoryAssigned / 1GB, 0) } #_____________________________________________________________ Write-Verbose -Message 'VM Information processed.' #_____________________________________________________________ }#foreachVM $vmCollection += $rawVM $computerName = $vm | Select-Object -ExpandProperty ComputerName $object | Add-Member -MemberType NoteProperty -name ComputerName -Value $env:COMPUTERNAME -Force $object | Add-Member -MemberType NoteProperty -name StorageSavings -Value "$vmMemory GB" -Force $objCollection = $object ##################################### }#if_rawVM else { Write-Verbose -Message 'No VMs were found on this device.' }#else_rawVM }#clusterEval }#administrator check else { Write-Warning -Message 'Not running as administrator. No further action can be taken.' return }#administrator check switch ($InfoType) { 'StorageSavings' { $final = $objCollection }#StorageSavings 'VMInfo' { $final = $vmCollection | Select-Object ComputerName, VMName, AutomaticStopAction, @{ Label = "Memory Assigned"; Expression = { '{0:N0}' -F ($_.MemoryAssigned / 1GB) } } }#VMInfo }#switch_InfoType return $final }#Get-BINSpaceInfo <# .EXTERNALHELP Diag-V-help.xml #> function Get-CSVInfo { [cmdletbinding()] param ( [Parameter(Mandatory = $false, HelpMessage = 'PSCredential object for storing provided creds')] [pscredential]$Credential ) Write-Verbose -Message 'Processing pre-checks. This may take a few seconds...' $adminEval = Test-RunningAsAdmin if ($adminEval -eq $true) { $clusterEval = Test-IsACluster if ($clusterEval -eq $true) { Write-Verbose -Message "Cluster detected. Performing CSV discovery..." try { $clusterSharedVolume = Get-ClusterSharedVolume -ErrorAction Stop }#try_Get-ClusterSharedVolume catch { Write-Warning -Message 'An error was encountered retrieving CSV information:' Write-Error $_ return }#catch_Get-ClusterSharedVolume if ($null -ne $clusterSharedVolume) { $results = @() foreach ($csv in $clusterSharedVolume) { #___________________________________________________ $volumeowner = $null $csvVolume = $null $cimSession = $null $volumeInfo = $null $csvdisknumber = $null $csvtophysicaldisk = $null #___________________________________________________ $volumeowner = $csv.OwnerNode.Name #___________________________________________________ $csvVolume = $csv.SharedVolumeInfo.Partition.Name #___________________________________________________ try { if ($Credential) { $cimSession = New-CimSession -Credential $Credential -ComputerName $volumeowner -ErrorAction Stop }#if_Credential else { $cimSession = New-CimSession -ComputerName $volumeowner -ErrorAction Stop }#else_Credential $volumeInfo = Get-Disk -CimSession $cimSession -ErrorAction Stop ` | Get-Partition -ErrorAction Stop ` | Select-Object DiskNumber, @{Name = "Volume"; Expression = {Get-Volume -Partition $_ -ErrorAction Stop}} $csvdisknumber = ($volumeinfo | Where-Object { $_.volume.path -eq $csvVolume -or $_.volume.ObjectID -eq $csvVolume }).Disknumber $fileSystemType = ($volumeinfo | Where-Object { $_.volume.path -eq $csvVolume -or $_.volume.ObjectID -eq $csvVolume }).Volume.FileSystemType #___________________________________________________ $csvtophysicaldisk = New-Object -TypeName PSObject -Property @{ "CSVName" = $csv.Name "CSVOwnerNode" = $volumeowner "CSVVolumePath" = $csv.SharedVolumeInfo.FriendlyVolumeName "FileSystemType" = $fileSystemType "CSVPhysicalDiskNumber" = $csvdisknumber "CSVPartitionNumber" = $csv.SharedVolumeInfo.PartitionNumber "Size (GB)" = [int]($csv.SharedVolumeInfo.Partition.Size / 1GB) "FreeSpace (GB)" = [int]($csv.SharedVolumeInfo.Partition.Freespace / 1GB) "Percent Free" = $csv.SharedVolumeInfo.Partition.PercentFree } #___________________________________________________ }#try_All catch { Write-Warning -Message 'An error was encountered:' Write-Error $_ return }#catch_All $results += $csvtophysicaldisk }#foreach_CSV }#if_nullCheck else { Write-Warning -Message 'No CSVs discovered.' return }#else_nullCheck }#if_cluster else { Write-Warning "No cluster detected. This function is only applicable to clusters with CSVs." return }#clusterEval }#administrator check else { Write-Warning -Message 'Not running as administrator. No further action can be taken.' return }#administrator check return $results }#Get-CSVInfo <# .EXTERNALHELP Diag-V-help.xml #> function Get-FileSizeInfo { [cmdletbinding()] Param ( #directory path that you wish to scan [Parameter(Mandatory = $true, HelpMessage = "Please enter a path (Ex: C:\ClusterStorage\Volume1)", ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0) ] [string]$Path ) Write-Verbose -Message 'Verifying that path specified exists...' if (Test-Path $path) { Write-Verbose -Message "Path verified." Write-Warning -Message 'This can take some time depending on how many files are in the path you specified.' Write-Verbose -Message "Getting files..." $files = Get-ChildItem -Path $path -Recurse -Force -ErrorAction SilentlyContinue if ($null -ne $files) { Write-Verbose -Message "Processing files..." #___________________ [double]$intSize = 0 $results = @() #___________________ foreach ($objFile in $files) { $intSize = $intSize + $objFile.Length }#foreach_File #___________________ $intSize = [math]::round($intSize / 1GB, 0) #___________________ $results += $files ` | Select-Object Directory, Name, @{Label = 'Size(MB)'; Expression = {[math]::round($_.Length / 1MB, 2)}} ` | Sort-Object 'Size(MB)' -Descending | Select-Object -First 10 $results += "Total size of all files: $intSize GB" #___________________ }#if_Null else { Write-Warning "No files were found at the specified location." return }#else_Null }#if_Test-Path else { Write-Warning "The path specified is not valid." return }#else_Test-Path return $results }#Get-FileSizeInfo <# .EXTERNALHELP Diag-V-help.xml #> function Get-HyperVLogInfo { [cmdletbinding()] param ( [Parameter(Mandatory = $false, HelpMessage = 'Hostname of destination machine')] [string]$HostName = $env:COMPUTERNAME, [Parameter(Mandatory = $false, HelpMessage = 'Admin credentials for destination machine')] [pscredential]$Credential, [Parameter(Mandatory = $false, HelpMessage = 'Name of logs you wish to pull results from')] [string[]]$LogName = "*Hyper-v*", [Parameter(Mandatory = $false, HelpMessage = 'Log level you wish to query')] [ValidateRange(1, 5)] [int[]]$Level = (1, 2, 3), [Parameter(Mandatory = $false, HelpMessage = 'Starting DateTime')] [datetime]$StartDate = (Get-Date).AddDays(-1), [Parameter(Mandatory = $false, HelpMessage = 'Ending DateTime')] [datetime]$EndDate = (Get-Date) ) Write-Verbose -Message "Building filter..." $finalLogString = @() foreach ($log in $LogName) { $finalLogString += $log }#foreach_LogName $finalLevel = @() foreach ($number in $Level) { $finalLevel += $number }#foreach_Level Write-Verbose -Message "Log Name: $finalLogString" Write-Verbose -Message "Level: $finalLevel" Write-Verbose -Message "StartTime: $StartDate" Write-Verbose -Message "EndTime: $EndDate" #create filter hashtable $filter = @{ LogName = $finalLogString Level = $finalLevel StartTime = $StartDate EndTime = $EndDate } Write-Verbose -Message "Attempting to gather logs from $HostName ..." try { if ($Credential) { $creds = $Credential Write-Verbose -Message "Credentials set." $a = Get-WinEvent -FilterHashTable $filter -ComputerName $HostName -Credential $creds -ErrorAction Stop } else { $a = Get-WinEvent -FilterHashTable $filter -ComputerName $HostName -ErrorAction Stop } Write-Verbose -Message "Log capture complete." }#try_Get-WinEvent catch { Write-Verbose $_ if ($_.Exception -like "*that match*") { $a = $null }#if_error_no_match else { Write-Warning "An error was encountered capturing logs from $HostName" Write-Error $_ return }#else_error_no_match }#catch_Get-WinEvent if ($a) { Write-Verbose -Message "Processing logs results..." $results = $a | Select-Object TimeCreated, LogName, ProviderName, LevelDisplayName, Message }#if_logsNull else { Write-Verbose -Message "No logs were found that matched this search criteria." $results = [PSCustomObject]@{ HostName = $HostName LogName = $finalLogString Level = $finalLevel StartTime = $StartDate EndTime = $EndDate Status = "No logs were found that matched this search criteria." } }#else_logsNull return $results }#Get-HyperVLogInfo <# .EXTERNALHELP Diag-V-help.xml #> function Get-IntegrationServicesCheck { [CmdletBinding()] param ( [Parameter(Mandatory = $false, HelpMessage = 'No formatting of return object')] [switch]$NoFormat, [Parameter(Mandatory = $false, HelpMessage = 'PSCredential object for storing provided creds')] [pscredential]$Credential ) Write-Verbose -Message 'Processing pre-checks. This may take a few seconds...' $adminEval = Test-RunningAsAdmin if ($adminEval -eq $true) { $vmCollection = @() $clusterEval = Test-IsACluster if ($clusterEval -eq $true) { Write-Verbose -Message 'Cluster detected. Executing cluster appropriate diagnostic...' Write-Verbose -Message 'Getting all cluster nodes in the cluster...' $nodes = Get-ClusterNode -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name if ($null -ne $nodes) { Write-Warning -Message "Getting VM Information. This can take a few moments..." Foreach ($node in $nodes) { $rawVM = $null $connTest = $false if ($env:COMPUTERNAME -ne $node) { Write-Verbose -Message "Performing connection test to node $node ..." $connTest = Test-NetConnection -ComputerName $node -InformationLevel Quiet }#if_local else { Write-Verbose -Message 'Local device.' $connTest = $true }#else_local if ($connTest -ne $false) { Write-Verbose -Message 'Connection succesful.' Write-Verbose -Message "Getting VM Information from node $node..." try { if ($Credential -and $env:COMPUTERNAME -ne $node) { $rawVM = Get-VM -ComputerName $node -Credential $Credential -ErrorAction Stop }#if_Credential else { $rawVM = Get-VM -ComputerName $node -ErrorAction Stop }#else_Credential }#try_Get-VM catch { Write-Warning "An issue was encountered getting VM information from $node :" Write-Error $_ return }#catch_Get-VM if ($rawVM) { Write-Verbose -Message 'Processing VM return data...' ##################################### foreach ($vm in $rawVM) { #_____________________________________________________________ $vmname = "" $vmname = $vm.VMName $rawIntegration = $null Write-Verbose -Message "Retrieving information for VM: $vmname" #_____________________________________________________________ try { if ($Credential -and $env:COMPUTERNAME -ne $node) { $rawIntegration = Get-VMIntegrationService -ComputerName $node -VMName $vmname -Credential $Credential -ErrorAction Stop }#if_Credential else { $rawIntegration = Get-VMIntegrationService -ComputerName $node -VMName $vmname -ErrorAction Stop }#else_Credential }#try_Get-VMIntegrationService catch { Write-Warning 'An issue was encountered getting VM information:' Write-Error $_ return }#catch_Get-VMIntegrationService $rawCombine = $rawIntegration + $vm $cObj = $rawCombine | Select-Object ComputerName, VMName, Name, Enabled, PrimaryStatusDescription, IntegrationServicesVersion #_____________________________________________________________ Write-Verbose -Message 'VM Information processed.' #_____________________________________________________________ $vmCollection += $cObj #_____________________________________________________________ }#foreachVM ##################################### }#if_rawVM else { Write-Verbose "No VMs were returned from $node" }#else_rawVM }#if_connection else { Write-Warning -Message "Connection test to $node unsuccesful." }#else_connection }#foreach_Node }#if_nodeNULLCheck else { Write-Warning -Message 'Device appears to be configured as a cluster but no cluster nodes were returned by Get-ClusterNode' return }#else_nodeNULLCheck }#if_cluster else { Write-Verbose -Message 'Standalone server detected. Executing standalone diagnostic...' Write-Verbose -Message 'Getting VM Information...' try { $rawVM = Get-VM -ErrorAction Stop }#try_Get-VM catch { Write-Warning 'An issue was encountered getting VM information:' Write-Error $_ return }#catch_Get-VM if ($rawVM) { Write-Verbose -Message 'Processing VM return data...' ##################################### foreach ($vm in $rawVM) { #_____________________________________________________________ $vmname = "" $vmname = $vm.VMName $rawIntegration = $null Write-Verbose -Message "Retrieving information for VM: $vmname" #_____________________________________________________________ try { $rawIntegration = Get-VMIntegrationService -VMName $vmname -ErrorAction Stop }#try_Get-VMIntegrationService catch { Write-Warning 'An issue was encountered getting VM information:' Write-Error $_ return }#catch_Get-VMIntegrationService $rawCombine = $rawIntegration + $vm $cObj = $rawCombine | Select-Object ComputerName, VMName, Name, Enabled, PrimaryStatusDescription, IntegrationServicesVersion #_____________________________________________________________ Write-Verbose -Message 'VM Information processed.' #_____________________________________________________________ $vmCollection += $cObj #_____________________________________________________________ }#foreachVM ##################################### }#if_rawVM else { Write-Verbose -Message 'No VMs were found on this device.' }#else_rawVM }#clusterEval }#administrator check else { Write-Warning -Message 'Not running as administrator. No further action can be taken.' return }#administrator check Write-Verbose -Message 'Processing results for return' if ($NoFormat) { $final = $vmCollection }#if_NoFormat else { $final = $vmCollection | Format-Table }#else_NoFormat return $final }#Get-IntegrationServicesCheck <# .EXTERNALHELP Diag-V-help.xml #> function Get-SharedVHD { [CmdletBinding()] param ( [Parameter(Mandatory = $false, HelpMessage = 'PSCredential object for storing provided creds')] [pscredential]$Credential ) Write-Verbose -Message 'Processing pre-checks. This may take a few seconds...' $adminEval = Test-RunningAsAdmin if ($adminEval -eq $true) { $vmCollection = @() $clusterEval = Test-IsACluster if ($clusterEval -eq $true) { Write-Verbose -Message 'Cluster detected. Executing cluster appropriate diagnostic...' Write-Verbose -Message 'Getting all cluster nodes in the cluster...' $nodes = Get-ClusterNode -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name if ($null -ne $nodes) { Write-Warning -Message 'Getting VM Information. This can take a few moments...' Foreach ($node in $nodes) { $rawVM = $null $connTest = $false if ($env:COMPUTERNAME -ne $node) { Write-Verbose -Message "Performing connection test to node $node ..." $connTest = Test-NetConnection -ComputerName $node -InformationLevel Quiet }#if_local else { Write-Verbose -Message 'Local device.' $connTest = $true }#else_local if ($connTest -ne $false) { Write-Verbose -Message 'Connection succesful.' Write-Verbose -Message "Getting VM Information from node $node..." try { if ($Credential -and $env:COMPUTERNAME -ne $node) { $rawVM = Get-VM -ComputerName $node -Credential $Credential -ErrorAction Stop }#if_Credential else { $rawVM = Get-VM -ComputerName $node -ErrorAction Stop }#else_Credential }#try_Get-VM catch { Write-Warning "An issue was encountered getting VM information from $node :" Write-Error $_ return }#catch_Get-VM if ($rawVM) { Write-Verbose -Message 'Processing VM return data...' ##################################### foreach ($vm in $rawVM) { #_____________________________________________________________ $vmname = "" $vmname = $vm.VMName #resets $object = New-Object -TypeName PSObject Write-Verbose -Message "Retrieving VHD information for VM: $vmname" try { if ($Credential -and $env:COMPUTERNAME -ne $node) { $rawVMDisk = Get-VMHardDiskDrive -ComputerName $node -VMName $vmname -Credential $Credential -ErrorAction Stop }#if_Credential else { $rawVMDisk = Get-VMHardDiskDrive -ComputerName $node -VMName $vmname -ErrorAction Stop }#else_Credential }#try_Get-VMHardDiskDrive catch { Write-Warning -Message "An error was encountered getting VHD disk information for: $vmname" }#catch_Get-VMHardDiskDrive $object | Add-Member -MemberType NoteProperty -name Name -Value $vmname -Force foreach ($vhd in $rawVMDisk) { Write-Verbose -Message 'Processing VHD.' #________________ $pReservation = $null $path = '' $object = New-Object -TypeName PSObject #________________ ##################################################### #$vhdType = $vhd.VhdType $pReservation = $vhd.SupportPersistentReservations $path = $vhd.Path $object | Add-Member -MemberType NoteProperty -name Host -Value $node -Force $object | Add-Member -MemberType NoteProperty -name Name -Value $vmname -Force $object | Add-Member -MemberType NoteProperty -name SupportPersistentReservations -Value $pReservation -Force $object | Add-Member -MemberType NoteProperty -name Path -Value $path -Force $vmCollection += $object ##################################################### $currentS += $size $potentialS += $maxSize ##################################################### }#foreachVHD #_____________________________________________________________ Write-Verbose -Message 'VM Information processed.' #_____________________________________________________________ $vmCollection += $object #_____________________________________________________________ }#foreachVM }#if_rawVM else { Write-Verbose "No VMs were returned from $node" }#else_rawVM }#if_connection else { Write-Warning -Message "Connection test to $node unsuccesful." }#else_connection }#foreach_Node }#if_nodeNULLCheck else { Write-Warning -Message 'Device appears to be configured as a cluster but no cluster nodes were returned by Get-ClusterNode' return }#else_nodeNULLCheck }#if_cluster else { Write-Verbose -Message 'Standalone server detected. Executing standalone diagnostic...' Write-Verbose -Message 'Getting VM Information...' try { $rawVM = Get-VM -ErrorAction Stop }#try_Get-VM catch { Write-Warning 'An issue was encountered getting VM information:' Write-Error $_ return }#catch_Get-VM if ($rawVM) { Write-Verbose -Message 'Processing VM return data...' ##################################### $currentS = 0 $potentialS = 0 foreach ($vm in $rawVM) { #_____________________________________________________________ $vmname = "" $vmname = $vm.VMName #resets $object = New-Object -TypeName PSObject Write-Verbose -Message "Retrieving VHD disk information for VM: $vmname" try { $rawVMDisk = Get-VMHardDiskDrive -VMName $vmname -ErrorAction Stop }#try_Get-VMHardDiskDrive catch { Write-Warning -Message "An error was encountered getting VHD information for: $vmname" }#catch_Get-VMHardDiskDrive $object | Add-Member -MemberType NoteProperty -name Name -Value $vmname -Force foreach ($vhd in $rawVMDisk) { Write-Verbose -Message 'Processing VHD.' #________________ $pReservation = $null $path = '' $object = New-Object -TypeName PSObject #________________ ##################################################### #$vhdType = $vhd.VhdType $pReservation = $vhd.SupportPersistentReservations $path = $vhd.Path $object | Add-Member -MemberType NoteProperty -name Name -Value $vmname -Force $object | Add-Member -MemberType NoteProperty -name SupportPersistentReservations -Value $pReservation -Force $object | Add-Member -MemberType NoteProperty -name Path -Value $path -Force $vmCollection += $object ##################################################### $currentS += $size $potentialS += $maxSize ##################################################### }#foreachVHD #_____________________________________________________________ Write-Verbose -Message 'VM Information processed.' #_____________________________________________________________ $vmCollection += $object #_____________________________________________________________ }#foreachVM }#if_rawVM else { Write-Verbose -Message 'No VMs were found on this device.' }#else_rawVM }#clusterEval }#administrator check else { Write-Warning -Message 'Not running as administrator. No further action can be taken.' return }#administrator check <# if ($NoFormat) { $final = $vmCollection }#if_NoFormat else { $final = $vmCollection | Format-Table }#else_NoFormat #> $final = $vmCollection return $final }#Get-SharedVHD <# .EXTERNALHELP Diag-V-help.xml #> function Get-VMInfo { [CmdletBinding()] param ( [Parameter(Mandatory = $false, HelpMessage = 'PSCredential object for storing provided creds')] [pscredential]$Credential ) filter Import-CimXml { # Filter for parsing XML data # Create new XML object from input $CimXml = [Xml]$_ $CimObj = New-Object System.Management.Automation.PSObject # Iterate over the data and pull out just the value name and data for each entry foreach ($CimProperty in $CimXml.SelectNodes("/INSTANCE/PROPERTY[@NAME='Name']")) { $CimObj | Add-Member -MemberType NoteProperty -Name $CimProperty.NAME -Value $CimProperty.VALUE } foreach ($CimProperty in $CimXml.SelectNodes("/INSTANCE/PROPERTY[@NAME='Data']")) { $CimObj | Add-Member -MemberType NoteProperty -Name $CimProperty.NAME -Value $CimProperty.VALUE #return $CimProperty.VALUE } return $CimObj }#Import-CimXml Write-Verbose -Message 'Processing pre-checks. This may take a few seconds...' $adminEval = Test-RunningAsAdmin if ($adminEval -eq $true) { $vmCollection = @() $clusterEval = Test-IsACluster if ($clusterEval -eq $true) { Write-Verbose -Message 'Cluster detected. Executing cluster appropriate diagnostic...' Write-Verbose -Message 'Getting all cluster nodes in the cluster...' $nodes = Get-ClusterNode -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name if ($null -ne $nodes) { Write-Warning -Message 'Getting VM Information. This can take a few moments...' Foreach ($node in $nodes) { $rawVM = $null $connTest = $false if ($env:COMPUTERNAME -ne $node) { Write-Verbose -Message "Performing connection test to node $node ..." $connTest = Test-NetConnection -ComputerName $node -InformationLevel Quiet }#if_local else { Write-Verbose -Message 'Local device.' $connTest = $true }#else_local if ($connTest -ne $false) { Write-Verbose -Message 'Connection succesful.' Write-Verbose -Message "Getting VM Information from node $node..." try { if ($Credential -and $env:COMPUTERNAME -ne $node) { $rawVM = Get-VM -ComputerName $node -Credential $Credential -ErrorAction Stop }#if_Credential else { $rawVM = Get-VM -ComputerName $node -ErrorAction Stop }#else_Credential }#try_Get-VM catch { Write-Warning "An issue was encountered getting VM information from $node :" Write-Error $_ return }#catch_Get-VM if ($rawVM) { Write-Verbose -Message 'Processing VM return data...' ##################################### foreach ($vm in $rawVM) { #_____________________________________________________________ $vmname = "" $vmname = $vm.name Write-Verbose -Message "Retrieving information for VM: $vmname on node: $node" #_____________________________________________________________ #resets $object = New-Object -TypeName PSObject $cimS = $null $VmCIM = $null $msvmName = $null $kvp = $null $obj = $null $opsName = $null $fqdn = $null $computerName = $null $name = $null $cpu = $null $dyanamic = $null $memMin = $null $memMax = $null $clustered = $null $vmVersion = $null $repHealth = $null $repHealth = $null $vhds = $null #resets $query = "Select * From Msvm_ComputerSystem Where ElementName='" + $vmname + "'" if ($Credential -and $env:COMPUTERNAME -ne $node) { try { $cimS = New-CimSession -ComputerName $node -Credential $Credential -ErrorAction Stop $VmCIM = Get-CimInstance -Namespace root\virtualization\v2 -query $query -CimSession $cimS -ErrorAction SilentlyContinue $msvmName = $VmCIM.Name $kvp = Get-CimInstance -Namespace root\virtualization\v2 -Filter "SystemName like ""$msvmName""" -CimSession $cimS -ClassName Msvm_KvpExchangeComponent } catch { Write-Warning -Message "Unable to establish CIM session to $node" } } else { $VmCIM = Get-CimInstance -Namespace root\virtualization\v2 -query $query -computername $node -ErrorAction SilentlyContinue $msvmName = $VmCIM.Name $kvp = Get-CimInstance -Namespace root\virtualization\v2 -Filter "SystemName like ""$msvmName""" -ComputerName $node -ClassName Msvm_KvpExchangeComponent } if ($null -ne $kvp -and $kvp -ne '') { $obj = $Kvp.GuestIntrinsicExchangeItems | Import-CimXml $opsName = $obj | Where-Object Name -eq OSName | Select-Object -ExpandProperty Data $fqdn = $obj | Where-Object Name -eq FullyQualifiedDomainName | Select-Object -ExpandProperty Data } if ($null -eq $opsName -or $opsName -eq '') { $opsName = "Unknown" } if ($null -eq $fqdn -or $fqdn -eq '') { $fqdn = "Unknown" } #_____________________________________________________________ $computerName = $vm | Select-Object -ExpandProperty ComputerName $object | Add-Member -MemberType NoteProperty -name ComputerName -Value $computerName -Force $name = $vm | Select-Object -ExpandProperty Name $object | Add-Member -MemberType NoteProperty -name Name -Value $name -Force $cpu = $vm | Select-Object -ExpandProperty ProcessorCount $object | Add-Member -MemberType NoteProperty -name CPU -Value $cpu -Force $dyanamic = $vm | Select-Object -ExpandProperty DynamicMemoryEnabled $object | Add-Member -MemberType NoteProperty -name DynamicMemoryEnabled -Value $dyanamic -Force $memMin = [math]::round($vm.MemoryMinimum / 1MB, 0) $object | Add-Member -MemberType NoteProperty -name 'MemoryMinimum(MB)' -Value $memMin -Force $memMax = [math]::round($vm.MemoryMaximum / 1GB, 0) $object | Add-Member -MemberType NoteProperty -name 'MemoryMaximum(GB)' -Value $memMax -Force $clustered = $vm | Select-Object -ExpandProperty IsClustered $object | Add-Member -MemberType NoteProperty -name 'IsClustered' -Value $clustered -Force $vmVersion = $vm | Select-Object -ExpandProperty Version $object | Add-Member -MemberType NoteProperty -name 'Version' -Value $vmVersion -Force $repHealth = $vm | Select-Object -ExpandProperty ReplicationHealth $object | Add-Member -MemberType NoteProperty -name 'ReplicationHealth' -Value $repHealth -Force $object | Add-Member -MemberType NoteProperty -name 'OSName' -Value $opsName -Force $object | Add-Member -MemberType NoteProperty -name 'FQDN' -Value $fqdn -Force #_____________________________________________________________ Write-Verbose -Message 'VM Information processed.' Write-Verbose -Message 'Retrieving VHD information...' $i = 0 try { if ($Credential -and $env:COMPUTERNAME -ne $node) { $vhds = Get-VHD -ComputerName $node -VMId $VM.VMId -Credential $Credential -ErrorAction Stop }#if_Credential else { $vhds = Get-VHD -ComputerName $node -VMId $VM.VMId -ErrorAction Stop }#else_Credential }#try_Get-VHD catch { Write-Warning -Message "An error was encountered getting VHD information from $node :" Write-Error $_ }#catch_Get-VHD foreach ($vhd in $vhds) { $vhdType = $vhd.vhdtype $object | Add-Member -MemberType NoteProperty -name "VHDType-$i" -Value $vhdType -Force #$vhdSize = $vhd.filesize / 1gb -as [int] [int]$vhdSize = $vhd.filesize / 1GB $object | Add-Member -MemberType NoteProperty -name "VHDSize(GB)-$i" -Value $vhdSize -Force #$vhdMaxSize = $vhd.size / 1gb -as [int] [int]$vhdMaxSize = $vhd.size / 1GB $object | Add-Member -MemberType NoteProperty -name "MaxSize(GB)-$i" -Value $vhdMaxSize -Force $i++ }#foreach_VHD Write-Verbose -Message 'VHD info proccessed.' #_____________________________________________________________ $vmCollection += $object #_____________________________________________________________ }#foreachVM ##################################### }#if_rawVM else { Write-Verbose "No VMs were returned from $node" }#else_rawVM }#if_connection else { Write-Warning -Message "Connection test to $node unsuccesful." }#else_connection }#foreach_Node }#if_nodeNULLCheck else { Write-Warning -Message 'Device appears to be configured as a cluster but no cluster nodes were returned by Get-ClusterNode' return }#else_nodeNULLCheck }#if_cluster else { Write-Verbose -Message 'Standalone server detected. Executing standalone diagnostic...' Write-Verbose -Message 'Getting VM Information...' try { $rawVM = Get-VM -ErrorAction Stop }#try_Get-VM catch { Write-Warning 'An issue was encountered getting VM information:' Write-Error $_ return }#catch_Get-VM if ($rawVM) { Write-Verbose -Message 'Processing VM return data...' ##################################### foreach ($vm in $rawVM) { #_____________________________________________________________ $vmname = "" $vmname = $vm.name Write-Verbose -Message "Retrieving information for VM: $vmname" #_____________________________________________________________ #resets $object = New-Object -TypeName PSObject $VmCIM = $null $msvmName = $null $kvp = $null $obj = $null $opsName = $null $fqdn = $null $computerName = $null $name = $null $cpu = $null $dyanamic = $null $memMin = $null $memMax = $null $clustered = $null $vmVersion = $null $repHealth = $null $repHealth = $null $vhds = $null #resets $query = "Select * From Msvm_ComputerSystem Where ElementName='" + $vmname + "'" $VmCIM = Get-CimInstance -Namespace root\virtualization\v2 -query $query -computername $node.name -ErrorAction SilentlyContinue $msvmName = $VmCIM.Name $kvp = $null $kvp = Get-CimInstance -Namespace root\virtualization\v2 -Filter "SystemName like ""$msvmName""" -ClassName Msvm_KvpExchangeComponent #$Kvp = Get-CimInstance -Namespace root\virtualization\v2 -query $query2 -computername $node.name -ErrorAction SilentlyContinue if ($null -ne $kvp -and $kvp -ne '') { $obj = $Kvp.GuestIntrinsicExchangeItems | Import-CimXml $opsName = $obj | Where-Object Name -eq OSName | Select-Object -ExpandProperty Data $fqdn = $obj | Where-Object Name -eq FullyQualifiedDomainName | Select-Object -ExpandProperty Data } if ($null -eq $opsName -or $opsName -eq '') { $opsName = "Unknown" } if ($null -eq $fqdn -or $fqdn -eq '') { $fqdn = "Unknown" } #_____________________________________________________________ $object | Add-Member -MemberType NoteProperty -name Name -Value $vmname -Force $cpu = $vm | Select-Object -ExpandProperty ProcessorCount $object | Add-Member -MemberType NoteProperty -name CPU -Value $cpu -Force $dyanamic = $vm | Select-Object -ExpandProperty DynamicMemoryEnabled $object | Add-Member -MemberType NoteProperty -name DynamicMemoryEnabled -Value $dyanamic -Force $memMin = [math]::round($vm.MemoryMinimum / 1MB, 0) $object | Add-Member -MemberType NoteProperty -name 'MemoryMinimum(MB)' -Value $memMin -Force $memMax = [math]::round($vm.MemoryMaximum / 1GB, 0) $object | Add-Member -MemberType NoteProperty -name 'MemoryMaximum(GB)' -Value $memMax -Force $clustered = $vm | Select-Object -ExpandProperty IsClustered $object | Add-Member -MemberType NoteProperty -name 'IsClustered' -Value $clustered -Force $vmVersion = $vm | Select-Object -ExpandProperty Version $object | Add-Member -MemberType NoteProperty -name 'Version' -Value $vmVersion -Force $repHealth = $vm | Select-Object -ExpandProperty ReplicationHealth $object | Add-Member -MemberType NoteProperty -name 'ReplicationHealth' -Value $repHealth -Force $object | Add-Member -MemberType NoteProperty -name 'OSName' -Value $opsName -Force $object | Add-Member -MemberType NoteProperty -name 'FQDN' -Value $fqdn -Force #_____________________________________________________________ Write-Verbose -Message 'VM Information processed.' Write-Verbose -Message 'Retrieving VHD information...' $i = 0 try { $vhds = Get-VHD -VMId $VM.VMId -ErrorAction Stop }#try_Get-VHD catch { Write-Warning -Message "An error was encountered getting VHD information:" Write-Error $_ }#catch_Get-VHD foreach ($vhd in $vhds) { $vhdType = $vhd.vhdtype $object | Add-Member -MemberType NoteProperty -name "VHDType-$i" -Value $vhdType -Force #$vhdSize = $vhd.filesize / 1gb -as [int] [int]$vhdSize = $vhd.filesize / 1gb $object | Add-Member -MemberType NoteProperty -name "VHDSize(GB)-$i" -Value $vhdSize -Force #$vhdMaxSize = $vhd.size / 1gb -as [int] [int]$vhdMaxSize = $vhd.size / 1gb $object | Add-Member -MemberType NoteProperty -name "MaxSize(GB)-$i" -Value $vhdMaxSize -Force $i++ }#foreach_VHD Write-Verbose -Message 'VHD info proccessed.' #_____________________________________________________________ $vmCollection += $object #_____________________________________________________________ }#foreachVM ##################################### }#if_rawVM else { Write-Verbose -Message 'No VMs were found on this device.' }#else_rawVM }#clusterEval }#administrator check else { Write-Warning -Message 'Not running as administrator. No further action can be taken.' return }#administrator check Write-Verbose -Message 'Processing results for return' $final = $vmCollection return $final }#Get-VMInfo <# .EXTERNALHELP Diag-V-help.xml #> function Get-VMLocationPathInfo { [CmdletBinding()] param ( [Parameter(Mandatory = $false, HelpMessage = 'PSCredential object for storing provided creds')] [pscredential]$Credential ) Write-Verbose -Message 'Processing pre-checks. This may take a few seconds...' $adminEval = Test-RunningAsAdmin if ($adminEval -eq $true) { $vmCollection = @() $clusterEval = Test-IsACluster if ($clusterEval -eq $true) { Write-Verbose -Message 'Cluster detected. Executing cluster appropriate diagnostic...' Write-Verbose -Message 'Getting all cluster nodes in the cluster...' $nodes = Get-ClusterNode -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name if ($null -ne $nodes) { Write-Warning -Message 'Getting VM Information. This can take a few moments...' Foreach ($node in $nodes) { $rawVM = $null $connTest = $false if ($env:COMPUTERNAME -ne $node) { Write-Verbose -Message "Performing connection test to node $node ..." $connTest = Test-NetConnection -ComputerName $node -InformationLevel Quiet }#if_local else { Write-Verbose -Message 'Local device.' $connTest = $true }#else_local if ($connTest -ne $false) { Write-Verbose -Message 'Connection succesful.' Write-Verbose -Message "Getting VM Information from node $node..." try { if ($Credential -and $env:COMPUTERNAME -ne $node) { $rawVM = Get-VM -ComputerName $node -Credential $Credential -ErrorAction Stop }#if_Credential else { $rawVM = Get-VM -ComputerName $node -ErrorAction Stop }#else_Credential }#try_Get-VM catch { Write-Warning "An issue was encountered getting VM information from $node :" Write-Error $_ return }#catch_Get-VM if ($rawVM) { $vmCollection += $rawVM }#if_rawVM else { Write-Verbose "No VMs were returned from $node" }#else_rawVM }#if_connection else { Write-Warning -Message "Connection test to $node unsuccesful." }#else_connection }#foreach_Node }#if_nodeNULLCheck else { Write-Warning -Message 'Device appears to be configured as a cluster but no cluster nodes were returned by Get-ClusterNode' return }#else_nodeNULLCheck }#if_cluster else { Write-Verbose -Message 'Standalone server detected. Executing standalone diagnostic...' Write-Verbose -Message 'Getting VM Information...' try { $rawVM = Get-VM -ErrorAction Stop }#try_Get-VM catch { Write-Warning 'An issue was encountered getting VM information:' Write-Error $_ return }#catch_Get-VM if ($rawVM) { $vmCollection += $rawVM }#if_rawVM else { Write-Verbose -Message 'No VMs were found on this device.' }#else_rawVM }#clusterEval }#administrator check else { Write-Warning -Message 'Not running as administrator. No further action can be taken.' return }#administrator check $final = $vmCollection | Select-Object ComputerName, VMName, State, Path, ConfigurationLocation, SnapshotFileLocation, SmartPagingFilePath return $final }#Get-VMLocationPathInfo <# .EXTERNALHELP Diag-V-help.xml #> function Get-VMReplicationStatus { [CmdletBinding()] param ( [Parameter(Mandatory = $false, HelpMessage = 'PSCredential object for storing provided creds')] [pscredential]$Credential ) Write-Verbose -Message 'Processing pre-checks. This may take a few seconds...' $adminEval = Test-RunningAsAdmin if ($adminEval -eq $true) { $vmCollection = @() $clusterEval = Test-IsACluster if ($clusterEval -eq $true) { Write-Verbose -Message "Cluster detected. Executing cluster appropriate diagnostic..." Write-Verbose -Message "Getting all cluster nodes in the cluster..." $nodes = Get-ClusterNode -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name if ($null -ne $nodes) { Write-Warning -Message "Getting VM Information. This can take a few moments..." Foreach ($node in $nodes) { $rawVM = $null $connTest = $false if ($env:COMPUTERNAME -ne $node) { Write-Verbose -Message "Performing connection test to node $node ..." $connTest = Test-NetConnection -ComputerName $node -InformationLevel Quiet }#if_local else { Write-Verbose -Message 'Local device.' $connTest = $true }#else_local if ($connTest -ne $false) { Write-Verbose -Message 'Connection succesful.' Write-Verbose -Message "Getting VM Information from node $node..." try { if ($Credential -and $env:COMPUTERNAME -ne $node) { $rawVM = Get-VM -ComputerName $node -Credential $Credential -ErrorAction Stop }#if_Credential else { $rawVM = Get-VM -ComputerName $node -ErrorAction Stop }#else_Credential }#try_Get-VM catch { Write-Warning "An issue was encountered getting VM information from $node :" Write-Error $_ return }#catch_Get-VM if ($rawVM) { $vmCollection += $rawVM }#if_rawVM else { Write-Verbose "No VMs were returned from $node" }#else_rawVM }#if_connection else { Write-Warning -Message "Connection test to $node unsuccesful." }#else_connection }#foreach_Node }#if_nodeNULLCheck else { Write-Warning -Message 'Device appears to be configured as a cluster but no cluster nodes were returned by Get-ClusterNode' return }#else_nodeNULLCheck }#if_cluster else { Write-Verbose -Message 'Standalone server detected. Executing standalone diagnostic...' Write-Verbose -Message 'Getting VM Information...' try { $rawVM = Get-VM -ErrorAction Stop }#try_Get-VM catch { Write-Warning 'An issue was encountered getting VM information:' Write-Error $_ return }#catch_Get-VM if ($rawVM) { $vmCollection += $rawVM }#if_rawVM else { Write-Verbose -Message 'No VMs were found on this device.' }#else_rawVM }#clusterEval }#administrator check else { Write-Warning -Message "Not running as administrator. No further action can be taken." }#administrator check $repEval = $vmCollection | Where-Object { $_.ReplicationState -ne "Disabled" } | Select-Object ComputerName, VMName, Status, ReplicationState, ReplicationHealth, ReplicationMode if (-not ($repEval)) { Write-Warning -Message 'No VMs were found that have replication enabled.' }#if_repEval $final = $repEval return $final }#Get-VMReplicationStatus <# .EXTERNALHELP Diag-V-help.xml #> function Get-VMStatus { [CmdletBinding()] param ( [Parameter(Mandatory = $false, HelpMessage = 'No formatting of return object')] [switch]$NoFormat, [Parameter(Mandatory = $false, HelpMessage = 'PSCredential object for storing provided creds')] [pscredential]$Credential ) Write-Verbose -Message 'Processing pre-checks. This may take a few seconds...' $adminEval = Test-RunningAsAdmin if ($adminEval -eq $true) { $vmCollection = @() $clusterEval = Test-IsACluster if ($clusterEval -eq $true) { Write-Verbose -Message 'Cluster detected. Executing cluster appropriate diagnostic...' Write-Verbose -Message 'Getting all cluster nodes in the cluster...' $nodes = Get-ClusterNode -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name if ($null -ne $nodes) { Foreach ($node in $nodes) { $rawVM = $null $connTest = $false if ($env:COMPUTERNAME -ne $node) { Write-Verbose -Message "Performing connection test to node $node ..." $connTest = Test-NetConnection -ComputerName $node -InformationLevel Quiet }#if_local else { Write-Verbose -Message 'Local device.' $connTest = $true }#else_local if ($connTest -ne $false) { Write-Verbose -Message 'Connection succesful.' Write-Verbose -Message "Getting VM Information from node $node..." try { if ($Credential) { $rawVM = Get-VM -ComputerName $node -Credential $Credential -ErrorAction Stop $vmCollection += $rawVM }#if_Credential else { $rawVM = Get-VM -ComputerName $node -ErrorAction Stop $vmCollection += $rawVM }#else_Credential }#try_Get-VM catch { Write-Warning "An issue was encountered getting VM information from $node :" Write-Error $_ return }#catch_Get-VM }#if_connection else { Write-Warning -Message "Connection test to $node unsuccesful." }#else_connection }#foreach_Node }#if_nodeNULLCheck else { Write-Warning -Message 'Device appears to be configured as a cluster but no cluster nodes were returned by Get-ClusterNode' return }#else_nodeNULLCheck }#if_cluster else { Write-Verbose -Message 'Standalone server detected. Executing standalone diagnostic...' Write-Verbose -Message 'Getting VM Information...' try { $rawVM = Get-VM -ErrorAction Stop }#try_Get-VM catch { Write-Warning 'An issue was encountered getting VM information:' Write-Error $_ return }#catch_Get-VM $vmCollection += $rawVM }#else_standalone }#if_adminEval else { Write-Warning -Message 'Not running as administrator. No further action can be taken.' return }#else_adminEval Write-Verbose -Message 'Processing results for return' if ($NoFormat) { $final = $vmCollection }#if_NoFormat else { $final = $vmCollection | Sort-Object ComputerName, State | Select-Object ComputerName, Name, State, CPUUsage, @{N = "MemoryMB"; E = {$_.MemoryAssigned / 1MB}}, Uptime, Status | Format-Table -AutoSize }#else_NoFormat return $final }#Get-VMStatus <# .EXTERNALHELP Diag-V-help.xml #> function Test-HyperVAllocation { [CmdletBinding()] param ( [Parameter(Mandatory = $false, HelpMessage = 'PSCredential object for storing provided creds')] [pscredential]$Credential ) Write-Verbose -Message 'Processing pre-checks. This may take a few seconds...' $adminEval = Test-RunningAsAdmin if ($adminEval -eq $true) { $clusterEval = Test-IsACluster if ($clusterEval -eq $true) { Write-Verbose -Message 'Cluster detected. Executing cluster appropriate diagnostic...' Write-Verbose -Message 'Getting all cluster nodes in the cluster...' $nodes = Get-ClusterNode -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name if ($null -ne $nodes) { Write-Warning -Message 'Getting VM Information. This can take a few moments...' #__________________ $results = @() $totalClusterRAM = 0 $totalVMClusterRAM = 0 $nodeCount = 0 #__________________ Foreach ($node in $nodes) { $connTest = $false if ($env:COMPUTERNAME -ne $node) { Write-Verbose -Message "Performing connection test to node $node ..." $connTest = Test-NetConnection -ComputerName $node -InformationLevel Quiet }#if_local else { Write-Verbose -Message 'Local device.' $connTest = $true }#else_local if ($connTest -ne $false) { Write-Verbose -Message 'Connection succesful.' ####################################################################################### ####################################################################################### ####################################################################################### #-------------------------------------------------------------------- #null all counts to permit multiple script runs #-------------------------------------------------------------------- $nodeCount += 1 #__________________ $name = $null $numCores = 0 $totalNumCores = 0 $numLogicProcs = 0 $totalNumLogicProcs = 0 $totalMemory = 0 $availVMMemory = 0 $freeMemory = 0 #__________________ $vmCount = 0 $vmProcCount = 0 $procRatio = 0 $cpuRatio = 0 $totalVMProcCount = 0 $finalRatio = '' #__________________ $memorystartup = 0 $MemoryMaximum = 0 $totalstartupmem = 0 $totalDynamicMaxMem = 0 $static = 0 $staticmemory = 0 #__________________ $ramHealth = '' $maxDynamicRamPotential = '' ########################################################################################## #Get ALL the Raw data up front and fail fast #--------------------------------------------------------------------- #get Cim data loaded up #--------------------------------------------------------------------- Write-Verbose -Message "Getting Cmi Information from node $node..." if ($Credential -and $env:COMPUTERNAME -ne $node) { try { $cimS = New-CimSession -ComputerName $node -Credential $Credential -ErrorAction Stop $w32ProcInfo = Get-CimInstance -class win32_processor -CimSession $cimS -ErrorAction Stop $w32OSInfo = Get-CimInstance -class Win32_OperatingSystem -CimSession $cimS -ErrorAction Stop }#try_Get-CimInstance catch { Write-Warning -Message "Unable to establish CIM session to $node" Write-Error $_ return }#catch_Get-CimInstance }#if_Credential else { try { $w32ProcInfo = Get-CimInstance -class win32_processor -ComputerName $node -ErrorAction Stop $w32OSInfo = Get-CimInstance -class Win32_OperatingSystem -ComputerName $node -ErrorAction Stop }#try_Get-CimInstance catch { Write-Warning -Message "An error was encountered getting Cim info from $node" Write-Error $_ return }#catch_Get-CimInstance }#else_Credential if ($null -eq $w32ProcInfo -or $null -eq $w32OSInfo) { Write-Warning -Message "Data was not sucessfully from the Host OS on $node." return }#if_CimNullCheck #--------------------------------------------------------------------- #get VM data loaded up #--------------------------------------------------------------------- Write-Verbose -Message "Getting VM Information from node $node..." try { if ($Credential -and $env:COMPUTERNAME -ne $node) { $vms = Get-VM -ComputerName $node -Credential $Credential -ErrorAction Stop }#if_Credential else { $vms = Get-VM -ComputerName $node -ErrorAction Stop }#else_Credential }#try_Get-VM catch { Write-Warning "An issue was encountered getting VM information from $node :" Write-Error $_ return }#catch_Get-VM ########################################################################################## Write-Verbose -Message 'We are now beginning to process data we have previously retrieved...' $object = New-Object -TypeName PSObject ########################################################################################## $name = $w32OSInfo.CSName Write-Verbose -Message "name: $name" $object | Add-Member -MemberType NoteProperty -name SystemName -Value $name -Force #________________________________________________________________________ $numCores = $w32ProcInfo.numberOfCores Write-Verbose -Message "numCores: $numCores" foreach ($core in $numCores) { $totalNumCores += $core }#foreach_numCores Write-Verbose -Message "totalNumCores: $totalNumCores" $object | Add-Member -MemberType NoteProperty -name Cores -Value $totalNumCores -Force #________________________________________________________________________ $numLogicProcs = $w32ProcInfo.NumberOfLogicalProcessors Write-Verbose -Message "numLogicProcs: $numLogicProcs" foreach ($proc in $numLogicProcs) { $totalNumLogicProcs += $proc }#foreach_numLogicProcs Write-Verbose -Message "totalNumLogicProcs: $totalNumLogicProcs" $object | Add-Member -MemberType NoteProperty -name 'LogicalProcessors' -Value $totalNumLogicProcs -Force ########################################################################################## $totalMemory = [math]::round($w32OSInfo.TotalVisibleMemorySize / 1MB, 0) Write-Verbose -Message "totalMemory: $totalMemory" $object | Add-Member -MemberType NoteProperty -name 'TotalMemory(GB)' -Value $totalMemory -Force ########################################################################################## foreach ($vm in $vms) { $vmProcCount += $vm.ProcessorCount Write-Verbose "Getting memory information from VM $vm" if ($vm.DynamicMemoryEnabled -eq $true) { Write-Verbose "Dynamic Deteced..." $memorystartup = [math]::Round(($VM | Select-Object MemoryStartup).MemoryStartup / 1GB, 0) $memoryMaximum = [math]::Round(($VM | Select-Object MemoryMaximum).MemoryMaximum / 1GB, 0) $totalstartupmem += $memoryStartup $totalDynamicMaxMem += $memoryMaximum }#if_Dynamic else { Write-Verbose "Static Deteced..." $static = [math]::Round(($VM | Select-Object MemoryStartup).MemoryStartup / 1GB, 0) Write-Verbose "Adding static memory of $static" $staticmemory += $static }#else_Static }#foreach_VM Write-Verbose -Message "vmProcCount: $vmProcCount" #________________________________________________________________________ #8GB of memory is RESERVED for the host $availVMMemory = $totalMemory - 8 $totalClusterRAM += $availVMMemory Write-Verbose -Message "availVMMemory: $availVMMemory" $object | Add-Member -MemberType NoteProperty -name 'AvailMemory(-8GBSystem)' -Value $availVMMemory -Force #________________________________________________________________________ $freeMemory = [math]::round($w32OSInfo.FreePhysicalMemory / 1MB, 0) Write-Verbose -Message "freeMemory: $freeMemory" $object | Add-Member -MemberType NoteProperty -name 'FreeRAM(GB)' -Value $freeMemory -Force #________________________________________________________________________ $memPercent = [math]::round($freeMemory / $totalMemory, 2) * 100 Write-Verbose -Message "memPercent: $memPercent" $object | Add-Member -MemberType NoteProperty -name 'FreeRAM(%)' -Value $memPercent -Force ########################################################################################## $vmCount = $vms | Measure-Object | Select-Object -ExpandProperty count Write-Verbose -Message "vmCount: $vmCount" $object | Add-Member -MemberType NoteProperty -name 'TotalVMCount' -Value $vmCount -Force #might adjust nomenclature here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! $totalVMProcCount = $vmProcCount Write-Verbose -Message "totalVMProcCount: $totalVMProcCount" $object | Add-Member -MemberType NoteProperty -name 'TotalvCPUs' -Value $totalVMProcCount -Force #________________________________________________________________________ if ($totalVMProcCount -eq 0) { $finalRatio = 'NA' }#if_vCPU_0 elseif ($totalVMProcCount -gt $totalNumLogicProcs) { $cpuRatio = ($totalNumLogicProcs / $totalVMProcCount) $procRatio = [math]::round($totalVMProcCount / $totalNumLogicProcs) $finalRatio = "$procRatio : 1" }#elseif_vCPU-gt else { $finalRatio = '1 : 1' }#else_vCPU Write-Verbose -Message "cpuRatio: $cpuRatio" Write-Verbose -Message "procRatio: $procRatio" Write-Verbose -Message "finalRatio: $finalRatio" $object | Add-Member -MemberType NoteProperty -name 'vCPURatio' -Value $finalRatio -Force ########################################################################################## #account for no static and no dynamic situations if ($null -eq $totalstartupmem) { $totalstartupmem = 0 }#nullCheck if ($null -eq $staticmemory) { $staticmemory = 0 }#nullCheck Write-Verbose -Message "totalstartupmem: $totalstartupmem" $object | Add-Member -MemberType NoteProperty -name 'DynamicStartupRequired' -Value $totalstartupmem -Force Write-Verbose -Message "staticmemory: $staticmemory" $object | Add-Member -MemberType NoteProperty -name 'StaticRAMRequired' -Value $staticmemory -Force #________________________________________________________________________ $totalramrequired = $totalstartupmem + $staticmemory $totalVMClusterRAM += $totalramrequired Write-Verbose -Message "totalramrequired: $totalramrequired" $object | Add-Member -MemberType NoteProperty -name 'TotalRAMRequired' -Value $totalramrequired -Force #________________________________________________________________________ if ($totalramrequired -lt $availVMMemory) { Write-Verbose -Message "Minimum RAM: $totalramrequired GB does not exceed available RAM: $availVMMemory GB" $ramHealth = 'Healthy' }#if_Healthy elseif ($totalramrequired -eq $availVMMemory) { Write-Verbose -Message "Minimum RAM: $totalramrequired GB is exactly at available RAM: $availVMMemory GB" $ramHealth = 'Warning' }#elseif_Warning else { Write-Verbose -Message "Minimum RAM: $totalramrequired GB exceeds available RAM: $availVMMemory GB" $ramHealth = 'UNHEALTHY' }#else_Unhealthy Write-Verbose -Message "ramHealth: $ramHealth" $object | Add-Member -MemberType NoteProperty -name 'RAMAllocation' -Value $ramHealth -Force #________________________________________________________________________ Write-Verbose -Message "totalDynamicMaxMem: $totalDynamicMaxMem" $object | Add-Member -MemberType NoteProperty -name 'DynamicMaxPotential' -Value $totalDynamicMaxMem -Force #________________________________________________________________________ if ($totalDynamicMaxMem -ne 0) { if ($totalDynamicMaxMem -lt $availVMMemory) { Write-Verbose -Message "Maximum potential RAM: $totalDynamicMaxMem GB does not exceed available RAM: $availVMMemory GB" $maxDynamicRamPotential = 'Good' }#if_Good else { Write-Verbose -Message "Maximum potential RAM: $totalDynamicMaxMem GB exceeds available RAM: $availVMMemory GB" $maxDynamicRamPotential = 'Warning' }#else_Warning }#if_Totalmax-ne-0 else { Write-Verbose -Message 'No Dynamic VMs detected.' $maxDynamicRamPotential = 'NA' }#else_noDynamic Write-Verbose -Message "maxDynamicRamPotential: $maxDynamicRamPotential" $object | Add-Member -MemberType NoteProperty -name 'DynamicMaxAllocation' -Value $maxDynamicRamPotential -Force ########################################################################################## $results += $object ####################################################################################### ####################################################################################### ####################################################################################### }#if_connection else { Write-Warning -Message "Connection test to $node unsuccesful." return }#else_connection }#foreach_Node ####################################################################################### ####################################################################################### ####################################################################################### #CSV Storage Space checks - we will check CSV locations only for clustered Hyps #-------------------------------------------------------------------- try { $clusterName = "." $clusterSharedVolume = Get-ClusterSharedVolume -Cluster $clusterName -ErrorAction Stop if ($null -ne $clusterSharedVolume) { foreach ($volume in $clusterSharedVolume) { #____________________________________________________ $diskName = '' $spaceFree = 0 $percentFree = 0 $size = 0 $expectations = 20 $object = New-Object -TypeName PSObject $driveHealth = '' #____________________________________________________ $diskName = $volume.SharedVolumeInfo.FriendlyVolumeName $percentFree = $volume.SharedVolumeInfo.Partition.PercentFree $spaceFree = [int]($volume.SharedVolumeInfo.Partition.Freespace / 1GB) #expectations: #15% For less than 1TB #10 % For greater than 1TB $size = [math]::Round($volume.SharedVolumeInfo.partition.Size / 1GB, 0) $expectations = 20 if ($size -le 1000) { $expectations = 15 } elseif ($size -gt 1000) { $expectations = 10 } Write-Verbose -Message "diskName: $diskName" Write-Verbose -Message "size: $size" Write-Verbose -Message "spaceFree: $spaceFree" Write-Verbose -Message "percentFree: $percentFree" Write-Verbose -Message "expectations: $expectations" $object | Add-Member -MemberType NoteProperty -name CSV -Value $diskName -Force $object | Add-Member -MemberType NoteProperty -name 'Size(GB)' -Value $size -Force $object | Add-Member -MemberType NoteProperty -name 'FreeSpace(GB)' -Value $spaceFree -Force $object | Add-Member -MemberType NoteProperty -name 'FreeSpace(%)' -Value $percentFree -Force if ($percentFree -lt $expectations) { $driveHealth = 'UNHEALTHY' } else { $driveHealth = 'HEALTHY' } Write-Verbose -Message "driveHealth: $driveHealth" $object | Add-Member -MemberType NoteProperty -name 'DriveHealth' -Value $driveHealth -Force $results += $object }#foreach_CSV }#if_null_csvs else { Write-Verbose -Message "No CSVs discovered - no storage information pulled" }#else_null_csvs }#try_Get-ClusterSharedVolume catch { Write-Warning -Message "An error was encountered getting CSVs spacing information from $node" Write-Error $_ }#catch_Get-ClusterSharedVolume ####################################################################################### ####################################################################################### ####################################################################################### Write-Verbose -Message 'Calculating a node loss and its impact...' $object = New-Object -TypeName PSObject $n1Eval = $false #assume the worst $x = $totalClusterRAM / $nodeCount $clusterNodeDownUseable = $totalClusterRAM - $x Write-Verbose -Message "totalClusterRAM: $totalClusterRAM" Write-Verbose -Message "totalVMClusterRAM: $totalVMClusterRAM" Write-Verbose -Message "nodeCount: $nodeCount" if ($totalVMClusterRAM -gt $clusterNodeDownUseable) { Write-Verbose -Message 'VMs would NOT survive a one node failure' } else { $n1Eval = $true Write-Verbose -Message 'VMs would survive a one node failure' } $object | Add-Member -MemberType NoteProperty -name 'N+1RAMEvaluation' -Value $n1Eval -Force $results += $object ####################################################################################### ####################################################################################### ####################################################################################### }#if_nodeNULLCheck else { Write-Warning -Message 'Device appears to be configured as a cluster but no cluster nodes were returned by Get-ClusterNode' return }#else_nodeNULLCheck }#if_cluster else { Write-Verbose -Message 'Standalone server detected. Executing standalone diagnostic...' ####################################################################################### ####################################################################################### ####################################################################################### ####################################################################################### ####################################################################################### #-------------------------------------------------------------------- #null all counts to permit multiple script runs #-------------------------------------------------------------------- $results = @() #__________________ $name = $null $numCores = 0 $totalNumCores = 0 $numLogicProcs = 0 $totalNumLogicProcs = 0 $totalMemory = 0 $availVMMemory = 0 $freeMemory = 0 #__________________ $vmCount = 0 $vmProcCount = 0 $procRatio = 0 $cpuRatio = 0 $totalVMProcCount = 0 $finalRatio = '' #__________________ $memorystartup = 0 $MemoryMaximum = 0 $totalstartupmem = 0 $totalDynamicMaxMem = 0 $static = 0 $staticmemory = 0 #__________________ $ramHealth = '' $maxDynamicRamPotential = '' ########################################################################################## #Get ALL the Raw data up front and fail fast $node = $env:COMPUTERNAME #--------------------------------------------------------------------- #get Cim data loaded up #--------------------------------------------------------------------- try { $w32ProcInfo = Get-CimInstance -class win32_processor -ErrorAction Stop $w32OSInfo = Get-CimInstance -class Win32_OperatingSystem -ErrorAction Stop $drives = Get-CimInstance win32_logicaldisk -ErrorAction Stop | Where-Object {$_.DeviceID -ne "C:"} }#try_Get-CimInstance catch { Write-Warning -Message "An error was encountered getting Cim info from $node" Write-Error $_ return }#catch_Get-CimInstance if ($null -eq $w32ProcInfo -or $null -eq $w32OSInfo) { Write-Warning -Message "Data was not sucessfully from the Host OS." return }#if_CimNullCheck #--------------------------------------------------------------------- #get VM data loaded up #--------------------------------------------------------------------- try { $vms = Get-VM -ErrorAction Stop }#try_Get-VM catch { Write-Warning -Message "An error was encountered getting VM info from $node" Write-Error $_ return }#catch_Get-VM ########################################################################################## Write-Verbose -Message 'We are now beginning to process data we have previously retrieved...' $object = New-Object -TypeName PSObject ########################################################################################## $name = $w32OSInfo.CSName Write-Verbose -Message "name: $name" $object | Add-Member -MemberType NoteProperty -name SystemName -Value $name -Force #________________________________________________________________________ $numCores = $w32ProcInfo.numberOfCores Write-Verbose -Message "numCores: $numCores" foreach ($core in $numCores) { $totalNumCores += $core }#foreach_numCores Write-Verbose -Message "totalNumCores: $totalNumCores" $object | Add-Member -MemberType NoteProperty -name Cores -Value $totalNumCores -Force #________________________________________________________________________ $numLogicProcs = $w32ProcInfo.NumberOfLogicalProcessors Write-Verbose -Message "numLogicProcs: $numLogicProcs" foreach ($proc in $numLogicProcs) { $totalNumLogicProcs += $proc }#foreach_numLogicProcs Write-Verbose -Message "totalNumLogicProcs: $totalNumLogicProcs" $object | Add-Member -MemberType NoteProperty -name 'LogicalProcessors' -Value $totalNumLogicProcs -Force ########################################################################################## $totalMemory = [math]::round($w32OSInfo.TotalVisibleMemorySize / 1MB, 0) Write-Verbose -Message "totalMemory: $totalMemory" $object | Add-Member -MemberType NoteProperty -name 'TotalMemory(GB)' -Value $totalMemory -Force ########################################################################################## foreach ($vm in $vms) { $vmProcCount += $vm.ProcessorCount Write-Verbose "Getting memory information from VM $vm" if ($vm.DynamicMemoryEnabled -eq $true) { Write-Verbose "Dynamic Deteced..." $memorystartup = [math]::Round(($VM | Select-Object MemoryStartup).MemoryStartup / 1GB, 0) $memoryMaximum = [math]::Round(($VM | Select-Object MemoryMaximum).MemoryMaximum / 1GB, 0) $totalstartupmem += $memoryStartup $totalDynamicMaxMem += $memoryMaximum }#if_Dynamic else { Write-Verbose "Static Deteced..." $static = [math]::Round(($VM | Select-Object MemoryStartup).MemoryStartup / 1GB, 0) Write-Verbose "Adding static memory of $static" $staticmemory += $static }#else_Static }#foreach_VM Write-Verbose -Message "vmProcCount: $vmProcCount" #________________________________________________________________________ #8GB of memory is RESERVED for the host $availVMMemory = $totalMemory - 8 Write-Verbose -Message "availVMMemory: $availVMMemory" $object | Add-Member -MemberType NoteProperty -name 'AvailMemory(-8GBSystem)' -Value $availVMMemory -Force #________________________________________________________________________ $freeMemory = [math]::round($w32OSInfo.FreePhysicalMemory / 1MB, 0) Write-Verbose -Message "freeMemory: $freeMemory" $object | Add-Member -MemberType NoteProperty -name 'FreeRAM(GB)' -Value $freeMemory -Force #________________________________________________________________________ $memPercent = [math]::round($freeMemory / $totalMemory, 2) * 100 Write-Verbose -Message "memPercent: $memPercent" $object | Add-Member -MemberType NoteProperty -name 'FreeRAM(%)' -Value $memPercent -Force ########################################################################################## $vmCount = $vms | Measure-Object | Select-Object -ExpandProperty count Write-Verbose -Message "vmCount: $vmCount" $object | Add-Member -MemberType NoteProperty -name 'TotalVMCount' -Value $vmCount -Force #might adjust nomenclature here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! $totalVMProcCount = $vmProcCount Write-Verbose -Message "totalVMProcCount: $totalVMProcCount" $object | Add-Member -MemberType NoteProperty -name 'TotalvCPUs' -Value $totalVMProcCount -Force #________________________________________________________________________ if ($totalVMProcCount -eq 0) { $finalRatio = 'NA' }#if_vCPU_0 elseif ($totalVMProcCount -gt $totalNumLogicProcs) { $cpuRatio = ($totalNumLogicProcs / $totalVMProcCount) $procRatio = [math]::round($totalVMProcCount / $totalNumLogicProcs) $finalRatio = "$procRatio : 1" }#elseif_vCPU-gt else { $finalRatio = '1 : 1' }#else_vCPU Write-Verbose -Message "cpuRatio: $cpuRatio" Write-Verbose -Message "procRatio: $procRatio" Write-Verbose -Message "finalRatio: $finalRatio" $object | Add-Member -MemberType NoteProperty -name 'vCPURatio' -Value $finalRatio -Force ########################################################################################## #account for no static and no dynamic situations if ($null -eq $totalstartupmem) { $totalstartupmem = 0 }#nullCheck if ($null -eq $staticmemory) { $staticmemory = 0 }#nullCheck Write-Verbose -Message "totalstartupmem: $totalstartupmem" $object | Add-Member -MemberType NoteProperty -name 'DynamicStartupRequired' -Value $totalstartupmem -Force Write-Verbose -Message "staticmemory: $staticmemory" $object | Add-Member -MemberType NoteProperty -name 'StaticRAMRequired' -Value $staticmemory -Force #________________________________________________________________________ $totalramrequired = $totalstartupmem + $staticmemory Write-Verbose -Message "totalramrequired: $totalramrequired" $object | Add-Member -MemberType NoteProperty -name 'TotalRAMRequired' -Value $totalramrequired -Force #________________________________________________________________________ if ($totalramrequired -lt $availVMMemory) { Write-Verbose -Message "Minimum RAM: $totalramrequired GB does not exceed available RAM: $availVMMemory GB" $ramHealth = 'Healthy' }#if_Healthy elseif ($totalramrequired -eq $availVMMemory) { Write-Verbose -Message "Minimum RAM: $totalramrequired GB is exactly at available RAM: $availVMMemory GB" $ramHealth = 'Warning' }#elseif_Warning else { Write-Verbose -Message "Minimum RAM: $totalramrequired GB exceeds available RAM: $availVMMemory GB" $ramHealth = 'UNHEALTHY' }#else_Unhealthy Write-Verbose -Message "ramHealth: $ramHealth" $object | Add-Member -MemberType NoteProperty -name 'RAMAllocation' -Value $ramHealth -Force #________________________________________________________________________ Write-Verbose -Message "totalDynamicMaxMem: $totalDynamicMaxMem" $object | Add-Member -MemberType NoteProperty -name 'DynamicMaxPotential' -Value $totalDynamicMaxMem -Force #________________________________________________________________________ if ($totalDynamicMaxMem -ne 0) { if ($totalDynamicMaxMem -lt $availVMMemory) { Write-Verbose -Message "Maximum potential RAM: $totalDynamicMaxMem GB does not exceed available RAM: $availVMMemory GB" $maxDynamicRamPotential = 'Good' }#if_Good else { Write-Verbose -Message "Maximum potential RAM: $totalDynamicMaxMem GB exceeds available RAM: $availVMMemory GB" $maxDynamicRamPotential = 'Warning' }#else_Warning }#if_Totalmax-ne-0 else { Write-Verbose -Message 'No Dynamic VMs detected.' $maxDynamicRamPotential = 'NA' }#else_noDynamic Write-Verbose -Message "maxDynamicRamPotential: $maxDynamicRamPotential" $object | Add-Member -MemberType NoteProperty -name 'DynamicMaxAllocation' -Value $maxDynamicRamPotential -Force ########################################################################################## $results += $object ########################################################################################## if ($null -ne $drives) { foreach ($drive in $drives) { #____________________________________________________ $totalSize = 0 $driveLetter = '' $spaceFree = 0 $percentFree = 0 $size = 0 $expectations = 20 $object = New-Object -TypeName PSObject $driveHealth = '' #____________________________________________________ $totalSize = [int]($drive.Size / 1GB) if ($totalSize -gt 10) { $driveLetter = $drive.DeviceID $spaceFree = [int]($drive.Freespace / 1GB) $percentFree = [math]::round(($spaceFree / $totalSize) * 100) #expectations: #15% For less than 1TB #10 % For greater than 1TB $size = [math]::Round($drive.Size / 1GB, 0) if ($size -le 1000) { $expectations = 15 } elseif ($size -gt 1000) { $expectations = 10 } Write-Verbose -Message "driveLetter: $driveLetter" Write-Verbose -Message "totalSize: $totalSize" Write-Verbose -Message "spaceFree: $spaceFree" Write-Verbose -Message "percentFree: $percentFree" Write-Verbose -Message "size: $size" Write-Verbose -Message "expectations: $expectations" $object | Add-Member -MemberType NoteProperty -name Drive -Value $driveLetter -Force $object | Add-Member -MemberType NoteProperty -name 'Size(GB)' -Value $totalSize -Force $object | Add-Member -MemberType NoteProperty -name 'FreeSpace(GB)' -Value $spaceFree -Force $object | Add-Member -MemberType NoteProperty -name 'FreeSpace(%)' -Value $percentFree -Force if ($percentFree -lt $expectations) { $driveHealth = 'UNHEALTHY' } else { $driveHealth = 'HEALTHY' } Write-Verbose -Message "driveHealth: $driveHealth" $object | Add-Member -MemberType NoteProperty -name 'DriveHealth' -Value $driveHealth -Force }#if_Drive-gt10 $results += $object }#foreach_Drive }#drive_nullCheck else { Write-Verbose -Message "No additional storage other than OS drive deteceted" }#else_nullCheck ########################################################################################## #return $results ####################################################################################### ####################################################################################### ####################################################################################### ####################################################################################### ####################################################################################### }#clusterEval }#administrator check else { Write-Warning -Message 'Not running as administrator. No further action can be taken.' return }#administrator check return $results }#Test-HyperVAllocation |