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).
Are you only using VSS or a mix of VSS and VDS switches?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
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
Just VDS
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
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.
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
Yes I would like each line to have only one ip address, thus it would be the info from only one vNIC.
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
This is much better thank you for helping me, I still need the Subnet Mask and Gateway address added as columns.
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
The ones for the guest OS.
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
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?
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
Thanks for helping me, I appreciate your time
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
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)!
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