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.

2 Answers 2

4
+50

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
4
  • It looks perfect. I didn't see the Delete() method listed in this article msdn.microsoft.com/en-us/library/aa394428(v=vs.85).aspx. Presumably this method is inherited from somewhere?
    – john
    Jul 31, 2013 at 6: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 1, 2013 at 11:25
  • I see now. $shadowCopies[0].GetType() is ManagementObject, which does provide .Delete() -- still not sure why it wouldn't be shown with Get-Member.
    – jscott
    Aug 1, 2013 at 11:35
  • One more try: $shadowCopies[0] | Get-Member -Force -View All will show .Delete(). Guess you learn something new everyday. :)
    – jscott
    Aug 1, 2013 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.

2
  • 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, 2013 at 14:44
  • You can specify a remote path so you only have to have a single batch file.
    – Nathan C
    Jul 25, 2013 at 14:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .