VMware Cloud Community
ContractChris
Contributor
Contributor
Jump to solution

Snapshot location and "Owner"

I am pretty new to powershell and have come accross this script (below) to collect Snapshot information. What the script does not do however is give me the datastore location for each snapshot reported, or, the "Owner" of the snapshot based on the folder the VM is located in VC. Has anyone out there collected this information before? Any suggestions are most welcome. Thanks

function Generate-Report {

Write-Output ".Error {color:#FF0000;font-weight: bold;}.Title .Normal {}"

Foreach ($snapshot in $report){
Write-Output "

VC report

VM Name

Snapshot Name

Older than 24 Hours

Host

Datastore

Owner

$($snapshot.vm)

$($snapshot.name)

$($snapshot.created)

$($snapshot.host)

"

}
Write-Output "

"

}

$username = '######'

$password = '#######'

$ServerList = "########"

*$Report = @()

foreach ($server in $serverlist){

if ($server -eq "VCServer"){Connect-VIServer $server}

else {Connect-VIServer $server -user $username -password $password}

get-vm | get-snapshot | %{

$Snap = {} | Select VM,Name,Created,Host

$Snap.VM = $_.vm.name

$Snap.Name = $_.name

$Snap.Created = $_.created -lt (Get-Date).AddDays(-20)

$Snap.Host = $_.vm.host.name

$Report += $Snap

}

}

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

The Connect-VIServer is called within the loop that runs through all the servers in $ServerList.

In the script below I moved the Connect-VIServer outside the loop when it concerns the "VCServer".

There was a table-row statement missing at the start of the line where the snapshot data is written.

function Generate-Report {
	Write-Output "<html><head><title></title><style type=""text/css"">.Error {color:#FF0000;font-weight: bold;}.Title {background: #0011D2;color: #FFFFFF;text-align:center;font-weight: bold;}.Normal {}</style></head><body><table>"
	Write-Output "<tr class=""Title""><td colspan=""7"">VC report</td></tr><tr class="Title"><td>VM Name </td><td>Snapshot Name </td><td>Older than 24 Hours </td><td>Host </td><td>Datastore </td><td>Owner </td></tr>"
	foreach ($snapshot in $report){
		Write-Output "<tr><td>$($snapshot.vm)</td><td>$($snapshot.name)</td><td>$($snapshot.created)</td><td>$($snapshot.host)</td><td>$($snapshot.DSdir)</td></tr>"
	}
	Write-Output "</table></body></html>"
}

$username = '######'
$password = '#######'
$ServerList = "########"
$Report = @()

if ($server -eq "VCServer"){Connect-VIServer $server}
foreach ($server in $serverlist){
	if ($server -ne "VCServer") {Connect-VIServer $server -user $username -password $password}
	get-vm | get-snapshot | % {
		$Snap = {} | Select VM,Name,Created,Host, DSdir
		$Snap.VM = $_.vm.name
		$Snap.Name = $_.name
		$Snap.Created = $_.created -lt (Get-Date).AddDays(-20)
		$Snap.Host = $_.vm.host.name
		$vm = Get-View -Id $_.VM.Id
		foreach($snaptree in $vm.Snapshot.RootSnapshotList){
		  if($snaptree.Name -eq $_.Name){
		    $sn = Get-View $snaptree.Snapshot
			$Snap.DSdir = $sn.Config.Files.SnapshotDirectory
		  }
		}
		$Report += $Snap
	}
}
Generate-Report > "C:\Temp\test.htm"


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

View solution in original post

0 Kudos
17 Replies
LucD
Leadership
Leadership
Jump to solution

This gives you the datastore + directory where each snapshot is located.

Is the directory what you meant by owner ?

function Generate-Report {
	Write-Output "<html><head><title></title><style type=""text/css"">.Error {color:#FF0000;font-weight: bold;}.Title {background: #0011D2;color: #FFFFFF;text-align:center;font-weight: bold;}.Normal {}</style></head><body><table><tr class=""Title""><td colspan=""7"">VC report</td></tr><tr class="Title"><td>VM Name </td><td>Snapshot Name </td><td>Older than 24 Hours </td><td>Host </td><td>Datastore </td><td>Owner </td></tr>"
	foreach ($snapshot in $report){
		Write-Output "<td>$($snapshot.vm)</td><td>$($snapshot.name)</td><td>$($snapshot.created)</td><td>$($snapshot.host)</td><td> "
	}
	Write-Output "</table></body></html>"
}

$username = '######'
$password = '#######'
$ServerList = "########"
*$Report = @()

