Public/Remove-AnyStackOldTemplates.ps1
|
function Remove-AnyStackOldTemplates { <# .SYNOPSIS Removes old VM templates. .DESCRIPTION Finds and deletes templates not modified in AgeDays. .PARAMETER Server vCenter Server hostname or VIServer object. Uses active connection if omitted. .PARAMETER AgeDays Age threshold in days (default 180). .EXAMPLE PS> Remove-AnyStackOldTemplates .OUTPUTS PSCustomObject .NOTES Author: The AnyStack Architect Requires: VCF.PowerCLI 9.0+, vSphere 8.0 U3+ #> [CmdletBinding(SupportsShouldProcess=$true)] [OutputType([PSCustomObject])] param( [Parameter(Mandatory=$false, ValueFromPipeline=$true)] [ValidateNotNull()] $Server, [Parameter(Mandatory=$false)] [int]$AgeDays = 180 ) begin { $vi = Get-AnyStackConnection -Server $Server $ErrorActionPreference = 'Stop' } process { try { Write-Verbose "[$($MyInvocation.MyCommand.Name)] Finding old templates on $($vi.Name)" $templates = Invoke-AnyStackWithRetry -ScriptBlock { Get-View -Server $vi -ViewType VirtualMachine -Property Name,Config.Modified,Summary.Storage.Committed -Filter @{'Config.Template'='True'} } $threshold = (Get-Date).AddDays(-$AgeDays) foreach ($t in $templates) { if ($t.Config.Modified -lt $threshold) { if ($PSCmdlet.ShouldProcess($t.Name, "Delete Old Template")) { Invoke-AnyStackWithRetry -ScriptBlock { $t.Destroy_Task() } [PSCustomObject]@{ PSTypeName = 'AnyStack.RemovedTemplate' Timestamp = (Get-Date) Server = $vi.Name TemplateName = $t.Name LastModified = $t.Config.Modified SizeGB = [Math]::Round($t.Summary.Storage.Committed / 1GB, 2) Removed = $true } } } } } catch { $PSCmdlet.ThrowTerminatingError([System.Management.Automation.ErrorRecord]::new(function Remove-AnyStackOldTemplates { <# .SYNOPSIS Removes old VM templates. .DESCRIPTION Finds and deletes templates not modified in AgeDays. .PARAMETER Server vCenter Server hostname or VIServer object. Uses active connection if omitted. .PARAMETER AgeDays Age threshold in days (default 180). .EXAMPLE PS> Remove-AnyStackOldTemplates .OUTPUTS PSCustomObject .NOTES Author: The AnyStack Architect Requires: VCF.PowerCLI 9.0+, vSphere 8.0 U3+ #> [CmdletBinding(SupportsShouldProcess=$true)] [OutputType([PSCustomObject])] param( [Parameter(Mandatory=$false, ValueFromPipeline=$true)] [ValidateNotNull()] $Server, [Parameter(Mandatory=$false)] [int]$AgeDays = 180 ) begin { $vi = Get-AnyStackConnection -Server $Server $ErrorActionPreference = 'Stop' } process { try { Write-Verbose "[$($MyInvocation.MyCommand.Name)] Finding old templates on $($vi.Name)" $templates = Invoke-AnyStackWithRetry -ScriptBlock { Get-View -Server $vi -ViewType VirtualMachine -Property Name,Config.Modified,Summary.Storage.Committed -Filter @{'Config.Template'='True'} } $threshold = (Get-Date).AddDays(-$AgeDays) foreach ($t in $templates) { if ($t.Config.Modified -lt $threshold) { if ($PSCmdlet.ShouldProcess($t.Name, "Delete Old Template")) { Invoke-AnyStackWithRetry -ScriptBlock { $t.Destroy_Task() } [PSCustomObject]@{ PSTypeName = 'AnyStack.RemovedTemplate' Timestamp = (Get-Date) Server = $vi.Name TemplateName = $t.Name LastModified = $t.Config.Modified SizeGB = [Math]::Round($t.Summary.Storage.Committed / 1GB, 2) Removed = $true } } } } } catch { $PSCmdlet.ThrowTerminatingError([System.Management.Automation.ErrorRecord]::new(function Remove-AnyStackOldTemplates { <# .SYNOPSIS Removes old VM templates. .DESCRIPTION Finds and deletes templates not modified in AgeDays. .PARAMETER Server vCenter Server hostname or VIServer object. Uses active connection if omitted. .PARAMETER AgeDays Age threshold in days (default 180). .EXAMPLE PS> Remove-AnyStackOldTemplates .OUTPUTS PSCustomObject .NOTES Author: The AnyStack Architect Requires: VCF.PowerCLI 9.0+, vSphere 8.0 U3+ #> [CmdletBinding(SupportsShouldProcess=$true)] [OutputType([PSCustomObject])] param( [Parameter(Mandatory=$false, ValueFromPipeline=$true)] [ValidateNotNull()] $Server, [Parameter(Mandatory=$false)] [int]$AgeDays = 180 ) begin { $vi = Get-AnyStackConnection -Server $Server $ErrorActionPreference = 'Stop' } process { try { Write-Verbose "[$($MyInvocation.MyCommand.Name)] Finding old templates on $($vi.Name)" $templates = Invoke-AnyStackWithRetry -ScriptBlock { Get-View -Server $vi -ViewType VirtualMachine -Property Name,Config.Modified,Summary.Storage.Committed -Filter @{'Config.Template'='True'} } $threshold = (Get-Date).AddDays(-$AgeDays) foreach ($t in $templates) { if ($t.Config.Modified -lt $threshold) { if ($PSCmdlet.ShouldProcess($t.Name, "Delete Old Template")) { Invoke-AnyStackWithRetry -ScriptBlock { $t.Destroy_Task() } [PSCustomObject]@{ PSTypeName = 'AnyStack.RemovedTemplate' Timestamp = (Get-Date) Server = $vi.Name TemplateName = $t.Name LastModified = $t.Config.Modified SizeGB = [Math]::Round($t.Summary.Storage.Committed / 1GB, 2) Removed = $true } } } } } catch { $PSCmdlet.ThrowTerminatingError([System.Management.Automation.ErrorRecord]::new(function Remove-AnyStackOldTemplates { <# .SYNOPSIS Removes old VM templates. .DESCRIPTION Finds and deletes templates not modified in AgeDays. .PARAMETER Server vCenter Server hostname or VIServer object. Uses active connection if omitted. .PARAMETER AgeDays Age threshold in days (default 180). .EXAMPLE PS> Remove-AnyStackOldTemplates .OUTPUTS PSCustomObject .NOTES Author: The AnyStack Architect Requires: VCF.PowerCLI 9.0+, vSphere 8.0 U3+ #> [CmdletBinding(SupportsShouldProcess=$true)] [OutputType([PSCustomObject])] param( [Parameter(Mandatory=$false, ValueFromPipeline=$true)] [ValidateNotNull()] $Server, [Parameter(Mandatory=$false)] [int]$AgeDays = 180 ) begin { $vi = Get-AnyStackConnection -Server $Server $ErrorActionPreference = 'Stop' } process { try { Write-Verbose "[$($MyInvocation.MyCommand.Name)] Finding old templates on $($vi.Name)" $templates = Invoke-AnyStackWithRetry -ScriptBlock { Get-View -Server $vi -ViewType VirtualMachine -Property Name,Config.Modified,Summary.Storage.Committed -Filter @{'Config.Template'='True'} } $threshold = (Get-Date).AddDays(-$AgeDays) foreach ($t in $templates) { if ($t.Config.Modified -lt $threshold) { if ($PSCmdlet.ShouldProcess($t.Name, "Delete Old Template")) { Invoke-AnyStackWithRetry -ScriptBlock { $t.Destroy_Task() } [PSCustomObject]@{ PSTypeName = 'AnyStack.RemovedTemplate' Timestamp = (Get-Date) Server = $vi.Name TemplateName = $t.Name LastModified = $t.Config.Modified SizeGB = [Math]::Round($t.Summary.Storage.Committed / 1GB, 2) Removed = $true } } } } } catch { $PSCmdlet.ThrowTerminatingError([System.Management.Automation.ErrorRecord]::new($_, 'UnexpectedError', [System.Management.Automation.ErrorCategory]::NotSpecified, $null)) } } } .Exception, 'UnexpectedError', [System.Management.Automation.ErrorCategory]::NotSpecified, $null)) } } } .Exception, 'UnexpectedError', [System.Management.Automation.ErrorCategory]::NotSpecified, $null)) } } } .Exception, 'UnexpectedError', [System.Management.Automation.ErrorCategory]::NotSpecified, $null)) } } } |