-
+
diff --git a/AD/GroupSearch.php b/AD/GroupSearch.php
index 4992404..1d2914e 100644
--- a/AD/GroupSearch.php
+++ b/AD/GroupSearch.php
@@ -35,7 +35,7 @@
-
+
diff --git a/Hyper-V/Legacy-VMList.php b/Hyper-V/Legacy-VMList.php
index 7ab1827..5ef4d51 100644
--- a/Hyper-V/Legacy-VMList.php
+++ b/Hyper-V/Legacy-VMList.php
@@ -37,7 +37,7 @@
-
+
diff --git a/Hyper-V/Migration.php b/Hyper-V/Migration.php
index a0afb42..3599046 100644
--- a/Hyper-V/Migration.php
+++ b/Hyper-V/Migration.php
@@ -35,7 +35,7 @@
-
+
diff --git a/Hyper-V/SYN-VMList.php b/Hyper-V/SYN-VMList.php
index 0f2903a..df95599 100644
--- a/Hyper-V/SYN-VMList.php
+++ b/Hyper-V/SYN-VMList.php
@@ -36,7 +36,7 @@
-
+
diff --git a/Hyper-V/VMs-Backups.php b/Hyper-V/VMs-Backups.php
index d28e5f5..28577a3 100644
--- a/Hyper-V/VMs-Backups.php
+++ b/Hyper-V/VMs-Backups.php
@@ -35,7 +35,7 @@
-
+
@@ -84,7 +84,7 @@
$answers = Invoke_infra("SELECT * FROM VMs_Backup where ( Owner like 'DUN-VMH%' or Owner like 'MDK-VMH%' ) and name not like 'WS%' and owner not like '%WKG%' and owner not like '%VMH-WM%' and Exclusion ='' and (LastResult <> 'OK' or lastresult is null) and policy is not null order by lastresult,name");
foreach ($answers as $row) {
$er++;
- $date1 = date_create($row['LastKnownGood']); $diff = date_diff($date1, date_create(date("Y-m-d")));
+ $date1 = date_create($row['LastKnownGood']??'01/01/1970'); $diff = date_diff($date1, date_create(date("Y-m-d")));
if ($diff->format("%R%a") >= 2 || $row['LastKnownGood'] == ''){
echo "";
}else{
diff --git a/Hyper-V/cluster-detail.php b/Hyper-V/cluster-detail.php
index 4f875c7..5d3b465 100644
--- a/Hyper-V/cluster-detail.php
+++ b/Hyper-V/cluster-detail.php
@@ -34,7 +34,7 @@
-
+
diff --git a/Hyper-V/clusters.php b/Hyper-V/clusters.php
index bc0fe29..8e92781 100644
--- a/Hyper-V/clusters.php
+++ b/Hyper-V/clusters.php
@@ -34,190 +34,233 @@
-
+
@@ -226,6 +269,3 @@
Hyper-V Clusters
- - - '' and cluster not like '%-WM%' and cluster not like '%-C1MAS%' and cluster not like '%-vrs%' and (cluster like 'DUN%' or cluster like 'DMV%') order by cluster"); - ?>
-
";
+ // =================================================================
+ // STEP 1: Fetch all required data with minimal database queries (MSSQL SYNTAX)
+ // =================================================================
+
+ // Query 1: Get aggregated data for all clusters at once.
+ $cluster_query = "
+ SELECT
+ cluster,
+ COUNT(node) as node_count,
+ MIN(node_ram) as min_node_ram,
+ SUM(TRY_CAST(vm_count AS INT)) as total_vms,
+ SUM(TRY_CAST(vm_memory AS INT)) as total_vm_memory,
+ SUM(TRY_CAST(io_disk AS FLOAT)) as total_io_disk,
+ STRING_AGG(CAST(csvs AS VARCHAR(MAX)), '|') as all_csvs
+ FROM
+ cmdb_HyperV_Hosts
+ WHERE
+ cluster <> ''
+ AND cluster NOT LIKE '%-WM%'
+ AND cluster NOT LIKE '%-C1MAS%'
+ AND cluster NOT LIKE '%-vrs%'
+ AND (cluster LIKE 'DUN%' OR cluster LIKE 'DMV%')
+ GROUP BY
+ cluster
+ ORDER BY
+ cluster
+ ";
+ $all_clusters_data = Invoke_Infra($cluster_query);
+
+ // Query 2: Get VM distribution for all relevant clusters at once.
+ $vm_repart_query = "
+ SELECT
+ v.Cluster,
+ v.Owner,
+ count(v.Owner) as vm_count
+ FROM
+ cmdb_vms v
+ INNER JOIN cmdb_HyperV_Hosts h ON v.Cluster = h.cluster
+ WHERE
+ v.decomtime IS NULL
+ AND h.cluster <> ''
+ AND h.cluster NOT LIKE '%-WM%'
+ AND h.cluster NOT LIKE '%-C1MAS%'
+ AND h.cluster NOT LIKE '%-vrs%'
+ AND (h.cluster LIKE 'DUN%' OR h.cluster LIKE 'DMV%')
+ GROUP BY
+ v.Cluster, v.Owner
+ ORDER BY
+ v.Cluster, v.Owner
+ ";
+ $raw_vm_distribution = Invoke_Infra($vm_repart_query);
+
+ // Process the VM distribution data into an easy-to-use associative array
+ $vm_distribution = [];
+ if (is_array($raw_vm_distribution)) {
+ foreach ($raw_vm_distribution as $repart) {
+ $vm_distribution[$repart['Cluster']][] = [
+ 'owner' => $repart['Owner'],
+ 'vm_count' => $repart['vm_count']
+ ];
}
- $data = Invoke_Infra("select * from cmdb_HyperV_Hosts where cluster = '" . $cluster['cluster'] . "'");
- $clumem = (invoke_infra("select min(node_ram) as nmem from cmdb_HyperV_Hosts where cluster ='".$cluster['cluster']."'"))[0]['nmem'];
- $nb = (invoke_infra("select count(node) as nb from cmdb_HyperV_Hosts where cluster ='".$cluster['cluster']."'"))[0]['nb'];
- $clmem = $clumem-32; if($nb == 4){$clmem = $clmem*2;}
- $nodes = count($data);
- $vms = 0;
- $vm_mem = 0;
- $disk = 0;
- $io = 0;
- $node_mem = 0;
- $capacity = 0; $free = 0;
- foreach ($data as $d) {
- $vms += $d['vm_count'];
- $vm_mem += $d['vm_memory'];
- $node_mem = (int) $d['node_ram'];
- foreach (explode("|", $d['csvs']) as $csv) {
- if (str_contains($csv, ';')) {
- $free += intval(explode(";", $csv)[1]) - intval(explode(";", $csv)[2]);
- $disk = max($disk, $free);
- $capacity += (int) explode(";", $csv)[1];
+ }
+ // =================================================================
+ // STEP 2: Loop through the pre-fetched data and display it
+ // =================================================================
+ $total_vms_left = 0;
+ $cluster_count = 0;
+
+ if (is_array($all_clusters_data)) {
+ foreach ($all_clusters_data as $cluster_data) {
+ if ($cluster_count > 0 && $cluster_count % 4 == 0) {
+ echo "
";
+ }
+
+ // --- Calculations ---
+ $cluster_name = $cluster_data['cluster'];
+ $node_count = (int)$cluster_data['node_count'];
+ $total_vms = (int)$cluster_data['total_vms'];
+ $total_vm_memory = (int)$cluster_data['total_vm_memory'];
+
+ // Memory calculation
+ $cluster_usable_mem = (int)$cluster_data['min_node_ram'] - 32;
+ if ($node_count == 4) {
+ $cluster_usable_mem *= 2;
+ }
+ $free_mem = $cluster_usable_mem - $total_vm_memory;
+ $free_mem_percentage = ($cluster_usable_mem > 0) ? round($free_mem / $cluster_usable_mem * 100) : 0;
+
+ // Storage calculation
+ $capacity_gb = 0;
+ $free_gb = 0;
+ if (!empty($cluster_data['all_csvs'])) {
+ // Explode the big string into an array of all CSV entries (with duplicates)
+ $all_csv_entries = explode("|", $cluster_data['all_csvs']);
+ // Create a new array containing only the unique CSV entries
+ $unique_csv_entries = array_unique($all_csv_entries);
+ // Loop through the UNIQUE entries to perform the calculation
+ foreach ($unique_csv_entries as $csv_string) {
+ if (str_contains($csv_string, ';')) {
+ $parts = explode(";", $csv_string);
+ if(count($parts) >= 3) {
+ $capacity_gb += (int)$parts[1];
+ // Free space is Total Capacity (parts[1]) - Used Space (parts[2])
+ $free_gb += (int)$parts[1] - (int)$parts[2];
+ }
+ }
}
}
- $io += $d['io_disk'];
- }
- $node_mem = $node_mem * count($data) / 2;
- $io= round($io / count($data) * 1024);
- if($io == 0){$io = "?";}
- $vmleft = floor(($node_mem - 24 - $vm_mem) / 16);
- $storageleft = floor($disk / 110);
- $vmleft = min($vmleft, $storageleft);
- $totalleft += $vmleft;
- if ($vmleft > 2) {
- $vleft = "(" . $vmleft . " VMs left)";
- } elseif ($vmleft == 2) {
- $vleft = "(" . $vmleft . " VMs left)";
- } else {
- $vleft = "(" . $vmleft . " VM left)";
- }
+ $free_gb = max(0, $free_gb);
+ $free_storage_percentage = ($capacity_gb > 0) ? round($free_gb / $capacity_gb * 100) : 0;
- ?>
+ // IOPS Calculation
+ $avg_io = ($node_count > 0) ? round((float)$cluster_data['total_io_disk'] / $node_count * 1024) : 0;
+ $io_display = ($avg_io == 0) ? "?" : $avg_io;
-
-
-
-
-
- Total VM Left :
+
+
+
+
+ +