Retrieving VM Network Settings with PowerShell and PowerCLI
Recently, one of my clients requested information about virtual machines (VMs) such as IP address, subnet mask, and default gateway for a specific VLAN. To streamline the process, I decided to create a quick PowerShell script using the VMware.PowerCLI module.
What is VMware.PowerCLI?
VMware.PowerCLI is a powerful command-line interface (CLI) tool that allows you to manage and automate VMware vSphere environments using PowerShell. It provides a wide range of cmdlets specifically designed for managing VMware infrastructure, making it an ideal choice for automating repetitive tasks.
Getting Started with VMware.PowerCLI
To begin, you’ll need to install the VMware.PowerCLI module. Open a PowerShell console with administrative privileges and run the following command:
Install-Module -Name VMware.PowerCLI -Scope CurrentUser
This command will download and install the latest version of the VMware.PowerCLI module from the PowerShell Gallery.
you can install VMware.PowerCLI on a computer that is not connected to the internet by manually downloading the PowerCLI module from the internet-connected machine and then transferring it to the offline machine by using this methode.
Connecting to the VMware vSphere Environment
Once the module is installed, you can connect to your VMware vSphere environment using the Connect-VIServer cmdlet. This cmdlet requires the IP address or hostname of your vCenter Server and your credentials.
Connect-VIServer -Server <vCenterServer> -User <Username> -Password <Password>
Replace <vCenterServer>, <Username>, and <Password> with the appropriate values for your environment.
Retrieving VM Information
With the VMware.PowerCLI module connected to your vSphere environment, you can now retrieve the required information for the specific VLAN. The following PowerShell script demonstrates how to retrieve the IP address, subnet mask, and default gateway for VMs on a particular VLAN:
$PG_VLANID = "123" # Replace with the VLAN ID you want to query
# Getting PortGroup Name
$PG_NAME = Get-VDPortgroup | ForEach-Object {if (($_.VlanConfiguration).VlanId -eq $PG_VLANID){ $_.Name }}
Write-Host "PortGroup Name is $PG_NAME"
# Getting all VMs attached to the specified PortGroup
$VMs = Get-VirtualPortGroup -Name $PG_NAME | Get-VM | Select-Object -ExpandProperty Name
Write-Host "Number of VMs attached to this PortGroup is $($VMs.count)"
foreach($VM in $VMs){
Write-Host "---------------- $VM ----------------"
Write-Host " VM Name: $VM"
$VM_detail = Get-VM -Name $VM
# check the status of the VM & VM Tools.
if (($VM_detail.PowerState -eq "PoweredOn") -and (($VM_detail.Guest).State -eq "Running")){
Write-Host " VM is $($VM_detail.PowerState)."
Write-Host " VM Tools is $(($VM_detail.Guest).State)."
$VM_OS = $VM_detail.Guest.OSFullName
$VM_IP = $VM_detail.Guest.IPAddress[0]
$VM_MASK = $VM_detail.ExtensionData.Guest.IpStack.IpRouteConfig.IpRoute | where {$_.Network -eq "$($VM_IP.Substring(0,$VM_IP.LastIndexOf("."))).0"} | select -ExpandProperty PrefixLength
$VM_GATEWAY = $VM_detail.ExtensionData.Guest.IpStack.IpRouteConfig.IpRoute.Gateway.IpAddress | where {$_ -ne $null}
$VM_DNS = [string]::Join(',',($VM_detail.ExtensionData.Guest.IpStack.DnsConfig.IpAddress))
Write-Host " OS: $VM_OS"
Write-Host " IP Address: $VM_IP"
Write-Host " MASK: $VM_MASK"
Write-Host " Default Gateway: $VM_GATEWAY"
Write-Host " DNS: $VM_DNS"
}
else {
Write-Host " VM is $($VM_detail.PowerState)."
Write-Host " VM Tools is $(($VM_detail.Guest).State)."
$VM_OS = $VM_detail.Guest.OSFullName
Write-Host " OS: $VM_OS"
Write-Host " IP Address: N/A"
Write-Host " MASK: N/A"
Write-Host " Default Gateway: N/A"
Write-Host " DNS: N/A"
}
Write-Host "--------------------------------------------"
Make sure to replace “123” in the $PG_VLANID variable with the actual VLAN ID you want to query. This script retrieves all VMs connected to the specified VLAN and displays their respective IP address, subnet mask, and default gateway.
Final Script
Here is the script that i created for my client to achieve this task. The script automates the process and generates a CSV result file named ‘VMs_VlanID.csv,’ streamlining data output for efficient analysis and reference.
<#
===========================================================================
Script Name: Get-VM-Netwrork-Settings
Version: 0.1
Modified on: 23.01.2023
Created by: Abdelilah BAKIR
===========================================================================
#>
param ([Parameter(Mandatory)]$VcenterServer)
if ( -Not (Test-Path -Path .\Logs)){
Write-Host "$(Get-Date -Format G) : Creating Logs Folder.." -ForegroundColor Green
New-Item -Name Logs -ItemType Directory -Force -ErrorAction Stop
}
$logpath = "Logs\$(get-date -format s | foreach {$_ -replace ":", "."}).log"
function Write-Log
{
param($msg,$color)
if ($color -eq "Red"){
Write-host "$(Get-Date -Format G) : $msg" -ForegroundColor Red
}
elseif ($color -eq "Green") {
Write-host "$(Get-Date -Format G) : $msg" -ForegroundColor Green
}else {
Write-host "$(Get-Date -Format G) : $msg"
}
"$(Get-Date -Format G) : $msg" | Out-File -FilePath $logpath -Append -Force
}
if ([string]::IsNullOrEmpty($(Get-Module -Name VMware.PowerCLI -ListAvailable))) {
Write-Log "VMware.PowerCLI module is not Installed." -color Red
$Installation_Choice = Read-Host "Do you Want to install it. (Y/N)"
switch ($Installation_Choice.Trim())
{
"y"
{
Write-Log "Starting Instalaltion of VMware.PowerCLI module." -color Green
try
{
Install-Module VMware.PowerCLI -Force
}
catch
{
$ErrorMessage = $_.Exception.Message
Write-Log "$ErrorMessage" -color Red
Start-Sleep -Seconds 120
exit 1
}
}
"n" {
Write-Log "Instalaltion aborted. Exiting in 1 minutes." -color Red
Start-Sleep -Seconds 60
Exit 1
}
}
}
if ($Authenticated -ne $True){
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -ParticipateInCeip $false -Confirm:$false
do
{
try
{
$MyCredentials = Get-Credential
}
catch
{
$ErrorMessage = $_.Exception.Message
Write-Log "$ErrorMessage" -color Red
Write-Log "Exiting in 1 minutes." -color Red
Start-Sleep -Seconds 120
exit 1
}
if (Connect-VIServer -server $VcenterServer -Credential $MyCredentials -ErrorAction SilentlyContinue){
Write-Log "Authentication success. Go to the next step..." -color Green
$Authenticated = $true
}
else{
$Authenticated = $false
Write-Log "Something went wrong, Try again please." -color Red
}
}
while ($Authenticated -eq $false)
}
$PG_VLANID = (Read-Host "Enter the VLAN ID").Trim()
try
{
$PG_NAME = Get-VDPortgroup | ForEach-Object {if (($_.VlanConfiguration).VlanId -eq $PG_VLANID){ $_.Name }}
if ( [string]::IsNullOrEmpty($PG_NAME)){
Write-Log "VLAN ID $PG_VLANID is not Exist." -color Red
Write-Log "Exiting in 2 minutes." -color Red
Start-Sleep -Seconds 120
Exit 1
}
Write-Log "PortGroup Name is $PG_NAME" -color Green
$VMs = Get-VirtualPortGroup -Name $PG_NAME | Get-VM | Select-Object -ExpandProperty Name
if ( [string]::IsNullOrEmpty($($VMs))){
Write-Log "No VM attached to Vlan ID $PG_VLANID." -color Red
Write-Log "Exiting in 2 minutes." -color Red
Start-Sleep -Seconds 120
Exit 1
}
Write-Log "Number of VMs attached to this PortGroup is $($VMs.count) " -color Green
$ResulFileName = "VMs_$PG_VLANID.csv"
"VM Name;VM Status;VM Tools;OS;IP Address; MASK;Default Gateway;DNS" | Out-File -FilePath $ResulFileName -force
}
catch
{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
Write-Log "$ErrorMessage" -color Red
Start-Sleep -Seconds 120
exit 1
}
foreach($VM in $VMs){
Write-Log "---------------- $VM ----------------"
Write-Log " VM Name: $VM"
$VM_detail = Get-VM -Name $VM
if (($VM_detail.PowerState -eq "PoweredOn") -and (($VM_detail.Guest).State -eq "Running")){
Write-Log " VM is $($VM_detail.PowerState)."
Write-Log " VM Tools is $(($VM_detail.Guest).State)."
$VM_OS = $VM_detail.Guest.OSFullName
$VM_IP = $VM_detail.Guest.IPAddress[0]
$VM_MASK = $VM_detail.ExtensionData.Guest.IpStack.IpRouteConfig.IpRoute | where {$_.Network -eq "$($VM_IP.Substring(0,$VM_IP.LastIndexOf("."))).0"} | select -ExpandProperty PrefixLength
$VM_GATEWAY = $VM_detail.ExtensionData.Guest.IpStack.IpRouteConfig.IpRoute.Gateway.IpAddress | where {$_ -ne $null}
$VM_DNS = [string]::Join(',',($VM_detail.ExtensionData.Guest.IpStack.DnsConfig.IpAddress))
Write-Log " OS: $VM_OS"
Write-Log " IP Address: $VM_IP"
Write-Log " MASK: $VM_MASK"
Write-Log " Default Gateway: $VM_GATEWAY"
Write-Log " DNS: $VM_DNS"
"$VM;$($VM_detail.PowerState);$(($VM_detail.Guest).State);$VM_OS;$VM_IP;$VM_MASK;$VM_GATEWAY;$VM_DNS" | Out-File -FilePath $ResulFileName -Append
}else {
Write-Log " VM is $($VM_detail.PowerState)."
Write-Log " VM Tools is $(($VM_detail.Guest).State)."
$VM_OS = $VM_detail.Guest.OSFullName
Write-Log " OS: $VM_OS"
Write-Log " IP Address: N/A"
Write-Log " MASK: N/A"
Write-Log " Default Gateway: N/A"
Write-Log " DNS: N/A"
"$VM;$($VM_detail.PowerState);$(($VM_detail.Guest).State);$VM_OS;N/A;N/A;N/A;N/A" | Out-File -FilePath $ResulFileName -Append
}
Write-Log "--------------------------------------------"
}
Write-Log "Please check the Result file $ResulFileName" -color Green
Save the script with a .ps1 file extension (e.g., get-vm-info.ps1) and run it from a PowerShell console. Ensure that you have the appropriate permissions to access the vSphere environment.
Wrapping Up
Using the VMware.PowerCLI module, you can quickly retrieve VM information such as IP address, subnet mask, and default gateway for a specific VLAN. By automating this process with PowerShell, you can save time and effort, especially when dealing with large-scale VMware environments.
Remember to always test your scripts in a non-production environment before running them in a production environment. This ensures that you are familiar with the script’s behavior and prevents any unintended consequences.
I trust this article was beneficial for you. If there’s anything you’d like to discuss or inquire about, please don’t hesitate to leave a comment below.
Thank you for being part of our community. Let’s explore, learn, and grow together at MyITDailyDose.com.
