Po$H Pete | Those who can… $cript
26May/112

Get Volume Shadow Copy Information from Powershell

A colleague came and asked me yesterday if it was possible to get Volume Shadow Copy Information from a list of servers..... Powershell to the rescue!

The biggest problem that I found is that the data in the WMI class refers to the drive by it's device ID, so I've built in a lookup to translate that to a drive letter.

Here's the function I came up with, hope it can help you too.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
Function Get-ShadowCopyInfo([string]$Computer,[string]$UserName,[string]$Password,[switch]$MB,[switch]$PromptForCredentials,[switch]$NoCredentials)
{
<#
.Synopsis
Get volume shadow copy information
.Description
Obtains volume shadow copy information for local and remote servers
.Parameter Computer
The name of the computer you wish to run the command against, default is LocalHost
.Parameter UserName
The UserName for any credentials you wish to pass
.Parameter Password
The Password for any credentials you wish to pass
.Parameter MB
Return stats in MB rather than GB
.Parameter PromptForCredentials
This will prompt you to enter credentials for the server, rather than passing in the data in plain text.
.Parameter NoCredentials
Forces the function to not use any credentials.
 
.Example
Get-ShadowCopyInfo
 
This will return information about the shadow copy data on localhost
.Example
Get-ShadowCopyInfo -Computer ServerA -UserName "MyDomain\MyUser" -Password "MyPassword"
 
This will return information about the shadow copy data on ServerA using the supplied credentials
.Example
Get-ShadowCopyInfo -Computer ServerA -PromptForCredentials
 
This will return information about the shadow copy data on ServerA, but will prompt you to enter credentials.
.Example
Get-ShadowCopyInfo -Computer ServerA -NoCredentials
 
This will return information about the shadow copy data on ServerA using no additional credentials.
.Example
Get-ShadowCopyInfo -MB
 
This will return data about the shadow copy volume on your computer, but return the stats in MB rather than GB.
 
.Notes
Name: Get-ShadowCopyInfo
Author: Peter Rossi
Last Edited: 26th May 2011
#>
 
	if(-not $UserName)
	{
		if(-not $Password)
		{
			If(-not $PromptForCredentials)
			{
				$NoCredentials = $True
			}
		}
	}
 
	if(-not $Computer)
	{
		$Computer = "LocalHost"
	}
	if(-not $NoCredentials)
	{
		if(-not $PromptForCredentials)
		{
			$SecPass = convertto-securestring -asplaintext -string $Password -force
			$Creds = new-object System.Management.Automation.PSCredential -argumentlist $UserName,$SecPass
		}
		Else
		{
			$Creds = Get-Credential 
		}
	}
 
	if(-not $NoCredentials)
	{
		$ShadowInfo = gwmi -Class win32_shadowstorage -ComputerName $Computer -Credential $Creds
		$VolumeInfo =  gwmi -Class win32_volume -ComputerName $Computer -Credential $Creds
	}
	Else
	{
		$ShadowInfo = gwmi -Class win32_shadowstorage -ComputerName $Computer
		$VolumeInfo =  gwmi -Class win32_volume -ComputerName $Computer
	}
 
	$Final = @()
	ForEach($Shadow in $ShadowInfo)
	{
		if(-not $MB)
		{
			$ARow = "" | Select Computer,Drive,SizeGB,ShadowMaxSizeGB,ShadowUsedSizeGB,ShadowPercent,TimeChecked
		}
		Else
		{
			$ARow = "" | Select Computer,Drive,SizeMB,ShadowMaxSizeMB,ShadowUsedSizeMB,ShadowPercent,TimeChecked
		}
		$ARow.Computer = $Computer
		$ARow.TimeChecked = Get-Date
 
		ForEach($Vol in $VolumeInfo)
		{
			If($Shadow.Volume -like "*$($Vol.DeviceId.trimstart("\\?\Volume").trimend("\"))*")
			{
				$ARow.Drive = $Vol.Name
				if($MB)
				{
					$ARow.SizeMB = "{0:N2}" -f ($Vol.Capacity/1024/1024)
					$ARow.ShadowMaxSizeMB = "{0:N2}" -f ($Shadow.MaxSpace/1024/1024)
					$ARow.ShadowUsedSizeMB = "{0:N2}" -f ($Shadow.UsedSpace/1024/1024)
				}
				Else
				{
					$ARow.SizeGB = "{0:N2}" -f ($Vol.Capacity/1024/1024/1024)
					$ARow.ShadowMaxSizeGB = "{0:N2}" -f ($Shadow.MaxSpace/1024/1024/1024)
					$ARow.ShadowUsedSizeGB = "{0:N2}" -f ($Shadow.UsedSpace/1024/1024/1024)
				}
				$Percent = ($Shadow.MaxSpace/$Vol.Capacity) * 100
				$ARow.ShadowPercent = [int]$Percent
 
			}
 
		}
 
		$Final += $ARow
 
 
	}
 
	Return $Final
 
 
}
Comments (2) Trackbacks (0)
  1. Good one!
    However, when there is no limit set (ShadowMaxSize), the script returns an error, whereby it cannot process a number higher than the maximum value possible for [int32] (which is 2147483647).
    So, i’ve changed the following lines (for MB and for GB):
    $ARow.SizeMB = “{0:N2}” -f ($Vol.Capacity/1024/1024)
    $ARow.ShadowMaxSizeMB = “{0:N2}” -f ($Shadow.MaxSpace/1024/1024)
    $ARow.ShadowUsedSizeMB = “{0:N2}” -f ($Shadow.UsedSpace/1024/1024)

    To (for MB):
    $ARow.SizeMB = [math]::Round($Vol.Capacity/1MB)
    $ARow.ShadowMaxSizeMB = [math]::Round($Shadow.MaxSpace/1MB)
    $ARow.ShadowUsedSizeMB = [math]::Round($Shadow.UsedSpace/1MB)

    And (for GB):
    $ARow.SizeGB = [math]::Round($Vol.Capacity/1GB)
    $ARow.ShadowMaxSizeGB = [math]::Round($Shadow.MaxSpace/1GB)
    $ARow.ShadowUsedSizeGB = [math]::Round($Shadow.UsedSpace/1GB)

    and I don’t get an int32 error anymore.

    thanks for this script though!

    Nick

  2. Sorry, and changed this one too:

    $ARow.ShadowPercent = [int]$Percent

    to

    $ARow.ShadowPercent = [int64]$Percent


Leave a comment

(required)

No trackbacks yet.