foreach ($server in $serverlist){
	if ($server -eq "VCServer"){Connect-VIServer $server}
	else {Connect-VIServer $server -user $username -password $password}
	get-vm | get-snapshot | % {
		$Snap = {} | Select VM,Name,Created,Host, DSdir
		$Snap.VM = $_.vm.name
		$Snap.Name = $_.name
		$Snap.Created = $_.created -lt (Get-Date).AddDays(-20)
		$Snap.Host = $_.vm.host.name
		$vm = Get-View -Id $_.VM.Id
		foreach($snaptree in $vm.Snapshot.RootSnapshotList){
		  if($snaptree.Name -eq $_.Name){
		    $sn = Get-View $snaptree.Snapshot
			$Snap.DSdir = $sn.Config.Files.SnapshotDirectory
		  }
		}
		$Report += $Snap
	}
}

PS: I'm not sure how you get your output. I suspect there is a call to the Generate-Report function missing somewhere.


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

ContractChris
Contributor
Contributor
Jump to solution

Thanks that has helped to get the datastore name/path for each snapshot.

Minor downpoint is that the login to VC seems to loop 3 times now - when the script is run it logs in 3 times.

You were right about the generate-report function being missing in the output i posted, that was user error.

The formatting of the HTML page has been messsed up a little since the changes. Instead of each entry in the table having a seperate row, all entries are now listed on the one row one after another.

Do you have any idea what could of caused this?

Again many thanks its much appreciated.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

The Connect-VIServer is called within the loop that runs through all the servers in $ServerList.

In the script below I moved the Connect-VIServer outside the loop when it concerns the "VCServer".

There was a table-row statement missing at the start of the line where the snapshot data is written.

function Generate-Report {
	Write-Output "<html><head><title></title><style type=""text/css"">.Error {color:#FF0000;font-weight: bold;}.Title {background: #0011D2;color: #FFFFFF;text-align:center;font-weight: bold;}.Normal {}</style></head><body><table>"
	Write-Output "<tr class=""Title""><td colspan=""7"">VC report</td></tr><tr class="Title"><td>VM Name </td><td>Snapshot Name </td><td>Older than 24 Hours </td><td>Host </td><td>Datastore </td><td>Owner </td></tr>"
	foreach ($snapshot in $report){
		Write-Output "<tr><td>$($snapshot.vm)</td><td>$($snapshot.name)</td><td>$($snapshot.created)</td><td>$($snapshot.host)</td><td>$($snapshot.DSdir)</td></tr>"
	}
	Write-Output "</table></body></html>"
}

$username = '######'
$password = '#######'
$ServerList = "########"
$Report = @()

if ($server -eq "VCServer"){Connect-VIServer $server}
foreach ($server in $serverlist){
	if ($server -ne "VCServer") {Connect-VIServer $server -user $username -password $password}
	get-vm | get-snapshot | % {
		$Snap = {} | Select VM,Name,Created,Host, DSdir
		$Snap.VM = $_.vm.name
		$Snap.Name = $_.name
		$Snap.Created = $_.created -lt (Get-Date).AddDays(-20)
		$Snap.Host = $_.vm.host.name
		$vm = Get-View -Id $_.VM.Id
		foreach($snaptree in $vm.Snapshot.RootSnapshotList){
		  if($snaptree.Name -eq $_.Name){
		    $sn = Get-View $snaptree.Snapshot
			$Snap.DSdir = $sn.Config.Files.SnapshotDirectory
		  }
		}
		$Report += $Snap
	}
}
Generate-Report > "C:\Temp\test.htm"


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

0 Kudos
ContractChris
Contributor
Contributor
Jump to solution

That works nicely, thanks again.

0 Kudos
wolficool
Contributor
Contributor
Jump to solution

Hello,

Thats a good script, but the Owner for the Snapshots is Empty. ?:|

I need the info which User has created the Snapshot.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Have a look at .

But you could also use Alan's vCheck (Daily Report) V3


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

0 Kudos
wolficool
Contributor
Contributor
Jump to solution

By the first Script i become the following Error:

You cannot call a method on a null-valued expression.

At C:\DOCUME1\vmadmin\LOCALS1\Temp\2\946b7dd5-d780-4df4-b011-018b1db0e607.ps1:35 char:54

+ $filter.Time.beginTime = (($snap.Created).AddSeconds <<<< (-5))

+ CategoryInfo : InvalidOperation: (AddSeconds:String) [], RuntimeException

+ FullyQualifiedErrorId : InvokeMethodOnNull

You cannot call a method on a null-valued expression.

At C:\DOCUME1\vmadmin\LOCALS1\Temp\2\946b7dd5-d780-4df4-b011-018b1db0e607.ps1:57 char:49

+ $key = $_.vm.Name + "&" + ($_.Created.ToString <<<< ())

