VMware Cloud Community
DZ1
Hot Shot
Hot Shot

VM sorting with a very small twist

I want to sort some VMs names, but only after a certain point.  If I have some names that are like:

XX01VM04

XX02VM02

XX03VM44

Sort-Object will sort by the begining characters, so the XX01, XX02 and so no.  I only want to sort the numbers after the "VM", so "XX02VM02" would actually be first, "XX01VM04" would be second, and so on.

Of course I thought about a regular expression, but I'm not a regex guru. 

I thought that it may be something like below, I know the caret is used to get the beggining of a line, I was just hoping that I'm at least on the right track. 

Get-folder "Test" | Get-VM | sort -Property @{ E={ ($_.Name).StartWith("^vm") } } -Descending

I thought matching the end would work like this:  Get-folder "Test" | Get-VM | sort -Property @{ E={ ($_.Name).EndsWith("vm*$") } } -Descending

0 Kudos
5 Replies
LucD
Leadership
Leadership

Try something like this

$mask = [regex]"\w*VM(\d*)" 
Get-VM |
Sort-Object -Property {$mask.Match($_.Name).Groups[1].Value}


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

0 Kudos
Grzesiekk
Expert
Expert

Hello,

Like LucD wrote, regex is the answer to problems like this. But in case you don't want to do regex, and the names have the same pattern you can still try to do this.

"xx01vm04","xx03vm44","xx01vm11","xx06vm01"|sort @{Expression={$_.substring(4)} }
xx06vm01
xx01vm04
xx01vm11
xx03vm44

sorted by vmXX pattern not XXnumber. But again that's silly to use substring Smiley Wink if you can do regex

heh.... take a look at this Smiley Wink

"xx01vm04","xx03vm44","xx01vm11","xx06vm01"| sort @{Expression= { $_.Substring( ($( $i=0; $_.getEnumerator()| % {$i++;if ($_ -eq "v"){$i} } )) -1) } }
xx06vm01
xx01vm04
xx01vm11
xx03vm44


"asxx01vm04","ADF3fxx03vm44","OOOOOzzAxx01vm11","xx06vm01"| sort @{Expression= { $_.Substring( ($( $i=0; $_.getEnumerator()| % {$i++;if ($_ -eq "v"){$i} } )) -1) } }


xx06vm01
asxx01vm04
OOOOOzzAxx01vm11
ADF3fxx03vm44

This approach detects where is letter V in your pattern and does -1 from that location and runs substring from that position Smiley Wink

BUT STILL Smiley Happy i would go with regex here

Regards,

GReg

--- @blog https://grzegorzkulikowski.info
0 Kudos
DZ1
Hot Shot
Hot Shot

Thanks for the responses, I have tried what you wrote Luc, but it's not filtering like I expect it to.  Thanks for the help, other tasks are taking up my time, so I have not been able to devote too much time on this.  For my own knowlege, I have been going through the regular expressions help information, so I will play with it some more.  I have not been able to try what Grzesiekk wrote either, but I will.  Thanks. 

0 Kudos
will47
Contributor
Contributor

Along the lines of what Grzesiekk suggested, if the names are not of fixed length,  I think something like this would work to sort based on the last two numeric digits:

PowerShell> cat .\test.txt

asdf04vm15

lah01vm09

hereherevm15

therevm17

blahblah06vm01


PowerShell> Get-Content .\test.txt | Sort-Object @{Expression={$_.Substring($_.length-2,2)}}

blahblah06vm01

lah01vm09

asdf04vm15

hereherevm15

therevm17

I would argue that it's much better to avoid using regex when the overhead is not necessary - I think that using Substring() should be more efficient, assuming it works for your purposes. Of course, if you have some 1 or 3 digit numbers, or some kind of other things to account for, it may not be an option.

0 Kudos
LucD
Leadership
Leadership

When you find the time to do some further tests, let me know what doesn't work.

In my tests it seemed to sort correctly.

Perhaps the VM names are not all interpreted correctly ?

Could you give me a sample of names for which it doesn't work ?


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

0 Kudos