Leveraging PowerShell to Enable or Disable System Restore on Windows Systems

System Restore is a powerful feature in Windows that allows users to revert their system to a previous state, addressing issues caused by faulty updates, software installations, or other changes. For IT professionals and Managed Service Providers (MSPs), configuring System Restore efficiently and programmatically is vital, particularly when managing multiple systems. A robust PowerShell script, like the one provided here, offers a precise, automated way to enable, disable, or manage restore points on Windows devices.

Background

System Restore safeguards system integrity by creating snapshots called restore points. While this feature is a lifesaver in emergencies, its configuration often requires administrative intervention, especially in enterprise environments. Manual configuration is not scalable for large networks, making a PowerShell-based solution indispensable. This script streamlines System Restore management, helping IT teams ensure that systems are configured consistently while avoiding potential issues such as excessive shadow copy deletions.

The Script:

#Requires -Version 5.1

<#
.SYNOPSIS
    Enables or Disables System Restore on System Drive(C:). Use caution when enabling on a system that contains system image backups(VSS).
.DESCRIPTION
    Enables or Disables System Restore on System Drive(C:). Use caution when enabling on a system that contains system image backups(VSS), as it will cause shadow copies to be deleted faster than normal.

    By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use.
    Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. 
    Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. 
    Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. 
    Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. 
    Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. 
    Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. 
    EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).

.EXAMPLE
    (No Parameters)
    ## EXAMPLE OUTPUT WITHOUT PARAMS ##

PARAMETER: -Action "Enable"
    Enables System Restore.
.EXAMPLE
    -Action "Enable"
    ## EXAMPLE OUTPUT WITH Action ##
    [Info] Enabling System Restore
    [Info] Enabled System Restore

PARAMETER: -Action "Disable"
    Disables System Restore.
.EXAMPLE
    -Action "Disable"
    [Info] Disabling System Restore
    [Info] Disabled System Restore

PARAMETER: -Action "DisableAndRemove"
    Disables System Restore and removes all existing restore points.
.EXAMPLE
    -Action "DisableAndRemove"
    [Info] Disabling System Restore
    [Info] Disabled System Restore
    [Info] Removing Existing Restore Points
    [Info] Removed Existing Restore Points

.NOTES
    Minimum OS Architecture Supported: Windows 10, Windows Server 2016
    Release Notes: Initial Release
#>

[CmdletBinding()]
param (
    [Parameter()]
    [ValidateSet("Enable", "Disable", "DisableAndRemove")]
    [string]$Action
)

