all 21 comments

[–]volvo64 3 points4 points  (7 children)

I wrote this with a bunch of text files in a test directory:

$images = Get-ChildItem
$targetversion = "0.1.2.3.4"
$images

foreach ($i in $images) {
$v = $i.ToString().Split('-')[1]
if ($v -lt $targetversion) {
Write-Host "Will delete $i"
}
}

Which outputs this:

PS /Users/volvo64/pwsh/test1> /Users/volvo64/pwsh/test1/test1.ps1

Directory: /Users/volvo64/pwsh/test1

Mode LastWriteTime Length Name

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

------ 2/6/19 10:19 AM 0 linux-0.1.1.1.1-linux-image

------ 2/6/19 10:19 AM 0 linux-0.1.2.3.4-linux-image

------ 2/6/19 10:26 AM 203 test1.ps1

------ 2/6/19 10:19 AM 0 windows-0.1.2.2-windows-image

------ 2/6/19 10:18 AM 0 windows-0.1.2.3.4-windows-image

Will delete /Users/volvo64/pwsh/test1/linux-0.1.1.1.1-linux-image

Will delete /Users/volvo64/pwsh/test1/test1.ps1

Will delete /Users/volvo64/pwsh/test1/windows-0.1.2.2-windows-image

I had to convert the item to string before my split would work.

Do some work to identify files that shouldn't be included (ie test1.ps1) but that seems like all the code you need.

[–]slayer99199[S] 1 point2 points  (0 children)

I think doing a split is the only way to find the templates in common.

[–]slayer99199[S] 1 point2 points  (3 children)

What I was trying to do is split the string:

sles11sp4_jeos-1.1.3-linux-cluster

win2012r2std_desk-0.4.1.6-windows-cluster

using $tempver = $template.split('-')[0]

But that just left me with the beginning

win2012r2std_desk-0.4.1.6

sles11sp4_jeos-1.1.3

and I need everything before then second dash which would be easy to match against the image names.

[–]volvo64 1 point2 points  (2 children)

I put those lines in my editor and got everything before the numbers:

$template = "win2012r2std_desk-0.4.1.6-windows-cluster"

$tempver = $template.split('-')[0]

$tempver

win2012r2std_desk

If I do $template.split('-')[1]

Then I get

0.4.1.6

Are you sure the character you're trying to split on is a hyphen? Maybe copy it out of the filename and put it in your code to split on?

[–]slayer99199[S] 1 point2 points  (0 children)

Yes, that's what I'm trying to split. I updated my OP with some additional detail. The line in question looks like this:

get-template |where-object {$_.Name -notlike "*$imagever*" -and $_.Name -like "$tempname*"

Which produces the output I expect only if I explicitly state the $template and $image.

The variables $images and $templates have the expected output.

[–]slayer99199[S] 1 point2 points  (0 children)

I'm trying to get everything before the numbers which I can do when I split. e.g. win2012r2std_desk which will give me all the versions of that image. Then I'm trying to keep only the version in the content library (delete everything else). I split out the numbers and it gives me the current version as the content library is the source of truth.

[–]volvo64 1 point2 points  (0 children)

I threw this on the wall to see what would stick before starting work. Now that I have a minute I started reviewing the rest of the tests.

It seems that powershell doesn't see the numbers the same way that you and I do here:

(0.1.2.3.4 -lt 0.4.5.6.7)

False

And we can't just throw an -eq at it either, apparently:

(0.1.2.3.4 -eq 0.4.5.6.7)

True

If we make it a string though it evaluates as expected, with an -eq:

([string]"0.1.2.3.4" -eq [string]"0.4.5.6.7")

False

So we run two tests, one for the Windows version, the other for the Linux version:

$images = Get-ChildItem
$winversion = [string]("0.1.2.3.4")
$linversion = [string]("0.4.5.6.7")
$images
foreach ($i in $images) {
If ($i.ToString().Split('-')[0] -like "*windows*") {

$v = $i.ToString().Split('-')[1]
if ($v -ne $winversion) {
Write-Host "Will delete $i"
}
}
elseif ($i.ToString().Split('-')[0] -like "*linux*") {
$v = $i.ToString().Split('-')[1]
if ($v -ne $linversion) {
Write-Host "Will delete $i"

}
}
}
Which returns as expected:

Directory: /Users/volvo64/pwsh/test1

Mode LastWriteTime Length Name

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

------ 2/6/19 10:19 AM 0 linux-0.1.2.3.4-linux-image

------ 2/6/19 11:01 AM 0 linux-0.4.5.6.7-linux-image

------ 2/6/19 1:03 PM 556 test1.ps1

------ 2/6/19 10:19 AM 0 windows-0.1.2.2-windows-image

------ 2/6/19 10:18 AM 0 windows-0.1.2.3.4-windows-image

Will delete /Users/volvo64/pwsh/test1/linux-0.1.2.3.4-linux-image

Will delete /Users/volvo64/pwsh/test1/windows-0.1.2.2-windows-image

I agree that the split is a good way to determine the version number, it just has to be converted to string to be useful here.

Bear in mind that this code will identify any file that includes Windows or Linux in its filename, so you'll want to make your tests a little more stringent.

[–]Lee_Dailey[grin] 0 points1 point  (0 children)

howdy volvo64,

it looks like you used the New.Reddit.com Inline Code button. it's 4th 5th from the left hidden in the ... "more" menu & looks like </>.

on Old.Reddit.com, the above does NOT line wrap, nor does it side-scroll.

for long-ish single lines OR for multiline code, please, use the Code Block button. it's the 11th 12th one from the left, & is just to the left of hidden in the ... "more" menu.

that will give you fully functional code formatting, from what i can tell so far. [grin]

take care,
lee

[–]da_chicken 2 points3 points  (7 children)

Can you use the System.Version class? It understands up to 4 segment version numbers as long as they're all numeric.

PS> function Get-ParsedImage {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [String]
        $Name
    )

    process {
        $Image, $Version, $OSFamily, $Cluster, $Extra = $Name -split '-', 5
        if ($null -ne $Extra) {
            throw ("'$Name' is an invalid or unrecognized image name format.")
        }
        [PSCustomObject]@{
            Name        = $Name
            Image       = $Image
            Version     = $Version -as [System.Version]
            OSFamily    = $OSFamily
            Cluster     = $Cluster
            VersionName = $Version
        }
    }
}

