markus81
Contributor
Contributor

Get List of VMs, Datastores and VMDK / path per Cluster

Jump to solution

Hi Folks,

as I´m new to this stuff, I´m wondering if anybody has already done some scripting work to gather a list of all virtual machines, its corresponding datastore(s) and the path to the VMDK-Files (or at least the name of it) - I know this part is already solved - found a couple of them 😉

But my problem is, I need this script drilled down per Cluster or Datacenter. As I said I´m completly new to this CLI-Stuff and don´t have a clue about how to solve this..

Cheers

Markus

1 Solution

Accepted Solutions
RvdNieuwendijk
Leadership
Leadership

Luc, you are right. I should have tested this.  Smiley Sad

This is a disadvantage of the ForEach command that I almost never use. Normally I use the Foreach-Object cmdlet and that works fine with pipeing the output to Export-CSV.

Markus you have to use option 2 in this case.

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition

View solution in original post

0 Kudos
54 Replies
RvdNieuwendijk
Leadership
Leadership

Hi Markus,

Welcome to the VMware Communities!

The next PowerCLI script will give you a list of all your VM's and their Datacenter, Cluster, HardDisks, Datastores and VMDK file paths. If you want to have the VM's only for a certain datacenter or cluster, you can filter the output by piping it to the Where-Object cmdlet.

ForEach ($Datacenter in (Get-Datacenter | Sort-Object -Property Name)) {
  ForEach ($Cluster in ($Datacenter | Get-Cluster | Sort-Object -Property Name)) { 
    ForEach ($VM in ($Cluster | Get-VM | Sort-Object -Property Name)) {
      ForEach ($HardDisk in ($VM | Get-HardDisk | Sort-Object -Property Name)) {
        "" | Select-Object -Property @{N="VM";E={$VM.Name}},
          @{N="Datacenter";E={$Datacenter.name}},
          @{N="Cluster";E={$Cluster.Name}},
          @{N="Hard Disk";E={$HardDisk.Name}},
          @{N="Datastore";E={$HardDisk.FileName.Split("]")[0].TrimStart("[")}},
          @{N="VMDKpath";E={$HardDisk.FileName}}
      }
    }
  }
}    

Don't hesitate to ask in this forum if you need more help.

Regards, Robert

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
0 Kudos
markus81
Contributor
Contributor

Hi Robert,

many thanks! That´s exactly what I´m looking for I think. I´m only struggling with one last thing... the Export-CSV-Thing... My  understanding would be someting like

$myVariable | Export-CSV blablabla..

But how would i define the $myVariable in your script?

I´m sorry for those really stupid rookie-questions ... have to talk to my boss that I need time and lessons to learn this stuff 😉

Thanks,

Markus

0 Kudos
RvdNieuwendijk
Leadership
Leadership

There are two options if you want to write the output of the script to a .csv file. You can change the last line of the script into:

} | Export-Csv -NoTypeInformation -UseCulture -Path "VmInfo.csv"

This will pipe the output of the script to the Export-CSV cmdlet. And it will create a .csv file called VmInfo.csv.

The second option is to change the first line of the script into:

