VMware Cloud Community
max2001
Contributor
Contributor
Jump to solution

Comparing objects - and VMproperty value as a result.

Hi Guys,

I need to create a new VMproperty that will have a value of either a "Yes" or "No".

The Value will be based on the "datastore name" of each VMDK of the VM and the storage datastorename

for example:

$a = get-vm vmname | Get-HardDisk | select filename

$a

as follows:

[datastore1] vmfolder/vmname.vmdk

[datastore2] vmfolder/vmname-1.mdk

all the [datastores] in $a need to be compared to a different list that we have stored in a text file on c:\list.txt which has the name of the datastore at the storage level:

$b = rdfile c:\list.txt

$b

as follows:

storage1:datastore1

storage2:datastore2

basically if there is a match between what is in [ ] in $a for the datastore to what is after the colon on $b, the new vm-property will have a value of yes.

1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

You didn't say how you would populate that $H, but I simulated something with a here-string

Try like this

$H = @"
Source
------
datastre1:name1
datastore1:name2
datastore1name3
"@


$lookupTab = @{}
$H | where {$_ -match ':'} | %{
 
$value,$key = $_.Split(':')
 
$lookupTab.Add($key,$value)
}

Get-VM vmname | Get-HardDisk |
Select FileName,@{N="Flag";E={
 
$dsName = $_.FileName.Split(']')[0].TrimStart('[')
 
if($lookupTab.ContainsKey($dsName)){"Yes"}else{"No"}
}}

Not a lot changes, the script only looks at lines that have a semi-column in there


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

View solution in original post

Reply
0 Kudos
19 Replies
LucD
Leadership
Leadership
Jump to solution

Try something like this

$lookupTab = @{}
Get-Content c:\list.txt | %{
 
$value,$key = $_.Split(':')
 
$lookupTab.Add($key,$value)
}

Get-VM vmname | Get-HardDisk |
Select FileName,@{N="Flag";E={
 
$dsName = $_.FileName.Split(']')[0].TrimStart('[')
 
if($lookupTab.ContainsKey($dsName)){"Yes"}else{"No"}
}}

It uses a hash table to store the entries from the file.

Then it extracts the datastorename, and checks if that datastorename is in the hash table.


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

max2001
Contributor
Contributor
Jump to solution

Hi LucD,

I am getting an error as follows

C:\> $lookupTab = @{}

C:\> Get-Content c:\list.txt | %{

>>   $key,$value = $_.Split(':')

>>   $lookupTab.Add($key,$value)

>> }

>>

Exception calling "Add" with "2" argument(s): "Item has already been added. Key in dictionary: 'storage1'  Key being added: 'storage1'"

At line:3 char:17

+   $lookupTab.Add <<<< ($key,$value)

    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

    + FullyQualifiedErrorId : DotNetMethodException

Exception calling "Add" with "2" argument(s): "Item has already been added. Key in dictionary: 'storage1'  Key being added: 'storage1'"

At line:3 char:17

+   $lookupTab.Add <<<< ($key,$value)

    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

    + FullyQualifiedErrorId : DotNetMethodException

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

It looks as if you have rows in the TXT file that start with the same value (for example multiple lines that start with 'storage1').

Is that the case ?


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

max2001
Contributor
Contributor
Jump to solution

Hi LucD,

yes that is correct, several lines start with 'Storage1'

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

I changed the order of $key - $value in the script above.

Try it like that


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

max2001
Contributor
Contributor
Jump to solution

Thanks,

The variable $lookupTab is now doing the splitting correctly with no errors, only problem is that i still don't get "yes" or "no" as a result of the script above, it returns the vmdk path in the datastore

\

example

[datastore1] vmfolder/vmname.vmdk



the above is what comes back

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

For each HD there should be 2 properties returned: Filename, Flag

Under the Flag property there should be a Yes/No value


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

max2001
Contributor
Contributor
Jump to solution

you are right i did not notice it because it was too far to the right!...

OK, my last question, how can I get this to work as a new-viproperty for a VM object that will give me a "yes" value if AT LEAST one hard disk has a YES flag and NO in none had a Yes flag.

as follows:

New-VIProperty -ObjectType VirtualMachine -Name nameofproperty -Value {scrip??}

this is exactly what i am trying to achieve!

Appreciate your help!

Reply
0 Kudos
max2001
Contributor
Contributor
Jump to solution

Hi LucD,

I have just noticed that the script above always returns a "No" under the flag, even if $dsname matches $_.FileName.Split(']')[0].TrimStart('[')

any idea why this is happening? ran it several times and it keeps returning a NO.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

I changed the ContainsValue method with the ContainsKey method in the script above.

Can you try like that ?


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

Reply
0 Kudos
max2001
Contributor
Contributor
Jump to solution

Thanks,

still the same, returns a NO

Filename                                                                                                                                              Flag

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

[datastore1] vm/vm.vmdk                                                                                                                    No

although "datastore1 is listen in c:\list.txt

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Does $dsName have the correct datastorename ?

Can you check by displaying that variable in the loop ?

Does the hash table contains the key ?

Do a $lookupTab.GetEnumerator() to diplay the contents of the hash table.


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

Reply
0 Kudos
max2001
Contributor
Contributor
Jump to solution

Does $dsName have the correct datastorename ? Can you check by displaying that variable in the loop ?

$dsName returns nothing when i run it

Does the hash table contains the key ?

see below

Do a $lookupTab.GetEnumerator() to diplay the contents of the hash table.

when I run $lookupTab or $lookupTab.GetEnumerator() , they return the following

Name                           Value

----                           -----

datastore1                   ... storage1

datastore2                ... storage1

datastore3                 ... storage1

datastore4                ... storage1

datastore5                 ... storage1

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Do you have the datastore when you do

Get-VM vmname | Get-HardDisk |

Select FileName,@{N="DS";E={$_.FileName.Split(']')[0].TrimStart('[')}}


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

Reply
0 Kudos
max2001
Contributor
Contributor
Jump to solution

yes it returns it correctly under the DS column

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

That seems to indicate that the comparison doesn't return $true.

Could there be some blanks in your text file at the end of some lines line ?


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

Reply
0 Kudos
max2001
Contributor
Contributor
Jump to solution

yes that actually turned out to be the case!

the initial export of the variable to list.txt created spaces, as soon as i manually removed the spaces it fixes the problem.

would you be able to tell me how the script would change if i use a variable $H rather than list.txt

only difference is the variable will have a line at the top as follows:

Source

------

datastre1:name1

datastore1:name2

datastore1name3

Appreciate your help

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You didn't say how you would populate that $H, but I simulated something with a here-string

Try like this

$H = @"
Source
------
datastre1:name1
datastore1:name2
datastore1name3
"@


$lookupTab = @{}
$H | where {$_ -match ':'} | %{
 
$value,$key = $_.Split(':')
 
$lookupTab.Add($key,$value)
}

Get-VM vmname | Get-HardDisk |
Select FileName,@{N="Flag";E={
 
$dsName = $_.FileName.Split(']')[0].TrimStart('[')
 
if($lookupTab.ContainsKey($dsName)){"Yes"}else{"No"}
}}

Not a lot changes, the script only looks at lines that have a semi-column in there


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

Reply
0 Kudos
max2001
Contributor
Contributor
Jump to solution

working perfectly fine! thanks for your help.

Reply
0 Kudos