powershellwindowwindows-servershadow-copyvssettings

Shadow copy disabled detection in powershell


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


Solution

  • 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