VMware Cloud Community
jvlach
Enthusiast
Enthusiast

Script to collect from all VM adapters - portgroup (network), VLAN ID, subnet mask, gateway address

This info is not all in one place, which adds to the complexity. I need to gather from all VM's info on all adapters portgroup and I need the VLAN ID, the gateway address, and the subnet mask. The reason for this is we want to gather portgroup info about both VLAN and network (subnet and gateway).

31 Replies
LucD
Leadership
Leadership

Are you only using VSS or a mix of VSS and VDS switches?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
piercj2
Enthusiast
Enthusiast

How about something like the following.

I don't know how you would get the Gateway Address but the below will give the IP Address on the NIC

$outputfile =  (Get-Date -Format yyyy-MMM-dd-HHmm) + ".csv"

$content = get-vm (Get-Content C:\Temp\vmlist.txt)

$Report=@()

foreach($Computer in $content){

      $GeneralProp=[ordered]@{

           'ComputerName'=$computer.Name;

      }

      $nic = 1

            $Computer | Get-VirtualPortGroup | foreach {

                 $GeneralProp.Add("NIC$($nic) vSwitch",$_.VirtualSwitch)

                 $GeneralProp.Add("NIC$($nic) PortGroup",$_.Name)

                 $GeneralProp.Add("NIC$($nic) VLAN ID",$_.VlanID)

                 $GeneralProp.Add("NIC$($nic) IP", $Computer.Guest.IPAddress[$nic-1])

                 $nic++

             }

       

     $Report += New-Object -TypeName psobject -Property $GeneralProp

}

$Report |

        Sort-Object -Property {($_ | Get-Member -MemberType NoteProperty).Count } -Descending |

        Export-Csv $outputfile -NoTypeInformation

Invoke-Item $outputfile

Reply
0 Kudos
jvlach
Enthusiast
Enthusiast

Just VDS

Reply
0 Kudos
LucD
Leadership
Leadership

Try like this, it should work for VSS and VDS.

Not sure what exactly you mean to get under subnet mask and gateway address.

Is that what you see in a Network Protocol Profile associated with a Portgroup?

Can you perhaps show with a screenshot?

