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.
Detailed Breakdown
The script is well-structured and versatile, catering to three primary actions:
- Enable System Restore: Activates the System Restore functionality.
- Disable System Restore: Turns off System Restore without removing existing restore points.
- 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.