$VmInfo = ForEach ($Datacenter in (Get-Datacenter | Sort-Object -Property Name)) {

And append the following line at the end of the script:

$VmInfo | Export-Csv -NoTypeInformation -UseCulture -Path "VmInfo.csv"

This will put the output of the script from my previous post into a variable $VmInfo. In the last line the variable is used to output it to a .csv file.

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
0 Kudos
LucD
Leadership
Leadership

Isn't option 1 giving you the infamous "An empty pipe element is not allowed." error ?


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

0 Kudos
RvdNieuwendijk
Leadership
Leadership

Luc, you are right. I should have tested this.  Smiley Sad

This is a disadvantage of the ForEach command that I almost never use. Normally I use the Foreach-Object cmdlet and that works fine with pipeing the output to Export-CSV.

Markus you have to use option 2 in this case.

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
0 Kudos
markus81
Contributor
Contributor

You guys are crazy 😉

Exactly what I  need 🙂 Many thanks to you ! Have just tested and works fine! If I find some spare time I´m trying to modify it a little bit more for more granularity in regards of choosing the cluster manually but for now that works perfect 🙂

Cheers
Markus

0 Kudos
markus81
Contributor
Contributor

Shame on me... Forgot one more thing .... Configuratio File of the VM...

Can anyone give a hint how to include this also?

0 Kudos
RvdNieuwendijk
Leadership
Leadership

You can add the VM's configuration file to the script by changing the script into:

$VmInfo = ForEach ($Datacenter in (Get-Datacenter | Sort-Object -Property Name)) {
  ForEach ($Cluster in ($Datacenter | Get-Cluster | Sort-Object -Property Name)) { 
    ForEach ($VM in ($Cluster | Get-VM | Sort-Object -Property Name)) {
      ForEach ($HardDisk in ($VM | Get-HardDisk | Sort-Object -Property Name)) {
        "" | Select-Object -Property @{N="VM";E={$VM.Name}},
          @{N="Datacenter";E={$Datacenter.name}},
          @{N="Cluster";E={$Cluster.Name}},
          @{N="Hard Disk";E={$HardDisk.Name}},
          @{N="Datastore";E={$HardDisk.FileName.Split("]")[0].TrimStart("[")}},
          @{N="VMConfigFile";E={$VM.ExtensionData.Config.Files.VmPathName}},
          @{N="VMDKpath";E={$HardDisk.FileName}}
      }
    }
  }
}
$VmInfo | Export-Csv -NoTypeInformation -UseCulture -Path "VmInfo.csv"

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
GlennL10
Contributor
Contributor

Hi guys,


Great script, works well, but I was wondering if it's possible to get the size of the VMDK file added to the output as well? How would I do this?

0 Kudos
CRad14
Hot Shot
Hot Shot
I will just add one line to this

$VmInfo = ForEach ($Datacenter in (Get-Datacenter | Sort-Object -Property Name)) {
  ForEach ($Cluster in ($Datacenter | Get-Cluster | Sort-Object -Property Name)) { 
    ForEach ($VM in ($Cluster | Get-VM | Sort-Object -Property Name)) {
      ForEach ($HardDisk in ($VM | Get-HardDisk | Sort-Object -Property Name)) {
        "" | Select-Object -Property @{N="VM";E={$VM.Name}},
          @{N="Datacenter";E={$Datacenter.name}},
          @{N="Cluster";E={$Cluster.Name}},
          @{N="Hard Disk";E={$HardDisk.Name}},
          @{N="Datastore";E={$HardDisk.FileName.Split("]")[0].TrimStart("[")}},
          @{N="VMConfigFile";E={$VM.ExtensionData.Config.Files.VmPathName}},
          @{N="VMDKpath";E={$HardDisk.FileName}},
          @{N="VMDK Size";E={($vm.extensiondata.layoutex.file|?{$_.name -contains $harddisk.filename.replace(".","-flat.")}).size/1GB}}
      }
    }
  }
}
$VmInfo | Export-Csv -NoTypeInformation -UseCulture -Path "VmInfo.csv"

Message was edited by: CRad14

Conrad www.vnoob.com | @vNoob | If I or anyone else is helpful to you make sure you mark their posts as such! 🙂
GlennL10
Contributor
Contributor

Thanks for the reply, but I don't get the sizes in the final report, in fact it's still the same?

0 Kudos
CRad14
Hot Shot
Hot Shot

Hah!!! I missed a comma, I edited that post, it should be correct now.

Conrad www.vnoob.com | @vNoob | If I or anyone else is helpful to you make sure you mark their posts as such! 🙂
0 Kudos
GlennL10
Contributor
Contributor

Thanks for your help, it works!

0 Kudos
alize77
Contributor
Contributor

Is there a way to capture multiple IP address of those VMs as well? Tried to include some of the scripts I got online to merge with this one but just couldn't get it to work correctly. Currently, I only manage to capture 1 IP address.

$VmInfo = ForEach ($Datacenter in (Get-Datacenter | Sort-Object -Property Name)) {
  ForEach ($Cluster in ($Datacenter | Get-Cluster | Sort-Object -Property Name)) {
    ForEach ($VM in ($Cluster | Get-VM | Sort-Object -Property Name)) {
      ForEach ($IP in $VM.Guest.IPAddress) {
        ForEach ($HardDisk in ($VM | Get-HardDisk | Sort-Object -Property Name)) {
        "" | Select-Object -Property @{N="VM";E={$VM.Name}},
          @{N="Datacenter";E={$Datacenter.name}},
          @{N="Cluster";E={$Cluster.Name}},
          @{N="IP";E={$IP}},
          @{N="Hard Disk";E={$HardDisk.Name}},
          @{N="Datastore";E={$HardDisk.FileName.Split("]")[0].TrimStart("[")}},
          @{N="VMConfigFile";E={$VM.ExtensionData.Config.Files.VmPathName}},
          @{N="VMDKpath";E={$HardDisk.FileName}},
          @{N="VMDK Size";E={($vm.extensiondata.layoutex.file|?{$_.name -contains $harddisk.filename.replace(".","-flat.")}).size/1GB}}
}
      }
    }
  }
}
$VmInfo | Export-Csv -NoTypeInformation -UseCulture -Path "VmInfo.csv"
0 Kudos
LucD
Leadership
Leadership

The IPAddress property is an array, you can always join the elements of this array into 1 string.

But note that you will get these same IP addresses (VM-level) displayed for each harddisk attached to that VM.

Something like this

$VmInfo = ForEach ($Datacenter in (Get-Datacenter | Sort-Object -Property Name)) {
  ForEach ($Cluster in ($Datacenter | Get-Cluster | Sort-Object -Property Name)) {
    ForEach ($VM in ($Cluster | Get-VM | Sort-Object -Property Name)) {
      ForEach ($HardDisk in ($VM | Get-HardDisk | Sort-Object -Property Name)) {
        "" | Select-Object -Property @{N="VM";E={$VM.Name}},
        @{N="Datacenter";E={$Datacenter.name}},
        @{N="Cluster";E={$Cluster.Name}},
       
@{N="IP";E={[string]::Join(',',$VM.Guest.IPAddress)}},
       
@{N="Hard Disk";E={$HardDisk.Name}},
        @{N="Datastore";E={$HardDisk.FileName.Split("]")[0].TrimStart("[")}},
        @{N="VMConfigFile";E={$VM.ExtensionData.Config.Files.VmPathName}},
        @{N="VMDKpath";E={$HardDisk.FileName}},
       
@{N="VMDK Size";E={($vm.extensiondata.layoutex.file|?{$_.name -contains $harddisk.filename.replace(".","-flat.")}).size/1GB}}       }     }   } } $VmInfo | Export-Csv -NoTypeInformation -UseCulture -Path "VmInfo.csv"


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

0 Kudos
zerotraction
Contributor
Contributor

Hi - coming a little late to the party, but I believe this is the script that I'm looking for.

I'm pretty new to scripting for PowerCLI and having issues getting this working on our infrastructure.  Getting an "Unexpected token '<' in expression or statement" error at line 10, character 72.  Seems that it doesn't like the closed square bracket.

We're running version 4.1 and I'm using PowerCLI 4.1 as well.

Any ideas?

Thanks,

--- A

0 Kudos
LucD
Leadership
Leadership

If you do not have a good reason to stick with PowerCLI 4.1, I would in any case advise an upgrade.

Let's first check if the copy/paste didn't introduce an error.

Try the attached script.

And copy the complete error message, should it still appear.


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

0 Kudos
zerotraction
Contributor
Contributor

Thanks for the help -

When running the attached script, I get another error "Export-CSV : Cannot bind argument to parameter 'InputObject' because it is null." at Line 18, Character 21 (which is the - in -NoTypeInformation, etc.) in the last line.

Taking your advice to upgrade to PowerCLI 5.0.1 and hoping that that makes this issue go away.

Thanks again,

--- A

0 Kudos
LucD
Leadership
Leadership

That would mean that the variable $VmInfo is empty ?

Try displaying the result on screen, remove the Export-Csv cmdlet at the end.


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

0 Kudos