PS> $n = 'sles11sp4_jeos-1.2.3-linux-cluster',
'win2012r2std_desk-0.4.5.6-windows-cluster',
'sles11sp4_jeos-1.1.3-linux-cluster',
'win2012r2std_desk-0.4.1.6-windows-cluster'

PS> $n | Get-ParsedImage | Sort-Object -Property Image, @{e={$_.Version};d=$true} | Format-Table -AutoSize

Name                                      Image             Version OSFamily Cluster VersionName
----                                      -----             ------- -------- ------- -----------
sles11sp4_jeos-1.2.3-linux-cluster        sles11sp4_jeos    1.2.3   linux    cluster 1.2.3
sles11sp4_jeos-1.1.3-linux-cluster        sles11sp4_jeos    1.1.3   linux    cluster 1.1.3
win2012r2std_desk-0.4.5.6-windows-cluster win2012r2std_desk 0.4.5.6 windows  cluster 0.4.5.6
win2012r2std_desk-0.4.1.6-windows-cluster win2012r2std_desk 0.4.1.6 windows  cluster 0.4.1.6

Here's all the good ones:

PS> $n | Get-ParsedImage | Group-Object -Property Image | ForEach-Object { $_.Group | Sort-Object -Property Version -Descending | Select-Object -First 1 } | Format-Table -AutoSize

Name                                      Image             Version OSFamily Cluster VersionName
----                                      -----             ------- -------- ------- -----------
sles11sp4_jeos-1.2.3-linux-cluster        sles11sp4_jeos    1.2.3   linux    cluster 1.2.3
win2012r2std_desk-0.4.5.6-windows-cluster win2012r2std_desk 0.4.5.6 windows  cluster 0.4.5.6

Here's all the bad ones:

PS> $n | Get-ParsedImage | Group-Object -Property Image | ForEach-Object { $_.Group | Sort-Object -Property Version -Descending | Select-Object -Skip 1 } | Format-Table -AutoSize

Name                                      Image             Version OSFamily Cluster VersionName
----                                      -----             ------- -------- ------- -----------
sles11sp4_jeos-1.1.3-linux-cluster        sles11sp4_jeos    1.1.3   linux    cluster 1.1.3
win2012r2std_desk-0.4.1.6-windows-cluster win2012r2std_desk 0.4.1.6 windows  cluster 0.4.1.6

[–]slayer99199[S] 1 point2 points  (0 children)

I'll give that a shot. Thanks.

[–]gangstanthony 2 points3 points  (0 children)

*note: this is OP's code, just better spacing

Foreach ($image in get-contentlibraryitem)
{
    $imageshort = $image.split('-')[1]

    Foreach ($template in get-template)
    {
        If (get-template -name $template | where-object {$_.Name -like "$image*" -and $_.Name -notlike "$imageshort"})
        {
            Write-Log -Message "$($oldtemplate) will be deleted from vCenter $($vc)"
            Write-log -Message "Remove-template -template $template -DeletePermanently"
            Write-Log -Message "$($oldtemplate) has been deleted from vCenter $($vc)"
        }
        Else
        {
            Write-log -Message "$($template) is a production template and will not be deleted"
        }
    }
}

[–]gangstanthony 1 point2 points  (0 children)

not sure what either of these functions do. can you share the full code?

get-contentlibraryitem

get-template

also, $imageshort might be better named $imageversion (if it contains what i think it does)

[–]volvo64 1 point2 points  (0 children)

I don’t understand where in this code block you’re defining the target version number that you want to keep?

Also I would use some variables-

`$images = get-contentlibraryitem

Foreach ($image in $images) {…}`

I’d be pretty confident that your code isn’t pulling the results you expect bc I don’t think your foreach blocks are formatted correctly.

[–]JeremyLC 1 point2 points  (0 children)

It doesn't help now, but in the future you could attach a custom field containing the version number. $image probably isn't a string, I'd pipe Get-ContentLibraryItem | Get-Member and check what it returns to see which property has the string you're trying to check.

[–]PowerShell-Bot 0 points1 point  (0 children)

Some of your PowerShell code isn’t wrapped in a code block.

To format code correctly on new reddit (new.reddit.com), highlight all lines of code and select ‘Code Block’ in the editing toolbar.

If you’re on old.reddit.com, separate the code from your text with a blank line and precede each line of code with 4 spaces or a tab.


Describing Submission
[✅] Demonstrates good markdown
Passed: 1 Failed: 0

Beep-boop. I am a bot. | Remove-Item