skrypt do pobrania:
python_hyper-v_topology_grapher.py
Poniższy kod umożliwia pobieranie informacji o przełącznikach wirtualnych (VMSwitches) oraz adapterach sieciowych maszyn wirtualnych (VMNetworkAdapters) w systemie Hyper-V. Następnie buduje on graf, gdzie węzły to przełączniki wirtualne oraz maszyny wirtualne, a krawędzie reprezentują połączenia między tymi elementami. Całość jest wizualizowana przy użyciu biblioteki Matplotlib.
Program składa się z kilku funkcji, które realizują różne zadania:
def get_vmswitches(): """ Use PowerShell to get Hyper-V virtual switches as JSON. """ cmd = ["powershell", "-Command", "Get-VMSwitch | ConvertTo-Json"] proc = subprocess.run(cmd, capture_output=True, text=True) try: switches = json.loads(proc.stdout) except json.JSONDecodeError as e: print("Error decoding JSON for switches:", e) print("PowerShell output was:", proc.stdout) switches = [] # Ensure the data is a list if isinstance(switches, dict): switches = [switches] return switches
Funkcja ta używa PowerShella do pobrania informacji o przełącznikach wirtualnych w systemie Hyper-V, a następnie konwertuje wynik na format JSON. Jeśli dekodowanie JSON zakończy się niepowodzeniem, wypisuje komunikat o błędzie i zwraca pustą listę. Jeśli dane nie są w formie listy, funkcja konwertuje je na listę.
def get_vmnetworkadapters(): """ Use PowerShell to get Hyper-V VM network adapters as JSON. This version pipes all VMs to Get-VMNetworkAdapter to ensure we get data. """ # Updated command to get network adapters from all VMs cmd = ["powershell", "-Command", "Get-VM | Get-VMNetworkAdapter | ConvertTo-Json"] proc = subprocess.run(cmd, capture_output=True, text=True) if proc.stderr: print("PowerShell error output:", proc.stderr) try: adapters = json.loads(proc.stdout) except json.JSONDecodeError as e: print("Error decoding JSON for adapters:", e) print("PowerShell output was:", proc.stdout) adapters = [] # Ensure the data is a list if isinstance(adapters, dict): adapters = [adapters] return adapters
Ta funkcja działa podobnie do poprzedniej, ale zamiast przełączników wirtualnych, pobiera dane o adapterach sieciowych maszyn wirtualnych w Hyper-V. W przypadku błędów podczas dekodowania JSON, wypisuje komunikat o błędzie i zwraca pustą listę.
def build_graph(switches, adapters): """ Build a graph with virtual switches as one type of node and VMs as another. An edge represents a connection between a VM and a virtual switch. """ G = nx.Graph() # Add virtual switch nodes for sw in switches: sw_name = sw.get("Name") if sw_name: G.add_node(sw_name, type="switch") # Add VM nodes and edges based on network adapter connections for adapter in adapters: vm_name = adapter.get("VMName") switch_name = adapter.get("SwitchName") if vm_name: G.add_node(vm_name, type="vm") # Create an edge if the adapter is connected to a switch if switch_name: G.add_edge(vm_name, switch_name) return G
Funkcja ta tworzy graf przy użyciu biblioteki NetworkX. Dodaje węzły do grafu reprezentujące przełączniki wirtualne (o typie „switch”) oraz maszyny wirtualne (o typie „vm”). Krawędzie grafu tworzone są pomiędzy maszynami wirtualnymi a przełącznikami wirtualnymi, jeśli adapter sieciowy jest podłączony do danego przełącznika.
def draw_graph(G): """ Draw the graph using matplotlib. Switches are drawn as squares (blue) and VMs as circles (green). """ pos = nx.spring_layout(G, k=1.0, iterations=100, seed=42) # For consistent layout # Separate nodes by type for custom styling switch_nodes = [n for n, d in G.nodes(data=True) if d.get("type") == "switch"] vm_nodes = [n for n, d in G.nodes(data=True) if d.get("type") == "vm"] plt.figure(figsize=(10, 8)) nx.draw_networkx_nodes(G, pos, nodelist=switch_nodes, node_color='lightblue', node_shape='s', node_size=1500, label="Virtual Switch") nx.draw_networkx_nodes(G, pos, nodelist=vm_nodes, node_color='lightgreen', node_shape='o', node_size=1500, label="Virtual Machine") nx.draw_networkx_edges(G, pos) nx.draw_networkx_labels(G, pos, font_size=10) plt.title("Hyper-V Topology: Virtual Switches & VMs") plt.axis('off') plt.legend(scatterpoints=1, labelspacing=1.5, handletextpad=1.0, borderaxespad=1.0) plt.tight_layout() plt.show()
Funkcja ta odpowiada za wizualizację grafu za pomocą biblioteki Matplotlib. Węzły reprezentujące przełączniki wirtualne są rysowane jako niebieskie kwadraty, a węzły reprezentujące maszyny wirtualne jako zielone okręgi. Krawędzie grafu reprezentują połączenia między przełącznikami a maszynami wirtualnymi.
def main(): print("Extracting Hyper-V virtual switches...") switches = get_vmswitches() print(f"Found {len(switches)} switch(es).") print("Extracting Hyper-V VM network adapters...") adapters = get_vmnetworkadapters() print(f"Found {len(adapters)} network adapter(s).") if not switches and not adapters: print("No data retrieved. Ensure Hyper-V is installed and you have proper permissions.") return graph = build_graph(switches, adapters) draw_graph(graph)
Funkcja `main` uruchamia proces zbierania danych o przełącznikach wirtualnych i adapterach sieciowych maszyn wirtualnych, a następnie buduje i rysuje graf przedstawiający te dane. Funkcja ta jest punktem wejścia programu i jest uruchamiana, gdy program jest wykonywany bezpośrednio.
if __name__ == "__main__": main()
Jest to standardowy sposób uruchamiania programu w Pythonie. Jeżeli skrypt jest uruchamiany bezpośrednio, wywoływana jest funkcja `main()`, która rozpoczyna cały proces.
Kod służy do pobierania danych o przełącznikach wirtualnych i adapterach sieciowych maszyn wirtualnych w systemie Hyper-V, budowania grafu przedstawiającego te elementy, a następnie wizualizowania tego grafu za pomocą biblioteki Matplotlib. Używa on PowerShella do pozyskiwania danych oraz NetworkX do manipulacji grafem.