Search code examples
windowsbatch-filebackupcommand-promptshadow-copy

Backup from shadow copy


So, I want to make backups from the shadow-copy using batch-script. That's what I have so far:

vssadmin list shadows | findstr /C:"Volume da Cópia de Sombra"

Output:

     Volume da Cópia de Sombra: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1
     Volume da Cópia de Sombra: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy2
     Volume da Cópia de Sombra: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy5

I need to get only the path in the last line returned by findstr, but I really don't know how I'll accomplish it.

And after getting the path and add a \to the end (it will only make the symbolic link if the path ends with a \) make a symbolic link to it.

mklink c:\shadowcopy /d %path%

So, I'm lost in the middle of it.

I found this question with an answer:

Batch file to output last line of findstr

But man, batch syntax is a mess and I don't understand a line of code in the answer to adapt it to my project.

Can someone help me and explain in details what i need to do (or the code, if you provide it) so I can understand what I'm doing instead of just paste and copy and, who knows, make some improvements/changes.


Solution

  • Whenever you want to capture the output of a command, use for /f. I suggest that ? would be a convenient delimiter in this case.

    This snippet would create links for all the shadow copies.

    if not exist c:\shadowcopy md c:\shadowcopy
    for /f "tokens=2 delims=?" %%I in ('vssadmin list shadows ^| find "GLOBALROOT"') do (
        mklink /d c:\shadowcopy\%%~nxI \\?%%I\
    )
    

    This snippet would create a single link from the final matched line of the shadow list.

    for /f "tokens=2 delims=?" %%I in ('vssadmin list shadows ^| find "GLOBALROOT"') do (
        set "target=\\?%%I\"
    )
    mklink /d c:\shadowcopy %target%
    

    See the difference? In the first code block, mklink fires on every iteration of the for /f loop and creates many symlinks; whereas in the second block, set overwrites the value stored in %target% on every iteration. mklink runs outside the loop, and therefore creates only one symlink. That's the secret sauce you're looking for I think.

    In a cmd console, enter help for for more information on for /f loops.