Hi everyone
I am in the process of developing a script to cleanup after our backup software.
One of the tasks will be to find snapshots of a certain name and remove them. This is pretty straight forward.
However, since we have several vCenters linked and since, when a backup job dies, there can be quite a number of of snapshots to work through AND people sometimes don't notice for a few days that something was amiss, I would like to optimise this in a few key aspects:
When a vm has nothing but backup snaps to be deleted, I would like to tell it to delete them all at once, which should be way easier than doing one at a time.
To do that, I need to check all snapshots per vm and group the vms and or their snapshots into either the "delete all" category or the "delete individually" category.
I would like to use views to drill down the data and only work with objects when it is clear what has to be done where. For this I need a way to find all snapshots of a certain vm. I have no trouble finding all vms with snapshots but I have so far only found a way to find the active snapshot and the root snapshot.
I can of course traverse the snapshot chains in code but I find this rather inelegant...
So in short: Is there a quick way in get-view to find all snapshots belonging to a vm? Or is there a much easier way to do what I want in the first place?
Regards,
Marco
Ok, that requires a few more lines of code.
Try like this
param(
[VMware.Vim.VirtualMachineSnapshotTree]$Snapshot
)
process{
$snapshot.Name
if($Snapshot.ChildSnapshotList.Count -gt 0){
$Snapshot.ChildSnapshotList | %{
Get-SnapChild -Snapshot $_
}
}
}
}
foreach($vm in Get-View -ViewType VirtualMachine -Property Name,Snapshot -Filter @{'Snapshot' = ''}){
$vm.Snapshot.RootSnapshotList | %{
Get-SnapChild -Snapshot $_ | Select @{N='VM';E={$vm.name}},@{N='Snapshot';E={$_}}
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
The fastest way to find VMs with snapshot is something like this
select Name
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD
That gives me a list of all the vms that have snapshots.
I need to have a list of all the snapshots for each of the vms returned.
Regards,
Marco
Ok, that requires a few more lines of code.
Try like this
param(
[VMware.Vim.VirtualMachineSnapshotTree]$Snapshot
)
process{
$snapshot.Name
if($Snapshot.ChildSnapshotList.Count -gt 0){
$Snapshot.ChildSnapshotList | %{
Get-SnapChild -Snapshot $_
}
}
}
}
foreach($vm in Get-View -ViewType VirtualMachine -Property Name,Snapshot -Filter @{'Snapshot' = ''}){
$vm.Snapshot.RootSnapshotList | %{
Get-SnapChild -Snapshot $_ | Select @{N='VM';E={$vm.name}},@{N='Snapshot';E={$_}}
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thank you, this works. I have no idea why it works but that's more due to my being a novice when it comes to coding and powershell in particular :smileygrin:.
I'll be staring at this code in total incomprehension some more now.
Lol!
To minimise the staring, some annotations:
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I may now understand your code. If you have the time I'd live for you to verify this:
Am I correct in assuming that the process block is more good coding style than strictly necessary?
Anyway as far as I can tell, you take the rootsnapshotlist which has an attribute childsnapshotlist (THIS is exactly the piece of linking information I was unable to find so far) and if it has more than 0 entries you traverse through those snapshots by calling your function inside itself.
The function then returns everything it has found through the first line after process{ and all you have to do is clean the output up a bit through the select statement.
Am I understanding this somewhat correctly?
And thanks again for the help.
Oh, you were faster than I was
Thanks, I believe I've got it!
You're an invaluable source of info... but I'm sure I'm not telling you anything new.
Correct, the function could be done without the Process block
Strictly speaking Begin-Process-End blocks are when objects are passed over the pipeline to the function.
The function just returns the names of all the snapshots it finds.
The Select is to combine that info with the VM name.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Like this.
For the user that created the snapshot, you will have to search the events.
See for example Re: snapshot who created it
{
param(
[VMware.Vim.VirtualMachineSnapshotTree]$Snapshot
)
process
{
$snapshot | Select Name, Description, CreateTime
if ($Snapshot.ChildSnapshotList.Count -gt 0)
{
$Snapshot.ChildSnapshotList | % {
Get-SnapChild -Snapshot $_
}
}
}
}
foreach ($vm in Get-View -ViewType VirtualMachine -Property Name, Snapshot -Filter @{'Snapshot' = '' })
{
$vm.Snapshot.RootSnapshotList | % {
Get-SnapChild -Snapshot $_ |
Select @{N = 'VM'; E = { $vm.name } },
@{N = 'Snapshot'; E = { $_.Name } },
@{N = 'Description'; E = { $_.Description } },
@{N = 'CReated'; E = { $_.CreateTime } }
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yes, set the execution policy, by a command in for example a profile for All Usersa
Set-ExecutionPolicy -ExecutionPolicy AllSigned
Or do it in a GPO.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hello,
regarding this script, I have 4 points that I request a help:
1/ How can I catch the creator/author of the snapshot with this script?
I try this but without success:
@{N = 'Creator'; E= {
$event = Get-VIEvent | where {$_ -is [VMware.Vim.TaskEvent] -and $_.Info.descriptionId -eq "VirtualMachine.createSnapshot"} | Select Username
$event.Info.Reason.userName} }
2/ I have a difference with the time of 1 hour between the result of this part of the script {N = 'Created'; E = { $_.CreateTime } }, it's 1 hour less if I compare with the time display in VMware web management. How can I display the correct time in the scipt result?
3/ How can I display the VMhost where the vm is located in the script result ?
4/ How can I output in CSV file?
regards