Hyper-V Bulk configure VM networks with PowerShell

Hyper-V Bulk configure VM networks with PowerShell

Tired of manually configuring networks for each VM? Perhaps you’re not alone. Virtual network management is time-consuming and error-prone. If I told you there’s a simpler way? This essay examines a PowerShell script that does that. Making your life easy is key. This will teach you how to quickly Bulk Configure VM networks with PowerShell.

This PowerShell script revolutionizes. Create a private switch and assign it to all VMs automatically. Imagine setting up networks without manually selecting VMs. The script verifies network’s existence. If not, it binds your VMs to a new private switch. Automation saves time and reduces errors. Efficiency at its best.

Before you start, make sure you have everything. PowerShell must be installed and running first. Additionally, the script requires administrative permissions to make significant modifications to your VM setup. View your VM network settings. Using this will prevent configuration conflicts. Checked everything? You can automate your VM network setup now.

The Script

$NewSwitchName = Read-Host "Enter the name for the private switch network"
$NewSwitch = Get-VMSwitch -Name $NewSwitchName -ErrorAction SilentlyContinue
if ($null -ne $NewSwitch) {
    Write-Error "Network $NewSwitchName Already Exists"
    end    
}
New-VMSwitch -Name $NewSwitchName -SwitchType Private -

$VMs = Get-VM
foreach ($VM in $VMs) {
    $networkAdapters = Get-VMNetworkAdapter -VMName $vm.Name
    if (!($networkAdapters.name -contains "$NewSwitchName")) {
        Add-VMNetworkAdapter -VMName $vm.Name -SwitchName $NewSwitchName -Name $NewSwitchName
        Connect-VMNetworkAdapter -VMName $vm.Name -Name $NewSwitchName -SwitchName $NewSwitchName
    }
    Start-Sleep -Seconds 5
    Get-VMNetworkAdapter -VMName $vm.Name | Select-Object VMName,SwitchName,MacAddress,IPAddresses,Status,connected | ft
}

The Breakdown

Let’s unravel this script line by line to understand exactly how it simplifies your VM network configurations.

  1. Reading the Switch Name:
    • First, the script prompts you to enter a name for your new private network switch. It uses this name to create or identify the switch.
$NewSwitchName = Read-Host "Enter the name for the private switch network"
  1. Checking for an Existing Switch:
    • It looks up an existing switch by the entered name. If found, it proceeds; if not, it silently handles the error without stopping the script.
$NewSwitch = Get-VMSwitch -Name $NewSwitchName -ErrorAction SilentlyContinue
  1. Error Handling:
    • If a switch with the specified name already exists, the script throws an error and stops. This prevents duplicate networks and potential confusion.
if ($null -ne $NewSwitch) {
    Write-Error "Network $NewSwitchName Already Exists"
    end    
}
  1. Creating the Private Switch:
    • If no existing switch is found, a new private switch is created with the name you provided. This is where the magic of automation starts.
New-VMSwitch -Name $NewSwitchName -SwitchType Private
  1. Grabs the Current VMs:
    • The script fetches a list of all virtual machines on your system.
$VMs = Get-VM
  1. Looping Through VMs:
    • It loops through each VM, checking and modifying network settings as needed.
foreach ($VM in $VMs) {}
  1. Managing Network Adapters:
    • For each VM, it retrieves the network adapters.
foreach ($VM in $VMs) {
    $networkAdapters = Get-VMNetworkAdapter -VMName $vm.Name
}
  1. Conditional Addition and Connection:
    • The script checks if the network adapter with the new switch name already exists.
    • If not, it adds a new adapter and connects it to the created switch.
if (!($networkAdapters.name -contains "$NewSwitchName")) {
        Add-VMNetworkAdapter -VMName $vm.Name -SwitchName $NewSwitchName -Name $NewSwitchName
        Connect-VMNetworkAdapter -VMName $vm.Name -Name $NewSwitchName -SwitchName $NewSwitchName
}
  1. Final Configuration Display:
    • The script pauses briefly, then displays the final configuration of network adapters for verification.
Start-Sleep -Seconds 5
Get-VMNetworkAdapter -VMName $vm.Name | Select-Object VMName,SwitchName,MacAddress,IPAddresses,Status,connected | ft

Each step is crafted to ensure your VM networks are set up efficiently and correctly, without manual repetition. This script is your shortcut to smarter VM management. A great way to Bulk configure VM networks with PowerShell.

Running the script

Running the script is easy. PowerShell needs administrator access to modify VM networks. Go to your script directory. Enter [YourScriptName].Type ps1 and Enter. Enter the network switch name as instructed on-screen. Each VM is configured by the script. Watch it streamline your network one VM at a time.