+ CategoryInfo : InvalidOperation: (ToString:String) [], RuntimeException

+ FullyQualifiedErrorId : InvokeMethodOnNull

Exception calling "ContainsKey" with "1" argument(s): "Key cannot be null.

Parameter name: key"

At C:\DOCUME1\vmadmin\LOCALS1\Temp\2\946b7dd5-d780-4df4-b011-018b1db0e607.ps1:58 char:25

+ if($report.ContainsKey <<<< ($key)){

+ CategoryInfo : NotSpecified: (Smiley Happy [], MethodInvocationException

+ FullyQualifiedErrorId : DotNetMethodException

The 2nd Script is to much. I just need the Snapshot Creater.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

There was indeed a problem when the script found snapshot creation events for snapshots that are already removed.

The attached version should take care of that problem.


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

0 Kudos
wolficool
Contributor
Contributor
Jump to solution

Hello thanks for this, but in this script i must be give the name of the vmmachine. This script had also a problem :-((

The term '<' is not recognized as a cmdlet, function, operable program, or script file. Verify the term and try again.

At C:\DOCUME1\vmadmin\LOCALS1\Temp\2\1bdac87e-ca21-4d59-9336-b7866ac612c7.ps1:65 char:12

+ $vmName = < <<<< VCS01>

+ CategoryInfo : ObjectNotFound: (<:String) [], CommandNotFoundException

+ FullyQualifiedErrorId : CommandNotFoundException

Get-VM : Cannot validate argument on parameter 'Name'. The argument cannot be null or empty.

At C:\DOCUME1\vmadmin\LOCALS1\Temp\2\1bdac87e-ca21-4d59-9336-b7866ac612c7.ps1:67 char:20

+ $Snapshots = Get-VM <<<< $vmName | Get-Snapshot | %{Get-SnapshotExtra $_}

+ CategoryInfo : InvalidData: (Smiley Happy , ParameterBindingValidationException

+ FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.Commands.GetVM

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You have to replace the text "<VM-name>" by the actual name of the VM machine.


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

0 Kudos
MadMax1980
Contributor
Contributor
Jump to solution

Hi there,

very nice script.

i'am trying to merge this script and to loop through the whole Vcenter.

But i have there a little understanding problem.

How could make an output to an variable correctly to use it as a input for an other query

i attached the script.

i changed the following:

Line 23: $vms = get-vm |Get-Snapshot |Select-Object VM (i get all the vm's with snapshot)

Line 44: foreach ($vm in $vms) (touch every vm with snapshot)

Line 46 : $_.EntityName -eq $vm} (i changed there to $vm)

Line 60: Get-VM $vm (changed also to $vm)

So now he recognized the Vm Objects but he could not touch them with get-vm

i got following error:

_________________________________________________________________________________

Get-VM : 27.11.2009 18:14:50 Get-VM VM with name '@{VM=TESTVM}' n

ot found, using the specified filter(s).

At C:\DOCUME1\xxxxxx\LOCALS1\Temp\b32e37d0-7eff-4f9e-8ee4-8239517899ee.ps1:

59 char:25

+ $snapshotsExtra = Get-VM <<<< $vm | Get-Snapshot | % {

Export-Csv : Cannot bind argument to parameter 'InputObject' because it is null

.

At C:\DOCUME1\xxxxxx\LOCALS1\Temp\b32e37d0-7eff-4f9e-8ee4-8239517899ee.ps1:

67 char:29

+ $snapshotsExtra | Export-Csv <<<< "C:\SnapshotsExtra.csv" -NoTypeInformation

______________________________________________________________________________

the VM Name is TESTVM. How could i avoid the @{} ? ;(

Many thx

Best Regards

Max

0 Kudos
LucD
Leadership
Leadership
Jump to solution

That's because the Select-Object cmdlet passes a custom object.

You could replace that line with

$vms = get-vm |Get-Snapshot | %{$_.VM}


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

0 Kudos
MadMax1980
Contributor
Contributor
Jump to solution

Hi,

thx for answer.

i changed your advice. but now i get following error:

Get-VM : 27.11.2009 20:18:43 Get-VM VM with name 'VMware.Vim.VirtualM

achine' not found, using the specified filter(s).

Regards

Max

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Oops, that should have been

Get-Vm | Get-SNapshot | %{$_.VM.Name}


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

0 Kudos
MadMax1980
Contributor
Contributor
Jump to solution

Hi

;( sry same error.

should i change elswhere too ?

regards

Max

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I adapted my previous script to run through all the guests with snapshots.

Give this one a try.


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

0 Kudos
MadMax1980
Contributor
Contributor
Jump to solution

ah very nice Smiley Wink

Many thx

Best regards

Max

0 Kudos