Search code examples
batch-filecommandvolume-shadow-service

Batch file: Automate VSS Snapshot checks


I'm looking for a way to create a VSS snapshot for all drives on a server, to ensure that the functionality is working as expected - after which i would need to delete the snapshots - so far I've been keeping it simple.

 vssadmin create shadow /for=C: >> C:\temp\vssoutput.txt
 vssadmin create shadow /for=E: >> C:\temp\vssoutput.txt

 vssadmin delete shadows /for=C:
 vssadmin delete shadows /for=E:

as time goes by, i've starting coming across servers with F:\, G:\ or even SQL mount points - so I'm looking to automate this script a little more.

Ideally i would like to run a check on drives (wmic Volume get Capacity, Name) , then set them as a variable and run the vssadmin command based on that variable, looping through all until completed.

any ideas where to start?


Solution

  • You can use for /F to parse the output of a command, like a wmic command line.

    Firstly, we need to assemble a suitable wmic command:

    wmic LOGICALDISK WHERE (DriveType=3 AND Size^>0) GET Name /VALUE
    

    Let us use LOGICALDISK rather than than VOLUME, because the latter returns also items with no drive letter and system-reserved partitions.
    The filter DriveType=3 includes local disk drives only; the filter Size>0 excludes non-formatted items (the > must be escaped like ^> in the command line, because > has a special meaning -- redirection).
    The /VALUE switch tells wmic to return lines like Name=C:.

    Then, we wrap around the proper for /F command (see also for /? for help):

    for /F "tokens=2 delims==" %%V in ('
        wmic LOGICALDISK WHERE ^(DriveType^=3 AND Size^^^>0^) ^
            GET Name /VALUE
    ') do for /F "delims=" %%L in ("%%V") do (
        echo.%%L
        rem Here you may add your `vssadmin` command lines:
        vssadmin create shadow /for=%%L >> C:\temp\vssoutput.txt
        ::
        vssadmin delete shadows /for=%%L
    )
    

    There are actually two nested for /F loops: the outer one parses the output of the wmic command line and enumerates all found drives; the inner one iterates exactly once per drive and is intended to remove carriage-return characters which might be appended by the wmic command.

    To use the above built wmic command line within for /F, several special characters need to be escaped; this explains the additional ^ symbols.


    To include also mountpoints in the output of the wmic command, you could use the following command line:

    wmic VOLUME WHERE (DriveType=3 AND FileSystem^>"" AND SystemVolume=FALSE) GET Name
    

    The filter DriveType=3 includes local disk drives only; the filter FileSystem>"" excludes non-formatted items; the filter SystemVolume=FALSE excludes system-reserved partitions.

    To parse the output with for /F, you need to escape special characters by ^ like above.