Powershell

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button