Shadow copy disabled detection in powershell

833 Views Asked by At

I am looking for a script in Powershell, which list information about VSS shadow copy on Windows Server 2016. I need to detect if shadow copy on specific volumes is Enabled or Disabled.

In GUI (This PC > Right click on (C:) > Configure Shadow Copies) you can Disabled or Enabled each volume for shadow copy. You can see in attach images "Volume" and "Next Run time" ("Time" or "Disabled" status).

I looking for stript in powerhsell that list information which I can see in GUI?

I have tried vssadmin list volumes or Get-CimInstance Win32_ShadowCopy but I need detect if VSS on specific Volume is Enabled or Disabled.

Please, does anybody know this issue?

Thank you for you answers and your help!

enter image description here enter image description here

2

There are 2 best solutions below

0
On BEST ANSWER

I previously wrote a script to do just this and I found that I needed to use a combination of vssadmin list shadowstorage and Get-ScheduledTask in order to pull all of the information I needed.

Here's what I came up with previously (it was a rush job that I never went back to, so could do with a bit of a tidy up and some error checking, but it should set you on the right path):

$configuration = vssadmin list shadowstorage

Add-Type -TypeDefinition @' 
namespace ScheduledTasks
{ 
    [System.Flags]
    public enum DaysOfWeek 
    { 
        Sunday = 1, 
        Monday = 2, 
        Tuesday = 4, 
        Wednesday = 8, 
        Thursday = 16, 
        Friday = 32, 
        Saturday = 64 
    } 
} 
'@

Function Get-Days($flags)
{
    $days = @()
    if (($flags -band [ScheduledTasks.DaysOfWeek]::Monday) -ne 0)
    {
        $days += "Monday";
    }

    if (($flags -band [ScheduledTasks.DaysOfWeek]::Tuesday) -ne 0)
    {
        $days += "Tuesday";
    }

    if (($flags -band [ScheduledTasks.DaysOfWeek]::Wednesday) -ne 0)
    {
        $days += "Wednesday";
    }

    if (($flags -band [ScheduledTasks.DaysOfWeek]::Thursday) -ne 0)
    {
        $days += "Thursday";
    }

    if (($flags -band [ScheduledTasks.DaysOfWeek]::Friday) -ne 0)
    {
        $days += "Friday";
    }

    if (($flags -band [ScheduledTasks.DaysOfWeek]::Saturday) -ne 0)
    {
        $days += "Saturday";
    }

    if (($flags -band [ScheduledTasks.DaysOfWeek]::Sunday) -ne 0)
    {
        $days += "Sunday";
    }
    
    return $days -join ",";
}

$count = 0;
foreach ($line in $configuration)
{
  if ($line.StartsWith("Shadow Copy Storage association"))
  {
      $DriveLetter = $($configuration[$count + 1]).Trim()
      $DriveLetter = $DriveLetter.Substring($DriveLetter.IndexOf('(') + 1, 2)

      $VSSDriveLetter = $($configuration[$count + 2]).Trim()
      $VSSDriveLetter = $VSSDriveLetter.Substring($VSSDriveLetter.IndexOf('(') + 1, 2)

      $UsedSpace = $($configuration[$count + 3]).Trim()
      $UsedSpace = $UsedSpace.Substring($UsedSpace.IndexOf(':') + 2)

      $AllocatedSpace = $($configuration[$count + 4]).Trim()
      $AllocatedSpace = $AllocatedSpace.Substring($AllocatedSpace.IndexOf(':') + 2)

      $MaxSpace = $($configuration[$count + 5]).Trim()
      $MaxSpace = $MaxSpace.Substring($MaxSpace.IndexOf(':') + 2)

      $VolumeID =  $($configuration[$count + 1]).Trim()
      $VolumeID = $VolumeID.Substring($VolumeID.IndexOf('{'), 38)

      $Enabled = $false;
      $Triggers = @();
      $Task = Get-ScheduledTask -TaskName "ShadowCopyVolume$($VolumeID)" -ea SilentlyContinue
      if ($Task -ne $null)
      {
        $TaskInfo = $Task | Get-ScheduledTaskInfo
        $Enabled = $Task.State -ne "Disabled";
        foreach ($Trigger in $Task.Triggers)
        {
            $object = New-Object -typeName PSObject
            $object | Add-Member -Type NoteProperty -Name "Start" -Value ([DateTime]::Parse($Trigger.StartBoundary))
            $object | Add-Member -Type NoteProperty -Name "End" -Value $(if ($Trigger.EndBoundary) {[DateTime]::Parse($Trigger.EndBoundary) } else { "" })
            $object | Add-Member -Type NoteProperty -Name "Days" -Value (Get-Days -flag $Trigger.DaysOfWeek)
            $object | Add-Member -Type NoteProperty -Name "WeeksInterval" -Value $Trigger.WeeksInterval
            $object | Add-Member -Type NoteProperty -Name "LastRunTime" -Value $TaskInfo.LastRunTime
            $object | Add-Member -Type NoteProperty -Name "NextRunTime" -Value $TaskInfo.NextRunTime
            $Triggers += $object
        }
      }

      $object = New-Object -TypeName PSObject
      $object | Add-Member -Type NoteProperty -Name "Source" -Value $DriveLetter
      $object | Add-Member -Type NoteProperty -Name "Destination" -Value $VSSDriveLetter
      $object | Add-Member -Type NoteProperty -Name "UsedSpace" -Value $UsedSpace
      $object | Add-Member -Type NoteProperty -Name "AllocatedSpace" -Value $AllocatedSpace
      $object | Add-Member -Type NoteProperty -Name "MaximumSpace" -Value $MaxSpace
      $object | Add-Member -Type NoteProperty -Name "Enabled" -Value $Enabled
      $object | Add-Member -Type NoteProperty -Name "Triggers" -Value $Triggers

      Write-Output $object
  }

  $count++;
}

This script outputs the following information as PSObjects that filtered with the Where-Object and Select-Object, etc...

Shadow Copy Data

1
On

I have the same task, but the system language is not English. So I decided to use another method - check the response template of the "vssadmin listshadowstorage" command. If the template is not found, then shadow storage is not enabled for that drive. But this code also enables shadow storage if the disk has 10% free space.

get-volume | ForEach-Object {
    $DriveLetter=$_.DriveLetter
    if ($DriveLetter -notlike "") {
        $DriveLetter=$DriveLetter+":"
        $ShadowStorage=$(vssadmin list shadowstorage /On="$DriveLetter" | Select-String -Pattern '(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})')
        if ($ShadowStorage -eq $null){
            $AllowSpace=$_.Size
            $FreeSpace=$_.SizeRemaining
            $SizeForRecovery=10 #percent
            $HaveFreeSpace=($AllowSpace/$SizeForRecovery) -lt $FreeSpace
            if ($HaveFreeSpace) {
                try{
                    enable-computerrestore -drive $($DriveLetter+"\")
                    vssadmin Resize ShadowStorage /For=$DriveLetter /On=$DriveLetter /Maxsize=$("$SizeForRecovery"+"%")
                }
                catch{
                    Write-Host("Enable shadow storage for drive $DriveLetter - FAILED")
                }
                finally{
                    Write-Host("Enable shadow storage for drive $DriveLetter - SUCCESFULLY")
                }
            }
        } else {
            Write-Host("For drive $DriveLetter shadow storage is already enabled")
        }
    }
}