begin {
    $EnableSystemRestore = $false
    $DisableSystemRestore = $false
    $RemoveExistingRestorePoints = $false
    function Test-IsElevated {
        $id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
        $p = New-Object System.Security.Principal.WindowsPrincipal($id)
        $p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
    }

    # If the registry value is 1, System Restore is enabled.
    $RegValue = Get-ItemPropertyValue -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SystemRestore\" -Name "RPSessionInterval" -ErrorAction SilentlyContinue

    $SystemRestoreStatus = if ($RegValue -ge 1) {
        # If either of the above conditions are met, System Restore is enabled.
        Write-Output "Enabled"
    }
    else {
        Write-Output "Disabled"
    }

    # Check if the action Script Variable was used
    if ($env:action -and $env:action -ne "null") {
        switch ($env:action) {
            "Enable" { $EnableSystemRestore = $true }
            "Disable" { $DisableSystemRestore = $true }
            "Disable and Remove Existing Restore Points" { $RemoveExistingRestorePoints = $true }
            Default {
                Write-Host -Object "[Error] Invalid Action"
                exit 1
            }
        }
        
    }
    # Check if the parameter Action was used
    else {
        switch ($Action) {
            "Enable" { $EnableSystemRestore = $true }
            "Disable" { $DisableSystemRestore = $true }
            "DisableAndRemove" { $RemoveExistingRestorePoints = $true }
            Default {
                Write-Host -Object "[Error] Invalid Action"
                exit 1
            }
        }
    }
    function Remove-ComputerRestorePoint {
        [CmdletBinding(SupportsShouldProcess = $True)]param(
            [Parameter(
                Position = 0,
                Mandatory = $true,
                ValueFromPipeline = $true
            )]
            $RestorePoint
        )
        begin {
            $fullName = "SystemRestore.DeleteRestorePoint"
            #check if the type is already loaded
            $isLoaded = $null -ne ([AppDomain]::CurrentDomain.GetAssemblies() | ForEach-Object { $_.GetTypes() } | Where-Object { $_.FullName -eq $fullName })
            if (!$isLoaded) {
                $SRClient = Add-Type -MemberDefinition @"
[DllImport ("Srclient.dll")]
public static extern int SRRemoveRestorePoint (int index);
"@ -Name DeleteRestorePoint -Namespace SystemRestore -PassThru
            }
        }
        process {
            foreach ($restorePoint in $RestorePoint) {
                if ($PSCmdlet.ShouldProcess("$($restorePoint.Description)", "Deleting Restore Point")) {
                    [SystemRestore.DeleteRestorePoint]::SRRemoveRestorePoint($restorePoint.SequenceNumber) | Out-Null
                }
            }
        }
    }
}
process {
    if (-not (Test-IsElevated)) {
        Write-Host -Object "[Error] Access Denied. Please run with Administrator privileges."
        exit 1
    }

    # Get Windows Install Drive from SystemRoot
    $TargetDrive = "$($env:SystemRoot -split "\\" | Select-Object -First 1)\"

    $ExitCode = 0
    # When the action is Enable
    if ($EnableSystemRestore) {
        if ($SystemRestoreStatus -eq "Enabled") {
            Write-Host -Object "[Info] System Restore is already enabled."
            exit 0
        }

        # Save the current value of the SystemRestorePointCreationFrequency registry key
        $OldValue = try {
            Get-ItemPropertyValue -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\SystemRestore" -Name "SystemRestorePointCreationFrequency" -ErrorAction Stop -WarningAction Stop
        }
        catch {
            # Return the default value of 1440 minutes if the registry key does not exist
            1440
        }
        if ($null -ne $OldValue) {
            Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\SystemRestore" -Name "SystemRestorePointCreationFrequency" -Value "0" -ErrorAction SilentlyContinue
        }

        # Enable System Restore
        try {
            Write-Host -Object "[Info] Enabling System Restore: $TargetDrive"
            Enable-ComputerRestore -Drive "$TargetDrive"
            Write-Host -Object "[Info] Enabled System Restore: $TargetDrive"
        }
        catch {
            Write-Host -Object "[Error] Failed to enable System Restore"
            $ExitCode = 1
        }

        try {
            Write-Host -Object "[Info] Creating restore point."

            # Create a new restore point
            Checkpoint-Computer -Description "Restore Point Created by Enable or Disable System Restore" -RestorePointType "MODIFY_SETTINGS" -ErrorAction Stop -WarningAction Stop

            Write-Host -Object "[Info] Created Restore Point."
        }
        catch {
            Write-Host -Object "[Error] Failed to create restore point."
            $ExitCode = 1
        }

        # Restore the old value of the SystemRestorePointCreationFrequency registry key
        if ($null -ne $OldValue) {
            Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\SystemRestore" -Name "SystemRestorePointCreationFrequency" -Value $OldValue -ErrorAction SilentlyContinue
        }
    }
    # When the action is Disable
    elseif ($DisableSystemRestore) {
        if ($SystemRestoreStatus -eq "Disabled") {
            Write-Host -Object "[Info] System Restore is already disabled."
            exit 0
        }
        # Disable System Restore
        try {
            Write-Host -Object "[Info] Disabling System Restore: $TargetDrive"
            Disable-ComputerRestore -Drive "$TargetDrive"
            Write-Host -Object "[Info] Disabled System Restore: $TargetDrive"
        }
        catch {
            Write-Host -Object "[Error] Failed to disable System Restore"
            $ExitCode = 1
        }
    }
    # When the action is DisableAndRemove / Disable and Remove Existing Restore Points
    elseif ($RemoveExistingRestorePoints) {
        if ($SystemRestoreStatus -eq "Disabled") {
            Write-Host -Object "[Info] System Restore is already disabled."
            exit 0
        }
        # Remove all existing restore points
        try {
            Write-Host -Object "[Info] Removing Existing Restore Points"
            Get-ComputerRestorePoint | Remove-ComputerRestorePoint
            Write-Host -Object "[Info] Removed Existing Restore Points"
        }
        catch {
            Write-Host -Object "[Error] Failed to remove existing restore points"
            $ExitCode = 1
        }
        # Disable System Restore
        try {
            Write-Host -Object "[Info] Disabling System Restore: $TargetDrive"
            Disable-ComputerRestore -Drive "$TargetDrive"
            Write-Host -Object "[Info] Disabled System Restore: $TargetDrive"
        }
        catch {
            Write-Host -Object "[Error] Failed to disable System Restore"
            $ExitCode = 1
        }
    }
    exit $ExitCode
}
end {
    
    
    
}

 