Fixing Common Problems

Despite this handy script, things may not always go well. Here are some common issues and their solutions:

  • Script Not Starting: Verify administrative permissions. Without these, the script can’t alter network settings.
  • Error “Network Already Exists”: A switch with the specified name already exists. Change the name or remove the switch if it’s unnecessary.
  • Adapters Not Connecting: Make sure your VMs can accept updated network configurations. VMs may need restarts to acknowledge updated settings.
  • Recheck each script step for typos or access rights if you find any issues. PowerShell errors typically indicate the problem, so check the output.

Conclusion

Congratulations on automating VM network setups with PowerShell! Your virtual machine management improved significantly. Try tweaking the script to meet your environment and watch how smooth your operations perform. Share a story or tweak? Leave a comment—let’s learn from each other and establish a smart system admin community!

What can we learn as a person?

Throughout my life, I’ve seen how friends often come from friends. My best friend? I met him because of a kid from the playground, and my wife, well, I met her through someone in a chat room. Even those pals from Discord were introduced by someone else. It’s kind of like that PowerShell script we talked about—making connections that make everything work better.

Building these networks, whether they’re the tight-knit kind or the more extensive, professional types, is crucial. It’s just like setting up networks in PowerShell. You’ve got your internal network—those are your close friends, the ones who really get you. And then there’s your external network, which includes acquaintances and professional contacts. Both are key for different reasons.

Networking events? They’re gold. They throw you into a room with people who might just have the same quirks or career goals. It’s about planting seeds that could grow into either your next job opportunity or into someone you can rely on when things get rough.

Just as our script ensures smooth communication across VMs, weaving through networking events helps build a solid web of contacts. Every handshake or quick chat could be the start of something big—think of each as connecting a new node in your vast network.

Keep it balanced, keep it genuine, and watch as your network—both personal and professional—flourishes. Just like a well-run system of VMs, a well-nurtured network supports and enhances your life in ways you might not even expect.

Additional Reading

Finding Old Snapshots with PowerShell

Finding Old Snapshots with PowerShell

Do you need to find Old Snapshots on a hyper-v server? It’s super easy. So, today we will go through how to get some basic information that allows us to make judgment calls.

The Script – Find Old Snapshots

$Date = (Get-Date).AddDays(-7)
$Vms = Get-VM | where-object { $_.state -like "Running" } 
$Return = foreach ($VM in $Vms) {
    $SnapShots = $VM | Get-VMSnapshot
    foreach ($SnapShot in $SnapShots) {
        if ($snapshot.creationTime -lt $date) {
            [pscustomobject]@{
                SnapShotName         = $SnapShot.name
                SnapShotCreationDate = $SnapShot.CreationTime
                VituralMachine       = $SnapShot.VmName
                Host                 = $SnapShot.ComputerName
            }
        }
    }
}
$Return

The Breakdown

The first part of the script is getting the age requirements. In this case, we want to know anything older than 7 days. So we use the Get-Date command. We add -7 days and this will give us the date to compare by.

$Date = (Get-Date).AddDays(-7)

In this case, we only want the running machines. The reason I want running machines is that the powered-off machines might be in a decommissioning process or for other reasons. So we look at the state of each VM to see if it’s “Running”. We do this with a where-object.

$Vms = Get-VM | where-object { $_.state -like "Running" } 

Now we have the running VMs to work with, we want to get each one’s snapshot. We want to compare each snapshot to see if it’s older than the date. The information we want is the name of the snapshot, the snapshots creation date, the vm, and the hostname. So we start for each loop. Inside the look, we ask with an if statement the creation time is less than the date we created earlier. Then from there we create a PS custom object and pull out the information we want.

$Return = foreach ($VM in $Vms) {
    $SnapShots = $VM | Get-VMSnapshot
    foreach ($SnapShot in $SnapShots) {
        if ($snapshot.creationTime -lt $date) {
            [pscustomobject]@{
                SnapShotName         = $SnapShot.name
                SnapShotCreationDate = $SnapShot.CreationTime
                VituralMachine       = $SnapShot.VmName
                Host                 = $SnapShot.ComputerName
            }
        }
    }
}

Then finally we output the $return value. We can export this to a CSV and drop it into a file share. I personally do this with a nextcloud instance. You can read more about that here. Another option is to email the report using a Microsoft Graph API or an SMTP email system. Finally, if you have confidence in your choice, you can delete the VMs.

Conclusion

Running this script and combining it with the file drop and a few other pieces of automation changed how I worked with multiple clients. This was a good cleanup process and saved many of my clients’ much-needed storage space. Let me know how you use this code for your systems.