VMware Cloud Community
Jaren_Haywood
Contributor
Contributor
Jump to solution

List VMs with NIC Connection State and VM Power State

Hello,

 

I am working on a script which is capable of querying a vCenter Server for a list of VMs which have at least one NIC attached but not set to connect at power on. The output should also return each respective VM's current power state and a few fields related to NIC attributes such as interface name, type, and current connection state. In my case, the data is stored within a variable and is exported to CSV or presented inside a PowerShell Grid window (dependent on user selection not included in the snippet below).

 

Specifically, I have the following line which successfully (albeit slowly) queries my vCenter Server and returns everything except the present connection state of the NIC:

$Report = Get-VM | Sort-Object name | Get-NetworkAdapter | Where-object {$_.ConnectionState.StartConnected -ne "True"} | Select-Object @{N="VM Name";E="Parent"},@{N="Power State";E={(Get-VM $_.Parent | Select-Object -Property PowerState).PowerState}},@{N="Interface";E="Name"},@{N="Type";E="Type"},@{N="Connect on Boot";E="ConnectionState"}

 

While I suspect there is opportunity for optimization in querying the respective VM's power state (open to suggestions!), I am struggling with returning the NIC Connection State in the form of "Connected" or "NotConnected". The "ConnectionState" is presently returned as "NotConnected, GuestControl, NoStartConnected" - but I just want to know if the state is connected or not. I tried replacing "ConnectionState" with "ConnectionState.Connected", but the output is blank. I cannot help but feel as though I'm missing something silly, but I'm kind of stumped.

 

I have reviewed the community topic below, but haven't found the right combination or arrangement of bits to retrieve the information I'm looking for:
https://communities.vmware.com/t5/VMware-PowerCLI-Discussions/PowerCLI-script-to-find-disconnected-V...

 

Any help would be greatly appreciated! Thank you!

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

My bad, I forgot that the PipelineVariable doesn't work with blocking cmdlet like Sort-Object.

Some blocking commands collect all the pipeline items before producing any output, for example Sort-Object or Select-Object -Last. Any PipelineVariable assigned in a command before such a blocking command always contains the final piped item from the preceding command when used in a command after the blocking command.

When we place the PieplineVariable on the Sort-Object cmdlet it works.

Get-VM |
Sort-Object -Property Name -PipelineVariable vm |
ForEach-Object -Process {
  Get-NetworkAdapter -VM $vm |
  Where-Object { $_.ConnectionState.StartConnected -ne $true} |
  Select-Object @{N = "VM Name"; E = {$vm.Name }},
    @{N = "Power State"; E = { $vm.PowerState } },
    @{N = "Interface"; E = {$_.Name }},
    @{N = 'ConnectionState'; E={if($_.ConnectionState.Connected){'Connected'}else{'NotConnected'}}},
    @{N = "Type"; E = {$_.Type }},
    @{N = "Connect on Boot";E = {$_.ConnectionState.StartConnected}}
}


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

View solution in original post

4 Replies
LucD
Leadership
Leadership
Jump to solution

Try like this

Get-VM -PipelineVariable vm |
  Sort-Object name |
  Get-NetworkAdapter |
  Where-Object { $_.ConnectionState.StartConnected -ne $true} |
  Select-Object @{N = "VM Name"; E = {$vm.Name }},
    @{N = "Power State"; E = { $vm.PowerState } },
    @{N = "Interface"; E = {$_.Name }},
    @{N = 'ConnectionState'; E={if($_.ConnectionState.Connected){'Connected'}else{'NotConnected'}}},
    @{N = "Type"; E = {$_.Type }},
    @{N = "Connect on Boot";E = {$_.ConnectionState.StartConnected}}


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

0 Kudos
Jaren_Haywood
Contributor
Contributor
Jump to solution

Hi @LucD and thank you for the swift response!

 

I replaced the line I provided with your snippet, but added "$Report = " just before the first Get-VM cmdlet. It seems we're making progress - the connection state data is now populating. Unfortunately, the "VM Name" column is now returning the same VM name several times. In other words, I believe I see the correct number of network interfaces, type, etc. but the VM names are not matched. Please see the below screenshot:

2022-09-06_15-42-54.png

 

I suspect I need a foreach loop, correct?

 

Thank you!

0 Kudos
LucD
Leadership
Leadership
Jump to solution

My bad, I forgot that the PipelineVariable doesn't work with blocking cmdlet like Sort-Object.

Some blocking commands collect all the pipeline items before producing any output, for example Sort-Object or Select-Object -Last. Any PipelineVariable assigned in a command before such a blocking command always contains the final piped item from the preceding command when used in a command after the blocking command.

When we place the PieplineVariable on the Sort-Object cmdlet it works.

Get-VM |
Sort-Object -Property Name -PipelineVariable vm |
ForEach-Object -Process {
  Get-NetworkAdapter -VM $vm |
  Where-Object { $_.ConnectionState.StartConnected -ne $true} |
  Select-Object @{N = "VM Name"; E = {$vm.Name }},
    @{N = "Power State"; E = { $vm.PowerState } },
    @{N = "Interface"; E = {$_.Name }},
    @{N = 'ConnectionState'; E={if($_.ConnectionState.Connected){'Connected'}else{'NotConnected'}}},
    @{N = "Type"; E = {$_.Type }},
    @{N = "Connect on Boot";E = {$_.ConnectionState.StartConnected}}
}


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

Jaren_Haywood
Contributor
Contributor
Jump to solution

Hi @LucD ,

 

Thank you - this works brilliantly and I'm grateful for your guidance! I am not familiar with PipelineVariable so thank you for the explanation. I'll read more about this for consideration in future projects. Thanks again!

0 Kudos