3

I currently use DISKSHADOW to remove shadow copies from our Hyper-V servers. To do this I have to log onto the server but psexec doesn't work.

psexec \\hyper-v-server diskshadow
DISKSHADOW> Error reading from console. Win32 error: 0x6
The handle is invalid.

I think vssadmin works doing the above, but I'd like to script this with PowerShell and slectively remove the shadow copies. Neither of these tools provide usable output in PowerShell.

I've done a bit of research but not found any way to query snapshots with PowerShell, either locally or remotely. I imagine doing this will involve use of the Get-WMIObject CMDlet to query the relevant info from WMI, but I can only find the Win32_ShadowCopy.Create() method.

EDIT: To be clear, what I would like are objects I can manipulate using PowerShell.

john
  • 1,995
  • 1
  • 17
  • 30

2 Answers2

4

You can use the Get-WMIObject cmdlet to remotely remove shadow copies. The example below demonstrates how it might work. It should be noted that the Get-WMIObject cmdlet returned a null object in the case where there were not any remote shadow copies available. This means that might still need a combination of PowerShell remoting and the vssadmin tool to remotely create shadow copies.

On the target server (from an elevated command prompt), let's first create a shadow copy so that one is available:

vssadmin create shadow /for=c:

From the management server:

$shadowCopies = Get-WMIObject -Class Win32_ShadowCopy -Computer <TARGET SERVER NAME>
$shadowCopies | % {$_.DeviceObject}  # Lists out just the names of the copies
$shadowCopies | Get-Member -View All # Lists all members even hidden ones such as "delete"
$shadowCopies[0].Delete()            # Deletes the first shadow copy when more than one exists
$shadowCopies.Delete()               # Works when only a single shadow copy exists
  • It looks perfect. I didn't see the Delete() method listed in this article http://msdn.microsoft.com/en-us/library/aa394428(v=vs.85).aspx. Presumably this method is inherited from somewhere? – john Jul 31 '13 at 06:52
  • +1. I was exploring the very same path as @tchester, when `$shadowCopies[0] | Get-Member -Force` did not contain `.Delete()` I started looking elsewhere. This is a great answer, I'd love to here where `.Delete()` is inherited from and why it's not "shown". – jscott Aug 01 '13 at 11:25
  • I see now. `$shadowCopies[0].GetType()` is [ManagementObject](http://msdn.microsoft.com/en-us/library/System.Management.ManagementObject.aspx), which does provide `.Delete()` -- still not sure why it wouldn't be shown with `Get-Member`. – jscott Aug 01 '13 at 11:35
  • One more try: `$shadowCopies[0] | Get-Member -Force -View All` will show `.Delete()`. Guess you learn something new everyday. :) – jscott Aug 01 '13 at 12:01
3

You can do this remotely with diskshadow. To accomplish this, write a batch file containing the wanted commands and place it somewhere on the target server, then: psexec \\remotehost diskshadow /s C:\path\to\script.bat. You can also use a network location for the path.

Nathan C
  • 14,901
  • 4
  • 42
  • 62
  • Thanks @NathanC. I was aware of this also, but I don't like the idea of having to maintain the batch files on each of our hosts. It just feels a bit "hacky". – john Jul 25 '13 at 14:44
  • You can specify a remote path so you only have to have a single batch file. – Nathan C Jul 25 '13 at 14:48