Public/fastchecks.ps1
# Short, Efficient Functions relevant to the repo. Function RebuildRegistryIndex { # Rebuild the index of the registry. regsvr32 /s /i:u shdocvw.dll } # Rebuild Windows Search Index Function RebuildWSearchIndex { $CurrentLoc = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows Search' -Name DataDirectory Set-Service WSearch -StartupType disabled Stop-Service wsearch Remove-Item $CurrentLoc.DataDirectory -Force -Confirm:$false -Recurse Set-Service WSearch -StartupType Automatic Start-Service WSearch } Function CheckHibernation { # Check if hibernation is enabled. $hibernation = Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Power' -Name HibernateEnabled if ($hibernation.HibernateEnabled -eq 1) { Write-Host "Hibernation is enabled." } else { Write-Host "Hibernation is disabled." } } Function DisableFastBoot { reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Power" /v HiberbootEnabled /t REG_DWORD /d 0 /F Write-Host "Fastboot Disabled" } # Function that resets the page file to default and forces it to be system managed. (This uses .NET or COM objects to do this.) function ResetPageFile { [CmdletBinding()] param( [switch]$Force ) try { # Get the current page file settings $pageFile = Get-WmiObject -Class Win32_PageFileSetting -ErrorAction Stop if (-not $pageFile) { Write-Host "No page file settings found" -ForegroundColor Yellow return $true } $pageFilePath = $pageFile.Name Write-Host "Current page file: $pageFilePath" -ForegroundColor Cyan Write-Host "Current initial size: $($pageFile.InitialSize) MB" -ForegroundColor Cyan Write-Host "Current maximum size: $($pageFile.MaximumSize) MB" -ForegroundColor Cyan # Check if already system managed if ($pageFile.InitialSize -eq 0 -and $pageFile.MaximumSize -eq 0) { Write-Host "Page file is already system managed" -ForegroundColor Green return $true } # To reset to system-managed, we need to: # 1. Set InitialSize to 0 (system-managed) # 2. Set MaximumSize to 0 (system-managed) # 3. Apply the changes $pageFile.InitialSize = 0 $pageFile.MaximumSize = 0 # Apply the changes $result = $pageFile.Put() if ($result.ReturnValue -eq 0) { Write-Host "Successfully reset page file to system-managed settings" -ForegroundColor Green # Verify the changes $updatedPageFile = Get-WmiObject -Class Win32_PageFileSetting Write-Host "Updated initial size: $($updatedPageFile.InitialSize) MB" -ForegroundColor Cyan Write-Host "Updated maximum size: $($updatedPageFile.MaximumSize) MB" -ForegroundColor Cyan if ($Force) { Write-Host "Rebooting system to apply page file changes..." -ForegroundColor Yellow Restart-Computer -Force } else { Write-Host "A system restart may be required for changes to take effect" -ForegroundColor Yellow } } else { Write-Host "Failed to update page file settings. Return code: $($result.ReturnValue)" -ForegroundColor Yellow return $false } } catch { Write-Host "Failed to reset page file: $_" -ForegroundColor Yellow return $false } return $true } # ---------------------------------------------------------------------------- # Name : Start-DefragglerDefrag # Description : Defrag selected drive using standalone version of Defraggler which does not require installation to function # Architect : Converted from Scripting Simon's batch script # # Version History # --------------- # v1.0 - Converted from batch script v2.1 (22nd Jan 2019) - Update to version 2.22.33.995 # ---------------------------------------------------------------------------- Function StartDefrag { <# .SYNOPSIS Defrag selected drive using standalone version of Defraggler. .DESCRIPTION This function defragments a specified drive using the standalone version of Defraggler which does not require installation to function. It automatically detects the system architecture and uses the appropriate executable (df.exe for x86, df64.exe for x64). .PARAMETER Drive The drive letter to defragment (e.g., "C:", "D:"). .PARAMETER DefragglerPath The path to the Defraggler executable directory. Defaults to current directory. .EXAMPLE Start-DefragglerDefrag -Drive "C:" .EXAMPLE Start-DefragglerDefrag -Drive "D:" -DefragglerPath "C:\Tools\Defraggler" .NOTES Requires the standalone Defraggler executables (df.exe and df64.exe) to be present in the specified directory. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [ValidatePattern("^[A-Za-z]:$")] [string]$Drive, [string]$DefragglerPath = $PSScriptRoot ) try { # Clear the console for better output visibility Clear-Host # Force working directory to current directory (equivalent to PUSHD %~dp0) Push-Location $DefragglerPath # Determine OS architecture if ([Environment]::Is64BitOperatingSystem) { $OSArch = "x64" $dfname = "df64.exe" } else { $OSArch = "x86" $dfname = "df.exe" } Write-Host "Operating System Architecture: $OSArch" -ForegroundColor Cyan Write-Host "Using Defraggler executable: $dfname" -ForegroundColor Cyan # Check for valid drive letter if (-not (Test-Path $Drive)) { throw "Drive '$Drive' is not accessible or does not exist" } # Check if the Defraggler executable exists $defragglerExe = Join-Path $DefragglerPath $dfname if (-not (Test-Path $defragglerExe)) { throw "Defraggler executable '$dfname' not found in '$DefragglerPath'" } # Build and execute the command $command = "& '$defragglerExe' '$Drive'" Write-Host "Running: $command" -ForegroundColor Green # Execute the defragmentation $result = Invoke-Expression $command if ($LASTEXITCODE -eq 0) { Write-Host "Defragmentation completed successfully for drive $Drive" -ForegroundColor Green } else { Write-Warning "Defragmentation completed with exit code: $LASTEXITCODE" } return $result } catch { Write-Error "Failed to defragment drive $Drive`: $_" return $false } finally { # Restore the original location Pop-Location } } # ------------------------------- # Name: OneDrive Stuff for Space Issues # Description: function Reset-OneDriveConfiguration { <# .SYNOPSIS Resets and configures OneDrive settings to ensure proper Files on Demand functionality and auto-start. .DESCRIPTION This function checks OneDrive configuration, verifies if it's properly set up, and fixes any issues. It ensures OneDrive runs on boot, enables Files on Demand, and resets OneDrive to correct data sync. .EXAMPLE Reset-OneDriveConfiguration .NOTES Requires administrative privileges to modify HKLM registry keys. #> [CmdletBinding()] param() Write-Host "Starting OneDrive configuration reset..." -ForegroundColor Green # Define registry paths $HKLMregistryPath = 'HKLM:\SOFTWARE\Policies\Microsoft\OneDrive' $DiskSizeregistryPath = 'HKLM:\SOFTWARE\Policies\Microsoft\OneDrive\DiskSpaceCheckThresholdMB' $HKCUOneDrivePath = 'HKCU:\Software\Microsoft\OneDrive' $HKCUPoliciesPath = 'HKCU:\Software\Policies\Microsoft\OneDrive' $TenantGUID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' # Function to check if OneDrive is properly configured function Test-OneDriveConfiguration { $issues = @() # Check if HKLM policies exist if (!(Test-Path $HKLMregistryPath)) { $issues += "HKLM OneDrive policies path missing" } # Check if SilentAccountConfig is set $silentConfig = Get-ItemProperty -Path $HKLMregistryPath -Name 'SilentAccountConfig' -ErrorAction SilentlyContinue if ($silentConfig.SilentAccountConfig -ne 1) { $issues += "SilentAccountConfig not properly set" } # Check if Files on Demand is enabled $filesOnDemand = Get-ItemProperty -Path $HKLMregistryPath -Name 'FilesOnDemandEnabled' -ErrorAction SilentlyContinue if ($filesOnDemand.FilesOnDemandEnabled -ne 1) { $issues += "Files on Demand not enabled" } # Check if OneDrive auto-start is enabled $autoStart = Get-ItemProperty -Path $HKCUPoliciesPath -Name 'EnableAutoStart' -ErrorAction SilentlyContinue if ($autoStart.EnableAutoStart -ne 1) { $issues += "OneDrive auto-start not enabled" } return $issues } # Check current configuration Write-Host "Checking current OneDrive configuration..." -ForegroundColor Yellow $configurationIssues = Test-OneDriveConfiguration if ($configurationIssues.Count -eq 0) { Write-Host "OneDrive appears to be properly configured. Proceeding with reset anyway..." -ForegroundColor Yellow } else { Write-Host "Found configuration issues:" -ForegroundColor Red foreach ($issue in $configurationIssues) { Write-Host " - $issue" -ForegroundColor Red } } try { # Create registry paths if they don't exist Write-Host "Setting up registry paths..." -ForegroundColor Yellow if (!(Test-Path $HKLMregistryPath)) { New-Item -Path $HKLMregistryPath -Force | Out-Null } if (!(Test-Path $DiskSizeregistryPath)) { New-Item -Path $DiskSizeregistryPath -Force | Out-Null } if (!(Test-Path $HKCUPoliciesPath)) { New-Item -Path $HKCUPoliciesPath -Force | Out-Null } # Configure HKLM policies Write-Host "Configuring HKLM OneDrive policies..." -ForegroundColor Yellow New-ItemProperty -Path $HKLMregistryPath -Name 'SilentAccountConfig' -Value '1' -PropertyType DWORD -Force | Out-Null New-ItemProperty -Path $DiskSizeregistryPath -Name $TenantGUID -Value '102400' -PropertyType DWORD -Force | Out-Null New-ItemProperty -Path $HKLMregistryPath -Name 'FilesOnDemandEnabled' -Value '1' -PropertyType DWORD -Force | Out-Null # Configure HKCU policies Write-Host "Configuring HKCU OneDrive policies..." -ForegroundColor Yellow New-ItemProperty -Path $HKCUPoliciesPath -Name 'EnableAutoStart' -Value '1' -PropertyType DWORD -Force | Out-Null # Clear problematic registry entries Write-Host "Clearing problematic OneDrive registry entries..." -ForegroundColor Yellow $regEntriesToDelete = @( 'SilentBusinessConfigCompleted', 'ClientEverSignedIn', 'PersonalUnlinkedTimeStamp', 'OneAuthUnrecoverableTimestamp' ) foreach ($entry in $regEntriesToDelete) { try { reg delete "HKCU\Software\Microsoft\OneDrive" /v $entry /f 2>$null } catch { Write-Verbose "Could not delete registry entry: $entry" } } # Kill OneDrive process Write-Host "Stopping OneDrive process..." -ForegroundColor Yellow $oneDriveProcesses = Get-Process -Name "OneDrive" -ErrorAction SilentlyContinue if ($oneDriveProcesses) { $oneDriveProcesses | Stop-Process -Force Start-Sleep -Seconds 2 } # Restart Explorer Write-Host "Restarting Explorer..." -ForegroundColor Yellow $explorerProcesses = Get-Process -Name "explorer" -ErrorAction SilentlyContinue if ($explorerProcesses) { $explorerProcesses | Stop-Process -Force Start-Sleep -Seconds 2 Start-Process "explorer.exe" } # Reset OneDrive Write-Host "Resetting OneDrive..." -ForegroundColor Yellow $oneDrivePath = "C:\Program Files\Microsoft\OneDrive\OneDrive.exe" if (Test-Path $oneDrivePath) { Start-Process -FilePath $oneDrivePath -ArgumentList "/reset" -Wait } else { Write-Warning "OneDrive executable not found at expected location: $oneDrivePath" } # Verify configuration after reset Write-Host "Verifying configuration after reset..." -ForegroundColor Yellow Start-Sleep -Seconds 5 $finalIssues = Test-OneDriveConfiguration if ($finalIssues.Count -eq 0) { Write-Host "OneDrive configuration reset completed successfully!" -ForegroundColor Green Write-Host "OneDrive should now be properly configured with Files on Demand enabled and auto-start enabled." -ForegroundColor Green } else { Write-Host "Configuration reset completed, but some issues remain:" -ForegroundColor Yellow foreach ($issue in $finalIssues) { Write-Host " - $issue" -ForegroundColor Yellow } } } catch { Write-Error "Error during OneDrive configuration reset: $($_.Exception.Message)" throw } } # ----------------- # Name : Remove-Profiles # Description : Remove profiles for system. Default is not selected. # # VH # --------- function Remove-UserProfiles { <# .SYNOPSIS Removes user profiles from the system using multiple methods. .DESCRIPTION This function attempts to remove user profiles using two different approaches: 1. Manual removal with registry hive unloading and permission changes 2. Using DelProf2 utility for more robust profile removal .PARAMETER ExcludedUsers Array of user names to exclude from removal. Default includes common system accounts. .PARAMETER UseDelProf2 Switch to use DelProf2 utility for profile removal. Default is $false. .EXAMPLE Remove-UserProfiles -ExcludedUsers @('admin', 'svcaccount') -UseDelProf2 .NOTES Requires administrative privileges to remove profiles. #> param( [string[]]$ExcludedUsers = @('svcaccount', 'admin', 'public'), [switch]$UseDelProf2 ) # Configure Excluded Local Users in an array. # Use regex to do -not and -notmatch to filter the profiles. # This is placeholder for additional filtering depending on requirements. if ($UseDelProf2) { # Attempt 2: Nuclear option with DelProf2 binary. It doesn't care about reg hives or any of that shit. Write-Host "Using DelProf2 method for profile removal..." # download delprof Set-ExecutionPolicy Bypass -Scope Process -Force $tempDir = $env:TEMP Set-Location $tempDir $url = 'https://helgeklein.com/downloads/DelProf2/current/Delprof2%201.6.0.zip' Invoke-WebRequest -Uri $url -OutFile "$tempDir\Delprof2.zip" Expand-Archive -Path "$tempDir\Delprof2.zip" -DestinationPath "$tempDir\Delprof2" -Force Set-Location "$tempDir\Delprof2\delprof2" # Get all profiles and filter based on exclusions $profiles = Get-ChildItem 'C:\Users' -Directory | Where-Object { $ExcludedUsers -notcontains $_.Name -and $_.Name -notmatch "^[a-zA-Z0-9].*" } # delete the profiles foreach ($profile in $profiles) { try { $path = $profile.FullName # run delprof2.exe $path & .\delprof2.exe $path Write-Host "Deleted profile: $($profile.Name)" } catch { Write-Warning "Failed to delete profile $($profile.Name): $_" } } } else { # Attempt 1: This is the most basic approach and is error prone due to people fucking with ACLs especially NT AUTHORITY\SYSTEM permission. Write-Host "Using manual method for profile removal..." $profiles = Get-ChildItem 'C:\Users' -Directory | Where-Object { $ExcludedUsers -notcontains $_.Name -and $_.Name -notmatch "^[a-zA-Z0-9].*" } foreach ($profile in $profiles) { try { $path = $profile.FullName $regKey = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" # Find and unload registry hive $sidKey = Get-ChildItem $regKey | Where-Object { (Get-ItemProperty $_.PSPath).ProfileImagePath -eq $path } if ($sidKey) { $sid = $sidKey.PSChildName reg unload "HKU\$sid" 2>$null | Out-Null } # Take ownership and set permissions takeown /f "$path" /r /d y 2>$null | Out-Null icacls "$path" /grant SYSTEM:F /t /c 2>$null | Out-Null # Remove the profile directory Remove-Item "$path" -Recurse -Force -ErrorAction Stop Write-Host "Deleted profile: $($profile.Name)" } catch { Write-Warning "Failed to delete profile $($profile.Name): $_" } } } } |