WizardKit/.bin/Scripts/functions/repairs.py
Alan Mason 6fc04266d4 2017-11: Retroactive Updates
## MAJOR refactoring done ##

* All .cmd Command scripts
  * Brandind / Settings variables now set via .bin/Scripts/settings/main.py
  * Window titles now set using KIT_FULL_NAME

* All .py Python scripts
  * All ClientDir paths should now use KIT_SHORT_NAME
  * Long lines wrapped to better follow PEP8
  * String formatting now more consistant
  * Updated run_program() and popen_program() calls to use lists
    * (e.g. cmd = ['', '', '']; run_program(cmd))
    ** Should improve clarity IMO
  * Update window titles AFTER init_global_vars() so KIT_FULL_NAME can be used

* Branding / Settings
  * Support tech now configurable
    * (e.g. "Please let {tech} know and they'll look into it")
  * Timezone now configurable
  * Upload info can now be disabled/enabled in .bin/Scripts/settings/main.py

* CHKDSK
  * Combined read-only and fix scripts and added menu

* DISM
  * Combined ScanHealth and RestoreHealth scripts and added menu

* functions/common.py
  * BREAKING: run_program() and popen_program() no longer accept 'args' variable

* Misc
  * Removed Win7 NVMe launcher
    * Never used and Win7 is deprecated
  * Removed "DeviceRemover" and "Display Driver Uninstaller" launchers
    * Both cut too deep and were not useful
  * Removed Nirsoft utilities and Sysinternals Suite launchers
    * Too many tools unused.
    * Added .url links to the websites in case the tools are needed
  * Replaced WinDirStat with TreeSizeFree
  * Replaced Q-Dir launcher with XYplorer launcher
    * Q-Dir was running into issues on Windows 10
  * Removed C.IntRep, ESET, and MBAM launchers from "OSR & VR"
  * Removed JRT
    * Deprecated and discontinued by MBAM
  * Removed unsupported QuickBooks launchers (2014 and older)
  * Removed unsupported Office launchers (2010 and 2013\365)
  * Removed "Revo Uninstaller" launcher
  * Removed infrequently used tools from "Diagnostics"
    * Auslogics DiskDefrag
    * BatteryInfoView
    * BIOSCodes
    * GpuTest
    * HeavyLoad

* Bugfixes
  * major_exception() try-blocks should catch CTL+c again
    * Allows for manual script bailing
2017-11-17 01:02:24 -07:00

126 lines
4.5 KiB
Python

# Wizard Kit: Functions - Repairs
from functions.common import *
def run_chkdsk(repair=False):
"""Run CHKDSK scan or schedule offline repairs."""
if repair:
run_chkdsk_offline()
else:
run_chkdsk_scan()
def run_chkdsk_scan():
"""Run CHKDSK in a "split window" and report errors."""
if global_vars['OS']['Version'] in ['8', '10']:
cmd = ['chkdsk', global_vars['Env']['SYSTEMDRIVE'], '/scan', '/perf']
else:
cmd = ['chkdsk', global_vars['Env']['SYSTEMDRIVE']]
out = run_program(cmd, check=False)
# retcode == 0: no issues
# retcode == 1: fixed issues (also happens when chkdsk.exe is killed?)
# retcode == 2: issues
if int(out.returncode) > 0:
# print_error(' ERROR: CHKDSK encountered errors')
raise GenericError
# Save stderr
with open(r'{LogDir}\CHKDSK.err'.format(**global_vars), 'a') as f:
for line in out.stderr.decode().splitlines():
f.write(line.strip() + '\n')
# Save stdout
with open(r'{LogDir}\CHKDSK.log'.format(**global_vars), 'a') as f:
for line in out.stdout.decode().splitlines():
f.write(line.strip() + '\n')
def run_chkdsk_offline():
"""Set filesystem 'dirty bit' to force a chkdsk during next boot."""
cmd = [
'fsutil', 'dirty',
'set',
global_vars['Env']['SYSTEMDRIVE']]
out = run_program(cmd, check=False)
if int(out.returncode) > 0:
raise GenericError
def run_dism(repair=False):
"""Run DISM /RestoreHealth, then /CheckHealth, and then report errors."""
if global_vars['OS']['Version'] in ['8', '10']:
if repair:
# Restore Health
cmd = [
'DISM', '/Online',
'/Cleanup-Image', '/RestoreHealth',
r'/LogPath:"{LogDir}\DISM_RestoreHealth.log"'.format(
**global_vars),
'-new_console:n', '-new_console:s33V']
else:
# Scan Health
cmd = [
'DISM', '/Online',
'/Cleanup-Image', '/ScanHealth',
r'/LogPath:"{LogDir}\DISM_ScanHealth.log"'.format(
**global_vars),
'-new_console:n', '-new_console:s33V']
run_program(cmd, pipe=False, check=False, shell=True)
wait_for_process('dism')
# Now check health
cmd = [
'DISM', '/Online',
'/Cleanup-Image', '/CheckHealth',
r'/LogPath:"{LogDir}\DISM_CheckHealth.log"'.format(**global_vars)]
result = run_program(cmd, shell=True).stdout.decode()
# Check result
if 'no component store corruption detected' not in result.lower():
raise GenericError
else:
raise UnsupportedOSError
def run_kvrt():
"""Run KVRT."""
extract_item('KVRT', silent=True)
os.makedirs(global_vars['QuarantineDir'], exist_ok=True)
cmd = [
global_vars['Tools']['KVRT'],
'-accepteula', '-dontcryptsupportinfo', '-fixednames',
'-d', global_vars['QuarantineDir'],
'-processlevel', '3']
popen_program(cmd, pipe=False)
def run_sfc_scan():
"""Run SFC in a "split window" and report errors."""
cmd = [
r'{SYSTEMROOT}\System32\sfc.exe'.format(**global_vars['Env']),
'/scannow']
out = run_program(cmd, check=False)
# Save stderr
with open(r'{LogDir}\SFC.err'.format(**global_vars), 'a') as f:
for line in out.stderr.decode('utf-8', 'ignore').splitlines():
f.write(line.strip() + '\n')
# Save stdout
with open(r'{LogDir}\SFC.log'.format(**global_vars), 'a') as f:
for line in out.stdout.decode('utf-8', 'ignore').splitlines():
f.write(line.strip() + '\n')
# Check result
log_text = out.stdout.decode('utf-8', 'ignore').replace('\0', '')
if re.findall(r'did\s+not\s+find\s+any\s+integrity\s+violations', log_text):
pass
elif re.findall(r'successfully\s+repaired\s+them', log_text):
raise GenericRepair
else:
raise GenericError
def run_tdsskiller():
"""Run TDSSKiller."""
extract_item('TDSSKiller', silent=True)
os.makedirs(r'{QuarantineDir}\TDSSKiller'.format(
**global_vars), exist_ok=True)
cmd = [
global_vars['Tools']['TDSSKiller'],
'-l', r'{LogDir}\TDSSKiller.log'.format(**global_vars),
'-qpath', r'{QuarantineDir}\TDSSKiller'.format(**global_vars),
'-accepteula', '-accepteulaksn',
'-dcexact', '-tdlfs']
run_program(cmd, pipe=False)
if __name__ == '__main__':
print("This file is not meant to be called directly.")