VSS Writers are responsible for backups – if they stop working, then backups might fail. The solution to that is restarting VSS Writers, but the problem here is that there are many, and at least out of the box, there’s no mechanism to make this automatic… but there’s PowerShell.

I’m not interested in your code, I just want to restart these VSS Writers

In that case, head on to: mygithub, use the code and run:

That function will go ahead, retrieve all failed VSS Writers, and restart associated services with them. If that won’t help, then you probably need to reboot the server.

Get-KPVssWriter

Let’s talk PowerShell

The source code is available on GitHub.

As far as VSS Writers go, there were a few issues needed to be addressed for the function:

  • the VssAdmin.exe tool is CMD only, and returns only strings.
  • There’s no filter in VssAdmin, thus it always returns all writers
  • The writers are associated with many Windows Services, and it’s not always obvious which service is responsible for given VSS Writer

Therefore I’ve written a couple of functions:

  • Get-KPVssWriter – that function will convert the output string from VssAdmin into a PowerShell objects + it can filter results by state (at the moment Stable or Failed).
  • Restart-KPVssWriter – this function takes the name of the VSS writer and restarts required service with it. It has hard-coded names of VSS writers with associated services.

How do you make a use of these?

You pipe results from Get function, to Restart function thus:

will retrieve all failed writers and restart them. Let’s look into actual code.

Get-KPVssWriter

First is to run VSSAdmin and start converting the output into PowerShell object:

Select-String

These two lines will convert the output from vssadmin into PowerShell object. The Select-String really shines here as:

  • -Pattern parameter allows it to search for a specific phrase. In that case I’m looking for ‘Writer name:’ as each listed writer starts with that line.
  • -Context 0,4 tells PowerShell that for each pattern (line) you found, match 0 line prior to it, and 4 past it.

Thus if we look for this sample:

You can see that there’s pattern: Each Writer Name is followed by four line of text, and then the next one appears.

Select-String will then create an object for each pattern found, with properties of Line, Context.PostContext and Context.PreContext.

And since we know that:

Line = pattern found,

Context.PostContext = an array of each line found past pattern

Context.PreContext. = an array of each line found prior the pattern

It’s very easy to create the object, but first we need to remove the leftovers of the string.

Replace

For every object generated by Select-String, I will assign a specific variable, and run -replace to remove unnecessary characters. Replace can also take regex , making it super effective while working with text.

PsCustomObject

The final step is to assembly all variables created in previous step into a PowerShell object:

Since the main purpose of using this function is to restart failed, I thought it would be worth to add a parameter for filtering out VSS Writers based on status, thus this simple if statement which amends what will be outputed by the function:

There we go, the analogue application has been converted into a digital form (LOL), we can go ahead now and work on the actual restarts.

Restart-KPVssWriter

This function will take the name of the VSS writer that requires restart, match Windows service to it, and restart the service.

Switch

PowerShell has a beatifull command – Switch – that eliminates the need of writing complex if statements. Let’s have a look:

Hell yeah, that would be quite a if statement. Instead of that, switch will match the name on the left, and execute the code to the right.

The last line is interesting, default – if switch won’t match the name, it will execute that one instead. I’m casting that into $null.

If

The final step is to restart service:

Simple restart of service if it was matches earlier on, or just write warning if it wasn’t found.

Happy ever after

I hope you found this useful. What can be done here is e.g. put the script into a scheduled task to run hourly, and hopefully you will have one problem less to worry about – as nobody likes to see failed backups on Monday morning.

Photo by Jason Yu on Unsplash