Save time with over 300+ scripts from the NinjaOne Dojo.

Get access today.

Detailed Breakdown

The script is well-structured and versatile, catering to three primary actions:

  1. Enable System Restore: Activates the System Restore functionality.
  2. Disable System Restore: Turns off System Restore without removing existing restore points.
  3. Disable and Remove Restore Points: Disables System Restore and deletes all existing restore points.

Here’s how the script functions step by step:

1. Initialization and Parameter Handling:

a. The script begins by defining parameters (Enable, Disable, and DisableAndRemove) and initializing variables to manage these actions.

b. It checks if the script is run with administrator privileges using the Test-IsElevated function. This ensures the necessary permissions for modifying system settings.

2. Detecting Current System Restore Status:

a. The script retrieves the current status of System Restore from the Windows Registry. If the registry key RPSessionInterval exists and has a value, System Restore is considered enabled.

3. Action Execution:

a. Based on the specified action, the script executes the corresponding tasks:

i. Enable: Activates System Restore on the system drive and creates a new restore point.

ii. Disable: Deactivates System Restore.

iii. DisableAndRemove: Deactivates System Restore and removes all existing restore points using the Remove-ComputerRestorePoint function.

4. Error Handling:

a. Throughout the script, exceptions are caught, and detailed error messages are logged. This provides transparency and helps IT professionals troubleshoot issues effectively.

Potential Use Cases

Case Study: Automated Endpoint Management

Imagine an MSP managing hundreds of endpoints for a client. To ensure consistent rollback capabilities, the MSP uses this script to enable System Restore on all machines during deployment. Later, to free up disk space, they run the script with the DisableAndRemove parameter on devices nearing storage limits. This automated approach saves time and reduces errors compared to manual configurations.

Comparisons

Other methods to manage System Restore include using the Windows GUI or Group Policy. While the GUI offers simplicity for individual users, it is inefficient for large-scale operations. Group Policy provides centralized control but lacks the granularity and immediate feedback of PowerShell. This script bridges the gap, offering scalability, precision, and immediate execution feedback.

FAQs

1. Can this script be used on older versions of Windows?

The script is designed for Windows 10 and Windows Server 2016 or later. For older versions, adjustments to registry keys or commands may be required.

2. What happens if I run the script without administrator privileges?

The script checks for administrative rights and terminates if insufficient privileges are detected, preventing partial execution.

3. Will enabling System Restore affect existing system image backups?

Yes, enabling System Restore can increase shadow copy deletions, which may interfere with system image backups.

Implications

Using this script correctly can significantly enhance endpoint resilience, but mismanagement could lead to data loss, especially when deleting restore points. IT administrators must balance the benefits of System Restore with potential storage constraints and backup strategies.

Recommendations

  • Test in a Controlled Environment: Always test scripts in a lab or staging environment before deploying them to production systems.
  • Document Changes: Keep a record of when and where the script is executed to maintain a clear audit trail.
  • Integrate with Backup Solutions: Combine System Restore configurations with comprehensive backup strategies to ensure optimal protection.

Final Thoughts

This PowerShell script is a valuable tool for IT professionals seeking to manage System Restore efficiently. It enables automation, consistency, and precision, addressing the challenges of manual configurations. For those looking to streamline endpoint management further, solutions like NinjaOne can offer integrated tools for monitoring, automation, and backup management, ensuring a robust and secure IT environment.

Next Steps

Building an efficient and effective IT team requires a centralized solution that acts as your core service deliver tool. NinjaOne enables IT teams to monitor, manage, secure, and support all their devices, wherever they are, without the need for complex on-premises infrastructure.

Learn more about NinjaOne Remote Script Deployment, check out a live tour, or start your free trial of the NinjaOne platform.

Categories:

You might also like

×

See NinjaOne in action!

By submitting this form, I accept NinjaOne's privacy policy.

NinjaOne Terms & Conditions

By clicking the “I Accept” button below, you indicate your acceptance of the following legal terms as well as our Terms of Use:

  • Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms.
  • Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party.
  • Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library belonging to or under the control of any other software provider.
  • Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations.
  • Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks.
  • Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script.
  • EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).