Gather VM IP Addresses using PowerCLI

Today I needed to find a way to gather a list of the IP’s for all of our VM’s so I came up with this little one-liner, so thought I’d share it with you:

get-vm | select Name,@{N="IP Address";E={@($_.guest.IPAddress[0])}} |
         out-file c:\VM_IP_Addresses.csv

It’ll get all of the VM’s in the environment, and then list out the first IP address for each one. If you have multiple IP’s on some hosts, then remove the “[0]” section in the above and it’ll list all of them. The output will be tab delimited text rather than comma separated.

32 Replies to “Gather VM IP Addresses using PowerCLI”

      1. Hello,
        This is great!!

        Do you know how i can get list of the IP and then connect to windows and grab all the subnet, gateway and DNS config and export it to file?

        with your script i can get all the vm names and ip but i also want to grab the subent, gatway and DNS info.

        Please help

        Thank you

        1. Hi Abiy,
          You need to take the output and then use invoke-vmscript to get that done. This isn’t a hugely simple task, so can’t let you know exactly how to do this by reply. If I get a chance I’ll see what I can do, but that’s a rather big if at the moment!

          Dan

  1. Your one-liner is the most productive I have seen so far. Please try it with export-csv for better transformation and loading. Do you think this could be used to get just windows servers from the VIserver or ESXi server.

    1. Hi Joe,
      Sure can, bit of a convoluted method though:

      get-vm | get-view | where {$_.Guest.GuestFullName -like "*Windows*"} | select Name,@{N="OS";E={@($_.Guest.GuestFullName)}},@{N="IP";E={@($_.Guest.IPAddress)}} | export-csv -notypeinformation $env:userprofile\desktop\export.csv
      
  2. Thanks a lot for the script.
    Im a just a beginner(started a few days back) in PowerCli. Do you have any tutorials wherein i can learn about some basic attribute retrival from vsphere?
    Further, in the above command, how do you get the information about Storage(storage status,drive type)

    Thanks

    Rajesh

  3. How would I list VMs that reside on a certain subnet, instead of all subnets? ie: list all VMs on 192.168.200.0 -through- 192.168.200.254
    Thanks
    Jeff

    1. Hi Jeff,

      Off the top if my head, like this:

      get-vm | 
      select Name,@{N="IPAddress";E{@($_.guest.IPAddress[0])}} | 
      where {$_.IPAddress -like "192.168.200.*"} |
       out-file c:\VM_IP_Addresses.csv
      

      Dan

    1. Hi Karthik,
      Gathering the IP requires VMware Tools, and this needs to be running in the guest OS, so you won’t get information regarding powered off VM’s, as it isn’t available to vCenter or the ESX(i) host.

      Regards,

      Dan

  4. Hi Dan – good scripting work, I am trying to modify your script to also list the adapter type in use and am having difficulty accomplishing this. I do fine with the VM and IP per your script, and I also have a script I have been using that captures VM and adapter type, but haven’t figured out how to capture VMname, IP, and adapter type in the single output file… any ideas?

    My goal is to produce a file that shows all the VMs with IP and adapter type in one csv file so that the file produced can then be referenced by 2 other scripts. 1 script to swap out the adapters of all the VMs that are still configured with e1000 to vmxnet3. The second to reconfigure the IP stack of the newly installed vmxnet3 adapters using invoke-vmscript. swapping out e1000 for vmxnet3 blows away static ip in favor of DHCP and when you have 60 VMs to upgrade the ability to reconfigure the IP using invoke-vmscript is key.. and works great. I have all the scripts I need working but just can’t seem to get my initial script that needs to run to collect the values I require in the CSV, that being name, ip, adapter type. I’ll be happy to share any of the scripts I just mentioned if you are interested. I’m tired of manually editing the output file I’ve been creating to add the IP address of the VMs.. that is when I found your post.. I’ve been trying to integrate my script with yours but have fallen flat… any help you can provide would be nice and thanks in advance..

    1. Hi gman,
      This probably isn’t the most elegant method, but it should work:

      $out="Name,IPAddress,Type"+"`n"
      foreach ($vm in (get-vm)){$vminfo= get-vm $vm | select Name,@{N="IPAddress";E={@($_.guest.IPAddress[0])}}; $NIC=Get-NetworkAdapter -VM $VMInfo.Name; $Name=$vmInfo.name; $IP=$VMInfo.IPAddress; $NicType=$NIC.type; $out=$Out+"$Name,$IP,$NICType"+"`n"}
      out-file -inputobject $out -filepath $ENV:USERPROFILE\Desktop\VM_NIC_INFO.csv
      

      Just remember that you’ll only get IP Address information from powered on VM’s, and they must have VMware Tools installed. You can filter the get-vm statement at the start of the foreach loop with a ” | where $_.Powerstate -eq “PoweredOn” ” if you want to stop the script looking at suspended/powered off VMs. Just keep that where statement to the left the double close braces.

      Dan

      1. Hi Dan – thanks for the quick response, the script works nicely to produce the required output, and is quite a piece of work I might add, just not in the format I need. the output file needs to come from an export-CSV cmdlet so it is in the proper format for the other scripts to read from it. I tried replacing output-file with export-csv but it falls apart. Any thoughts about how to use export-csv within this script?

        1. Hello again gman,
          I’m glad you made me look at this again… as it made me learn something too, which is always a good thing with Powershell!

          Though I’ve imported CSV files written the way I had done in my previous comment, this way should definitely work, and in fact, it’s much less complex script!!!

          $out=@()
          foreach ($vm in (get-vm)){$vminfo= get-vm $vm | select Name,@{N="IPAddress";E={@($_.guest.IPAddress[0])}},@{N="NICType";E={@((get-networkadapter -VM $vm).Type)}}
          $out+=$vminfo}
          $out | export-csv -path $env:userprofile\Desktop\VM_NIC_INFO.csv -notypeinformation -force
          

          To clarify what this does:
          Line 1: Creates an empty array for the output information.
          Line 2: Gets a list of all VM’s, then for each VM in that list, gathers the Name and IP Address from the Get-VM cmdlet, then calls the get-networkadapter cmdlet and adds the “Type” information gathered to the array ($vminfo) made from the original get-vm cmdlet.
          Line 3: Adds $vminfo into the $out array for each VM found at line 2.
          Line 4: Pipes $out to Export-CSV and creates a well formatted CSV file for you, and saves it to your desktop (technically it’s the desktop of the user running the script).

          Again, if you only want powered on VM’s (so that you don’t get rows with empty IP Address values), then Line 2 should look like this:

          foreach ($vm in (get-vm | where {$_.Powerstate -eq "PoweredOn"})){$vminfo= get-vm $vm | select Name,@{N="IPAddress";E={@($_.guest.IPAddress[0])}},@{N="NICType";E={@((get-networkadapter -VM $vm).Type)}}
          

          Let me know if this works, but it should work perfectly with your import-csv requirement!

          Cheers,

          Dan

          1. Thanks Dan – new changes work like a charm.. for my purpose I replaced the (get-vm) with (get-vm -location $cluster) and define the $cluster variable up top along with a few other connection related pieces…

            In return for your much appreciated help, here is a nice tidbit for you to make use of and share out to your community of followers.

            This script will allow you to configured IP stack of VMs off the wire using invoke-vmscript CMDlet. This might seem trivial and easy enough at first thought, but the important thing is that you can’t configure a network adapter unless you know the specific adapter, and in windows this is a pain because of the hidden adapters created when deploying VMs from templates.. so the code here queries the guest os for the adapter name and then creates a variable from the query and then another variable from this variable just to wrap the quotes around it needed.. lots of fun.. (quotes are not needed around guest pw unless special character is in use)

            $vcenter = "x.x.x.x"
            $SNM = "255.255.255.0" 
            $GW = "x.x.x.x" 
            $dns1 = "x.x.x.x"
            $dns2 = "x.x.x.x"
            
            #   Define the functions to set IP,SNM, and GW
            
            Function Set-WinVMIP ($VM, $IP, $SNM, $GW){ 
            
            Invoke-VMScript -VM $VM -GuestUser administrator -GuestPassword 'xxxxx' -ScriptType bat -ScriptText ipconfig | select-string -pattern "Local Area Connection[ ]?[\d]*" | % { $_.Matches } | % {$_.Value} | new-variable LAC
            $LAC1 = $LAC -replace ".$"
            $LAC2 = '"' + $LAC1 + '"'
            
            $netsh = "c:\windows\system32\netsh.exe interface ip set address $LAC2 static $IP $SNM $GW 1" 
            
            Write-Host "Setting IP address for $VM..." 
            
            Invoke-VMScript -VM $VM -GuestUser administrator -GuestPassword 'xxxxxx' -ScriptType bat -ScriptText $netsh 
            
            Write-Host "Setting IP address completed." 
            } 
            
            Connect-VIServer $vcenter
            foreach ($_.VMname in (Import-Csv "$ENV:USERPROFILE\desktop\vm-ip.csv" -UseCulture) ) {
            $VM = Get-VM $_.VMname
            Set-WinVMIP $VM -GuestUser administrator -GuestPassword 'xxxxxx' $_.IP $SNM $GW
            }
            Disconnect-VIServer
            
          2. Hey gman,
            Glad the script worked out for you, and thanks for the return script to complete what you needed to do with the output from mine 🙂

            Made a slight amendment to your script (there was a missing ” at the end of the first $vcenter= line, and then I wrapped it with code so that it displays as a code block on the blog. 🙂

            Dan

      2. Hey Dan,

        this command is giving error.. please help

        $out=”Name,IPAddress,Type”+”`n”
        foreach ($vm in (get-vm)){$vminfo= get-vm $vm | select Name,@{N=”IPAddress”;E={@($_.guest.IPAddress[0])}}; $NIC=Get-NetworkAdapter -VM $VMInfo.Name; $Name=$vmInfo.name; $IP=$VMInfo.IPAddress; $NicType=$NIC.type; $out=$Out+”$Name,$IP,$NICType”+”`n”}
        out-file -inputobject $out -filepath $ENV:USERPROFILE\Desktop\VM_NIC_INFO.csv

  5. To get all the guest ips joined together by commas rather than tabs, you can do:

    Get-VM | select *, @{l=”GuestIps”;e={[string]::join(‘,’, $_.guest.IPAddress)}} | Export-Csv -NoTypeInformation -Path vms.csv

    In database terms this “de-normalises” the data, but this is often fine for reporting.

    1. Thanks for that Sonia… at the time I was only interested in the first IP of each VM, hence the part that only picks up the first IP in the array (the zero in square brackets in case readers don’t know).

    2. Works well Sonia, thanks. Gives all the IP addresses amongst all other things 🙂

      Is now out of date and gives several warnings but does the job still on ESXi5.0
      Rich

    1. Like this:

      get-vm | select Name,@{N=”IP Address”;E={@($_.guest.IPAddress[0])}},@{N=”OS”;E={@($_.guest.OSFullName)}} | out-file c:\VM_IP_Addresses.csv

      Apologies for the formatting, I’m replying from my phone, so it may not be great!!

      Dan

  6. Hello,
    This is great!!

    Do you know how i can get list of the IP and then connect to windows and grab all the subnet, gateway and DNS config and export it to file?

    with your script i can get all the vm names and ip but i also want to grab the subent, gatway and DNS info.

    Please help

    Thank you

  7. Hi Dan,

    I tried your method. However it only returns the IP address of Windows machine but not Linux (Ubuntu) boxes. Any suggestions?

    1. Hi Deepak,
      The VM’s must be powered on and have VMware tools installed, else the addresses won’t be gathered.

      I’ve about 200 Linux VM’s in an environment I use this script on with no issues…

      Dan

  8. Dan, Best script I’ve found so far.
    I removed the [0] to get all IPs but it listed only the first four followed by ‘…’
    I know that one VM has six IPs attached to the one NIC.
    Is there a reason it stops at four reported IPs?

    As a bonus, it also shows which NICs still have IPv6 enabled. 🙂
    Thanks
    Rich

Leave a Reply

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


CAPTCHA Image
Reload Image