VMware Cloud Community
janlena
Contributor
Contributor

List VM,Tag and Datastores

Hi,

I need a script that export a list with the name of the VM, the tag of that VM and the  attached datastores:

VM NameTagDatastores
VMnameTagvalueDatastore1,Datastore2

I found this but I need to have the datastores as well.

$tagCat = @()

$tagTab = @{}

foreach($tag in (Get-TagAssignment)){

    $tagCat += $tag.Tag.Category.Name

    $key = $tag.Entity.Name

    if($tagTab.ContainsKey($key)){

    ` $val = $tagTab.Item($key) 

    }

    else{

        $val = @{}

    }

    $val.Add($tag.Tag.Category.Name,$tag.Tag.Name)

    $tagTab[$key] = $val

}

$tagCat = $tagCat | Sort-Object -Unique

$tags = foreach($row in ($tagTab.GetEnumerator() | Sort-Object -Property Key)){

    $obj = New-Object PSObject -Property @{

        VM = $row.Key

    }

    $tagCat | %{

        $obj | Add-Member -Name $_ -Value $row.Value[$_] -MemberType NoteProperty

    }

    $obj

}

$tags | Export-Csv tags.csv -NoTypeInformation -UseCulture

13 Replies
RAJ_RAJ
Expert
Expert

Hi,

Below is one simple command line where you can get  VM  name and DS name

Get-vmhost  | get-datastore|%{$ds=$_; $ds.Extensiondata.Vm|%{$_|select @{n='vm name';e={(Get-View -property name -Id $_.toString()).name}},@{n='ds name';e={$ds.name}}  }}

vm name                                 ds name

-------                                        -------

WIN2012R2-01                     DS-01-LOCAL

SCM-MGT-02                        DS-01-LOCAL

SCM-SQL-01                         DS-01-LOCAL

SCM-SQL-01                         DS-02-LOCAL

I will surely check for tag option and update

RAJESH RADHAKRISHNAN VCA -DCV/WM/Cloud,VCP 5 - DCV/DT/CLOUD, ,VCP6-DCV, EMCISA,EMCSA,MCTS,MCPS,BCFA https://ae.linkedin.com/in/rajesh-radhakrishnan-76269335 Mark my post as "helpful" or "correct" if I've helped resolve or answered your query!
0 Kudos
LucD
Leadership
Leadership

Try something like this

$tagCat = @()

$tagTab = @{}

foreach($tag in (Get-TagAssignment)){

    $tagCat += $tag.Tag.Category.Name

    $key = $tag.Entity.Name

    if($tagTab.ContainsKey($key)){

        $val = $tagTab.Item($key)

    }

    else{

        $val = @{}

    }

    $val.Add($tag.Tag.Category.Name,$tag.Tag.Name)

    $tagTab[$key] = $val

}

$tagCat = $tagCat | Sort-Object -Unique

$tags = foreach($row in ($tagTab.GetEnumerator() | Sort-Object -Property Key)){

    $obj = New-Object PSObject -Property @{

        VM = $row.Key

    }

    $tagCat | %{

        $obj | Add-Member -Name $_ -Value $row.Value[$_] -MemberType NoteProperty

    }

    $obj | Add-Member -Name Datstore -Value ((Get-VM -Name $row.key | Get-Datastore | select -ExpandProperty Name) -join '|') -MemberType NoteProperty

    $obj

}

$tags | Export-Csv tags.csv -NoTypeInformation -UseCulture


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

0 Kudos
janlena
Contributor
Contributor

Thanks LucD; is it also possible to add the DRS rule and group?

0 Kudos
LucD
Leadership
Leadership

Try like this.

Note that it requires the DRSRule module!

$tagCat = @()

$tagTab = @{}

foreach($tag in (Get-TagAssignment)){

    $tagCat += $tag.Tag.Category.Name

    $key = $tag.Entity.Name

    if($tagTab.ContainsKey($key)){

        $val = $tagTab.Item($key)

    }

    else{

        $val = @{}

    }

    $val.Add($tag.Tag.Category.Name,$tag.Tag.Name)

    $tagTab[$key] = $val

}

$tagCat = $tagCat | Sort-Object -Unique

$tags = foreach($row in ($tagTab.GetEnumerator() | Sort-Object -Property Key)){

    $obj = New-Object PSObject -Property @{

        VM = $row.Key

    }

    $tagCat | %{

        $obj | Add-Member -Name $_ -Value $row.Value[$_] -MemberType NoteProperty

    }

    $obj | Add-Member -Name Datstore -Value ((Get-VM -Name $row.key | Get-Datastore | select -ExpandProperty Name) -join '|') -MemberType NoteProperty

    $obj | Add-Member -Name DRSRule -Value (Get-DrsRule -VM $row.Key -Cluster (Get-Cluster -VM $row.Key)).Name -MemberType NoteProperty

    $obj | Add-Member -Name DRSGroup -Value ((Get-DrsVMGroup -Cluster (Get-CLuster -VM $row.Key) | where{$_.VM -contains $row.Key} | select -ExpandProperty Name) -join '|') -MemberType NoteProperty

    $obj

}

$tags | Export-Csv tags.csv -NoTypeInformation -UseCulture

 


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

0 Kudos
janlena
Contributor
Contributor

Thanks but it should also show the vm's that have no tag. Can you suggest?

0 Kudos
LucD
Leadership
Leadership

Try like this

$tagCat = @()

$tagTab = @{}

foreach($tag in (Get-TagAssignment)){

    $tagCat += $tag.Tag.Category.Name

    $key = $tag.Entity.Name

    if($tagTab.ContainsKey($key)){

        $val = $tagTab.Item($key)

    }

    else{

        $val = @{}

    }

    if($val.ContainsKey($tag.Tag.Category.Name)){

      $val[$tag.Tag.Category.Name] = $val[$tag.Tag.Category.Name],$tag.Tag.Name

    }

    else{

      $val.Add($tag.Tag.Category.Name,$tag.Tag.Name)

    }

    $tagTab[$key] = $val

}

$tagCat = $tagCat | Sort-Object -Unique

$report = @()

foreach($vm in Get-VM){

  $objProp = [ordered]@{

    Name = $vm.Name

    Datastore = (Get-Datastore -RelatedObject $vm | select -ExpandProperty Name) -join '|'

    DRSRule = (Get-DrsRule -VM $vm.Name -Cluster (Get-Cluster -VM $vm.Name)).Name

    DRSGroup = ((Get-DrsVMGroup -Cluster (Get-CLuster -VM $vm.Name) | where{$_.VM -contains $vm.Name} | select -ExpandProperty Name) -join '|')

  }

  if($tagTab.ContainsKey($vm.Name)){

    $tagVal = $tagTab.Item($vm.Name)

  }

  else{

    $tagVal = @{}

  }

  $tagCat | %{

    $value = ''

    if($tagVal.ContainsKey($_)){

      $value = $tagVal.Item($_) -join '|'

    }

    $objProp.Add($_,$value)

  }

  $report += New-Object PSObject -Property $objProp

}

$report | ft -AutoSize


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

janlena
Contributor
Contributor

Seems not work, no errors, no output. Still debugging...

0 Kudos
LucD
Leadership
Leadership

Did the previous version, without the datastorenames, return anything?


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

0 Kudos
janlena
Contributor
Contributor

No but not all clusters have DRS maybe because of this? It works when I leave the DRS part out.

0 Kudos
janlena
Contributor
Contributor

In fact I think it's running but really really slow. I have removed a  lot of code and came up with something like this. Just to see how it performs and even this is really slow:

foreach($vm in Get-Cluster "PROD" |Get-VM){

   Write-Host $vm.Name "|" (Get-DrsRule -VM $vm.Name -Cluster "PROD").Name "|" ((Get-DrsVMGroup -Cluster "PROD" | where{$_.VM -contains $vm.Name} | select -ExpandProperty Name))

}

0 Kudos
LucD
Leadership
Leadership

Fetching the DRS info does take some computing cycles I'm afraid.

If you run it against a somewhat bigger environment the script might run quite some time.

When I run a similar example as your last one, it takes some time, but it still returns the result within seconds.

You can win some time by not using OBN, but providing the cluster object.

Something like this. Does that run faster?

$cluster = Get-Cluster -Name Prod

foreach($vm in Get-VM -Location $cluster){ 

       Write-Host $vm.Name "|" (Get-DrsRule -VM $vm.Name -Cluster $cluster).Name "|" ((Get-DrsVMGroup -Cluster $cluster | where{$_.VM -contains $vm.Name} | select -ExpandProperty Name))  

}  


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

0 Kudos
janlena
Contributor
Contributor

it takes some cycles.

Only issue with tags on line 18

if($val.ContainsKey($tag.Tag.Category.Name))

Exception calling "ContainsKey" with "1" argument(s): "Key cannot be null.

0 Kudos
LucD
Leadership
Leadership

That looks as if there is a Tag without a TagCategory present.

Not even sure if that is possible.

You could add a condition to check that the key is not empty, but not sure if that could cause other issues.

if($tag.Tag.Category.Name -ne $null -and $val.ContainsKey($tag.Tag.Category.Name))


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

0 Kudos