How do I backup network share and scheduled task information on Server 2012

We recently had a problem where the system (C:) drive of a Windows Server 2012 VM got hosed by an update.

Unfortunately we did not know about the problem until a reboot which happened long enough after the update that it transpired that all backups had the same problem.

This was not catastrophic as the data drives were fine and so we just attached them to a different server.

The big problem that we did have was that this was a file server and in losing the system, we also lost:-

1. The configuration of all the file shares on this server (there were a lot)
2. Detail of all the scheduled tasks on this server

So even though the shared data and associated file permissions remained, we had to rebuild all the file shares and this has taken a long time (and we are still discovering things that we missed).

So - I am wondering if there is an easy way to backup this configuration data in some other way so that it could be easily restored in the future if this happened again?

I am looking for something in addition to a standard backup, so even if the C: drive was corrupt on every backup instance, we could still restore this information using some other method.

The suggestion of keeping backups for longer is a valid one, however this is a server on an IaaS platform and it is not cost effective to keep backups for any longer than 2 weeks.

How do other people do this?  Anyone got any ideas?

FriendlyITInfrastructure TeamAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

DonNetwork AdministratorCommented:
I would use either Hyper-V replication or configure DFS or both.
DonNetwork AdministratorCommented:
FriendlyITInfrastructure TeamAuthor Commented:

The servers (which are IaaS so we don't have access above the OS layer anyway) I believe are running on VMware so I am not sure how Hyper-V replication would help (unless I am missing something).

How would we use DFS to help?

(I am not that familiar with either of these technologies, so it might well be that they would both help, but maybe you can elaborate on how we would use them to help with this?)

Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

DonNetwork AdministratorCommented:
Well, with DFS you would have identical shares on each server that's added to DFS. These get replicated between themselves. Users will be unaware of what server their share is pointed to. This allows users to have shares local, instead of over the WAN.

Look over
FriendlyITInfrastructure TeamAuthor Commented:
Thanks for that.  Worth knowing about.

I see two problems with that for us.

1. Storage costs are at a premium, so replicating the data would be prohibitive.  It is the information about the shares as opposed to the content of the shares that I am looking to back up.  Is it possible to do this in DFS without replicating the content?

2. We have a lot of hard-coded UNC paths around at the moment.  Wouldn't DFS break those?
Jose TorresCertified Database AdministratorCommented:
We faced an issue where during DR exercises we needed to recreate the shares and permissions as well.
We created a 2 powershell scripts.  One will export the shares and permissions to a csv file the other will import the shares and permissions from the csv file.

This is the code for the export change backup location to suit your needs
# change to the servername to be used. (currently set to get local computer name)
$ServerName = $Env:COMPUTERNAME

# get the current timestamp
$Date = Get-Date -Uformat '%Y%m%d%H%M%S'
# setup the filename
$FileName = 'C:\DisasterRecovery\Backup_Shares\Backups\' + 'Backup_' + $ServerName + '_ShareInfo_' + $Date + '.csv' 

# get Shares (Type o is "Normal" shares) 
$Shares = Get-WmiObject Win32_Share -ComputerName $ServerName -Filter 'type=0' 

# combine Shares with Security info 
$ShareInfo = @() 
Foreach ($share IN $Shares) { 
	$shareSec = Get-WmiObject Win32_LogicalShareSecuritySetting -ComputerName $ServerName -Filter "name='$($'" 
  	IF($shareSec) { 
    	$sd = $shareSec.invokeMethod('GetSecurityDescriptor',$null,$null) 
    	$ShareInfo += $sd.Descriptor.DACL |% { 
      		$_ | select @{e={$};n='Name'}, 
		$ShareInfo += $share | select Name,Path,Description 

# Export the shares to CSV 
$ShareInfo | select Name,Path,Description,User,Domain,SID, 
  AccessMask,AceFlags,AceType | export-csv -noType $filename

Open in new window

This is the code for the Import. I run this from a batch file so you will need to modify the $fname and remove the param section of the script. Also change the filename path accordingly.

# get argument passed by cmd
	[Parameter(Mandatory=$true)] [string] $fname,
	[Parameter(ValueFromRemainingArguments=$true)] $args
# check if more than 1 argument was passed
if ($args) {
	Write-Host "ERROR: Unknown argument(s): $args"
	Exit 2
# set filename and path
$FileName = 'C:\DisasterRecovery\Backup_Shares\Backups\' + $fname
# check if file exists
if (!(Test-Path $FileName)) {
	Write-Host "ERROR: File $FileName does not exist."
	Exit 3


# Functions used in script #

Function Modify-WMIShareACL([string]$ServerName, [string]$ShareName, $ace){
    $wPrivilege = Get-WmiObject Win32_LogicalShareSecuritySetting -ComputerName $ServerName -filter "name='$ShareName'" 
    $wPrivilege.psbase.Scope.Options.EnablePrivileges = $true 
    $oldDACL = ($wPrivilege.GetSecurityDescriptor()).Descriptor.DACL 
    $sd = ([WMIClass] ("\\" + $ServerName + "\root\CIMv2:Win32_SecurityDescriptor")).CreateInstance()     
    $sd.DACL = $oldDACL #copy
    $sd.DACL += @($ace.psobject.baseobject) # append
    $sd.ControlFlags="0x4" # set SE_DACL_PRESENT flag 

Function Create-WMITrustee ([string]$ServerName, [string]$ShareUser, [string]$ShareSID){
	$sid = New-Object Security.Principal.SecurityIdentifier($ShareSID)
	[byte[]]$ba = ,0 * $sid.BinaryLength     

	$Trustee = ([WMIClass] ("\\" + $ServerName + "\root\CIMv2:Win32_Trustee")).CreateInstance() 
    $Trustee.SID = $ba

Function Create-WMIAce ([string]$ServerName, [string]$ShareUser, [string]$ShareSID, [string]$ShareAccessMask, [string]$ShareAceFlags, [string]$ShareAceType){
	$Trustee = Create-WMITrustee $ServerName $ShareUser $ShareSID
	$ace = ([WMIClass] ("\\" + $ServerName + "\root\CIMv2:Win32_ACE")).CreateInstance() 
	$ace.AccessMask = $ShareAccessMask
	$ace.AceFlags = $ShareAceFlags
	$ace.AceType = $ShareAceType
	$ace.Trustee = $Trustee


# change to the servername to be used. (currently set to get local computer name)
$ServerName = $Env:COMPUTERNAME

# Import the CSV file 
$ShareList = Import-Csv $FileName 


# get the unique shares 
$UniqueShares = $ShareList | select -Unique name, Path, Description
# go thru each unique share
Foreach ($ushare in $UniqueShares) {
	$ShareName = $
	$SharePath = $ushare.Path
	$ShareDesc = $ushare.Description
	# check if path exists
	if (!(Test-Path $SharePath)) {
		Write-Host "ERROR: Path $SharePath DOES NOT EXIST"
		Exit 5
	# create share if it does not exist
	if (!(Get-WmiObject Win32_Share -ComputerName $ServerName | Where-Object -FilterScript {$_.Name -eq $ShareName})) {
		# create pointer to Win32_Share
		[WMIClass]$cshare = "\\$ServerName\root\CIMv2:Win32_Share"
		# create share
		$rc = $cshare.Create($SharePath, $ShareName, 0, 0, $ShareDesc)
		# get description or rc value
		Switch ($rc.returnvalue){
			0  {$rvalue = "Success"}
			2  {$rvalue = "Access Denied"}
			8  {$rvalue = "Unknown Failure"}
			9  {$rvalue = "Invalid Name"}
			10 {$rvalue = "Invalid Level"}
			21 {$rvalue = "Invalid Parameter"}
			22 {$rvalue = "Duplicate Share"}
			23 {$rvalue = "Redirected Path"}
			24 {$rvalue = "Unknown Device or Directory"}
			25 {$rvalue = "Net Name Not Found"}
		# check return value of create
		if ($rc.returnvalue -ne 0){
			Write-Host ("ERROR: Failed to create share {0} for {1} on {2}. Error: {3}" -f $ShareName, $SharePath, $ServerName, $rvalue)
			Exit 6

Foreach ($record in $ShareList) {
	$ShareName = $record.Name
	$SharePath = $record.Path
	$ShareDesc = $record.Description
	$ShareUser = $record.User
	$ShareDomain = $record.Domain
	$ShareSID = $record.SID
	$ShareAccessMask = $record.AccessMask
	$ShareAceFlags = $record.AceFlags
	$ShareAceType = $record.AceType
	$ace = Create-WMIAce $ServerName $ShareUser $ShareSID $ShareAccessMask $ShareAceFlags $ShareAceType
	Modify-WMIShareACL $ServerName $ShareName $ace

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
FriendlyITInfrastructure TeamAuthor Commented:
That looks interesting.  Thanks Jose.

Either got any suggestions for easily backing up / recreating scheduled tasks?
Jose TorresCertified Database AdministratorCommented:
I create a C:\DisasterRecovery\Backup_Shares folder on every production server with shares
Then create a scheduled task to run the export powershell script
Use the following for the command "Powershell.exe"
Use the following for the arguments "-ExecutionPolicy Bypass C:\DisasterRecovery\Backup_Shares\ExportShares.ps1"
Make sure you change the path
Jose TorresCertified Database AdministratorCommented:
Not related but I also backup the following on a scheduled basis
Shares, IIS, Windows Features, FSRM
Makes it a lot easier to stand up 43 servers during our yearly DR exercise.
FriendlyITInfrastructure TeamAuthor Commented:
Thanks - sorry you slightly misunderstood my question.

The other part of my original question was how to easily backup scheduled tasks as this was the other thing we lost when the C: drive was hosed.

How would you actually backup all the scheduled tasks? (i.e. the detail of what is running with what frequency?)
FriendlyITInfrastructure TeamAuthor Commented:
Anyone got any thoughts on that?
Jose TorresCertified Database AdministratorCommented:
Scheduled tasks are stored here C:\Windows\System32\Tasks
The files have no extension but they are in fact an xml file.
You can copy this file out and rename it with the .xml extension and import it using Task Scheduler.

I know this is an after the fact, but may help going forward.
For every scheduled task I export the scheduled task and save in the C:\DisasterRecovery\Backup_ScheduledTask folder.
Yes I use this a lot in every prod server this is because were mandated to do disaster recovery exercises every year and when you have to stand up 40+ servers in 2 days it comes in handy having some stuff locally on the server to use after we do the restores.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Windows Server 2012

From novice to tech pro — start learning today.