foreach($vm in Get-VM){

    foreach($nic in Get-NetworkAdapter -VM $vm){

        Get-VirtualPortGroup -Name $nic.NetworkName -VM $vm |

        Select @{N='VM';E={$vm.Name}},

            @{N='vNIC';E={$nic.Name}},

            @{N='IP';E={($vm.Guest.Nics | where{$_.NetworkName -eq $nic.NetworkName}).IPAddress -join ','}},

            @{N='Portgroup';E={$_.Name}},

            @{N='VLANId';E={

                if($_ -is [VMware.VimAutomation.ViCore.Types.V1.Host.Networking.DistributedPortGroup]){

                    if($_.ExtensionData.Config.DefaultPortConfig.Vlan -is [VMware.Vim.VmwareDistributedVirtualSwitchPvlanSpec]){

                        $_.ExtensionData.Config.DefaultPortConfig.Vlan.PvlanId

                    }

                    elseif($_.ExtensionData.Config.DefaultPortConfig.Vlan -is [VMware.Vim.VmwareDistributedVirtualSwitchVlanSpec]){

                        if($_.ExtensionData.Config.DefaultPortConfig.Vlan.VlanId -is [VMware.Vim.NumericRange[]]){

                            [string]::Join(',',($_.ExtensionData.Config.DefaultPortConfig.Vlan.VlanId | %{"$($_.Start)-$($_.End)"}))

                        }

                        else{

                            $_.ExtensionData.Config.DefaultPortConfig.Vlan.VlanId

                        }

                    }

                }

                else{$_.VlanId}}},

            @{N='VLAN Type';E={

                if($_ -is [VMware.VimAutomation.ViCore.Impl.V1.Host.Networking.DistributedPortGroupImpl]){

                    switch($_.ExtensionData.Config.DefaultPortConfig.Vlan.GetType().Name){

                        'VmwareDistributedVirtualSwitchPvlanSpec' {'PvLAN'}

                        'VmwareDistributedVirtualSwitchVlanIdSpec' {'VLAN'}

                        'VmwareDistributedVirtualSwitchTrunkVlanSpec' {'VLAN Trunking'}

                        Default {'None'}

                    }

                }

                else{          

                    $_.ExtensionData.GetType().Name

                }}},

            @{N='SwitchType';E={

                if($_ -is [VMware.VimAutomation.ViCore.Impl.V1.Host.Networking.DistributedPortGroupImpl]){

                    'VDS'

                }

                else{'VSS'}}}

    }

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
jvlach
Enthusiast
Enthusiast

Is it possible to get each adapter on its own line when exporting to CSV? Currently it is Joining multiple IP Addresses and separating them with a comma, I would prefer each adapter to be on a separate line.

Reply
0 Kudos
LucD
Leadership
Leadership

The script is already per vNIC (Get-NetworkAdapter), but some vNICs might have multiple IPs.

So you want a row per IP address, if I understand correctly?

That would mean you might have multiple lines per vNIC.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
jvlach
Enthusiast
Enthusiast

Yes I would like each line to have only one ip address, thus it would be the info from only one vNIC.

Reply
0 Kudos
LucD
Leadership
Leadership

Try something like this then

foreach($vm in Get-VM){

    foreach($vnic in $vm.Guest.Nics){

        foreach($ip in $vnic.IPAddress){

            if($vnic.NetworkName -ne $null){

                $pg = Get-VirtualPortGroup -Name $vnic.NetworkName -VM $vm -ErrorAction SilentlyContinue

            }

            else{

                $pg = $null

            }

            $ip | Select @{N='VM';E={$vm.Name}},

                @{N='vNIC';E={$vnic.Device}},

                @{N='IP';E={$ip}},

                @{N='Portgroup';E={$pg.Name}},

                @{N='VLANId';E={

                    if($pg -is [VMware.VimAutomation.ViCore.Types.V1.Host.Networking.DistributedPortGroup]){

                        if($pg.ExtensionData.Config.DefaultPortConfig.Vlan -is [VMware.Vim.VmwareDistributedVirtualSwitchPvlanSpec]){

                            $pg.ExtensionData.Config.DefaultPortConfig.Vlan.PvlanId

                        }

                        elseif($pg.ExtensionData.Config.DefaultPortConfig.Vlan -is [VMware.Vim.VmwareDistributedVirtualSwitchVlanSpec]){

                            if($pg.ExtensionData.Config.DefaultPortConfig.Vlan.VlanId -is [VMware.Vim.NumericRange[]]){

                                [string]::Join(',',($_.ExtensionData.Config.DefaultPortConfig.Vlan.VlanId | %{"$($_.Start)-$($_.End)"}))

                            }

                            else{

                                $pg.ExtensionData.Config.DefaultPortConfig.Vlan.VlanId

                            }

                        }

                    }

                    else{$pg.VlanId}}},

                @{N='VLAN Type';E={

                    if($pg -is [VMware.VimAutomation.ViCore.Impl.V1.Host.Networking.DistributedPortGroupImpl]){

                        switch($_.ExtensionData.Config.DefaultPortConfig.Vlan.GetType().Name){

                            'VmwareDistributedVirtualSwitchPvlanSpec' {'PvLAN'}

                            'VmwareDistributedVirtualSwitchVlanIdSpec' {'VLAN'}

                            'VmwareDistributedVirtualSwitchTrunkVlanSpec' {'VLAN Trunking'}

                            Default {'None'}

                        }

                    }

                    else{         

                        $pg.ExtensionData.GetType().Name

                    }}},

                @{N='SwitchType';E={

                    if($pg -is [VMware.VimAutomation.ViCore.Impl.V1.Host.Networking.DistributedPortGroupImpl]){

                        'VDS'

                    }

                    elseif($pg -eq $null){''}

                    else{'VSS'}}}

        }

    }

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
jvlach
Enthusiast
Enthusiast

This is much better thank you for helping me, I still need the Subnet Mask and Gateway address added as columns.

Reply
0 Kudos
LucD
Leadership
Leadership

As I asked before, which netmask and gateway do you mean?

The ones for a portgroup, or the guest OS specific ones for an IP address?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
jvlach
Enthusiast
Enthusiast

The ones for the guest OS.

Reply
0 Kudos
LucD
Leadership
Leadership

I'm not sure if that is practically possible in a generalised way.

That info is not available in the VirtualMachine object afaik.

That would mean the script would have to query inside the guest OS.

Which in turn creates a dependency on the presence of VMware Tools.

And a foolproof way to determine the actual guest OS, and then the correct guest OS command to query the netmask and the gateway.

The link between the vNic and the guest OS network adapter could be made on the basis of the MAC address, unless the guest OS uses a Locally Administered MAC address.

And how to handle nic bonding and virtual IP addresses?

As you can see, quite a complex algorithm.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
jvlach
Enthusiast
Enthusiast

Ultimately I am trying to gather info on the portgroups, so is that a possibility, to gather the subnet mask and gateway info from the portgroup?

Reply
0 Kudos
LucD
Leadership
Leadership

I'll have to admit defeat I'm afraid, can't find a way to get the netmask and default gateway for a portgroup either.

For a vmkernel that info is present, but not for a portgroup.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
jvlach
Enthusiast
Enthusiast

Thanks for helping me, I appreciate your time

Reply
0 Kudos
edegrave
Contributor
Contributor

I know it's an old one, but does what I need perfectly. Is there a way to get the results in a csv outut? I've tried but getting empty pipe error or only one line in the csv. Must have to do with the for each loop, but don't know how te solve it.
Reply
0 Kudos
LucD
Leadership
Leadership

Correct, a foreach statement doesn't place anything in the pipeline.

But you can do like this

$report = foreach($vm in Get-VM){

    foreach($vnic in $vm.Guest.Nics){

        foreach($ip in $vnic.IPAddress){

            if($vnic.NetworkName -ne $null){

                $pg = Get-VirtualPortGroup -Name $vnic.NetworkName -VM $vm -ErrorAction SilentlyContinue

            }

            else{

                $pg = $null

            }

            $ip | Select @{N='VM';E={$vm.Name}},

                @{N='vNIC';E={$vnic.Device}},

                @{N='IP';E={$ip}},

                @{N='Portgroup';E={$pg.Name}},

                @{N='VLANId';E={

                    if($pg -is [VMware.VimAutomation.ViCore.Types.V1.Host.Networking.DistributedPortGroup]){

                        if($pg.ExtensionData.Config.DefaultPortConfig.Vlan -is [VMware.Vim.VmwareDistributedVirtualSwitchPvlanSpec]){

                            $pg.ExtensionData.Config.DefaultPortConfig.Vlan.PvlanId

                        }

                        elseif($pg.ExtensionData.Config.DefaultPortConfig.Vlan -is [VMware.Vim.VmwareDistributedVirtualSwitchVlanSpec]){

                            if($pg.ExtensionData.Config.DefaultPortConfig.Vlan.VlanId -is [VMware.Vim.NumericRange[]]){

                                [string]::Join(',',($_.ExtensionData.Config.DefaultPortConfig.Vlan.VlanId | %{"$($_.Start)-$($_.End)"}))

                            }

                            else{

                                $pg.ExtensionData.Config.DefaultPortConfig.Vlan.VlanId

                            }

                        }

                    }

                    else{$pg.VlanId}}},

                @{N='VLAN Type';E={

                    if($pg -is [VMware.VimAutomation.ViCore.Impl.V1.Host.Networking.DistributedPortGroupImpl]){

                        switch($_.ExtensionData.Config.DefaultPortConfig.Vlan.GetType().Name){

                            'VmwareDistributedVirtualSwitchPvlanSpec' {'PvLAN'}

                            'VmwareDistributedVirtualSwitchVlanIdSpec' {'VLAN'}

                            'VmwareDistributedVirtualSwitchTrunkVlanSpec' {'VLAN Trunking'}

                            Default {'None'}

                        }

                    }

                    else{        

                        $pg.ExtensionData.GetType().Name

                    }}},

                @{N='SwitchType';E={

                    if($pg -is [VMware.VimAutomation.ViCore.Impl.V1.Host.Networking.DistributedPortGroupImpl]){

                        'VDS'

                    }

                    elseif($pg -eq $null){''}

                    else{'VSS'}}}

        }

    }

}

$report | Export-Csv -Path .\report.csv -NoTypeInformation -UseCulture


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

jeffreywmcclain
Enthusiast
Enthusiast

edit: I also noticed that the script will have errors on the line "Get-VirtualPortGroup -Name $nic.NetworkName -VM $vm", if nic.NetworkName isn't unique ignoring upper and lower case (e.g. if there are 2 networks like "VMGuest ENG - 37" and "VMGuest Eng - 37").

When I run this script, I get the following warning:

"WARNING: The output of the command produced distributed virtual switch objects. This behavior is obsolete and may change in the future. To retrieve distributed switches, use Get-VDSwitch cmdlet in the VDS component. To retrieve standard switches, use -Standard."

I know it's just a warning, but would you happen to know how to modify the script to not use behavior that might become obsolete, while keeping the functionality intact?

I don't recall seeing this warning in the past, so maybe VMware changed / updated something.

Thanks for all the assistance you provide on the forums, I really appreciate it (as I'm sure countless others do as well)!

Reply
0 Kudos
LucD
Leadership
Leadership

Concerning the warning, did you check with Get-PowerCLIConfiguration, how the setting for DisplayDeprecationWarnings is configured?

That might have changed in your installation.

I will have to update the script to avoid these warning and to handle case sensitivity correctly.

I'll update this thread when I have something.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos