Pause_Updates = 7
"""
give the number of days to pause updates. For Example: Pause_Updates = 35
give 0 to unpause the updates. for Example: Pause_Updates = 0
"""

Receive_Updates_For_Other_Microsoft_Products = "on"
"""
give "on" if you want to Turn On Receive updates for other Microsoft products when you update Windows
give "off" if you want to Turn Off Receive updates for other Microsoft products when you update Windows
"""

Get_me_up_to_date = "on"
"""
give "on" if you want to Turn On "Get me up to date"
give "off" if you want to Turn Off "Get me up to date"
This Option is also known as "Restart this device as soon as possible when a restart is required to install an update" in windows 10
"""

Download_Updates_Over_Metered_Connections = "on"
"""
give "on" if you want to Turn On download updates over metered connections
give "off" if you want to Turn Off download updates over metered connections
"""

Notify_me_when_a_restart_is_required_to_finish_updating = "on"
"""
give "on" if you want to Turn On "Notify me when a restart is required to finish updating"
give "off" if you want to Turn Off "Restart this device as soon as possible when a restart is required to install an update"
This Option is also Known as "Restart this device as soon as possible when a restart is required to install an update" in windows 10
"""

Beta_or_Release_Preview_Insider_Preview_Builds = "on"
"""
give "on" if you want to Turn On Stop Getting "Beta" or "Release Preview" Insider Preview Builds
give "off" if you want to Turn Off Stop Getting "Beta" or "Release Preview" Insider Preview Builds
"""

import os
from subprocess import PIPE, Popen
import ctypes
from datetime import datetime, timedelta

class disable_file_system_redirection:
    _disable = ctypes.windll.kernel32.Wow64DisableWow64FsRedirection
    _revert = ctypes.windll.kernel32.Wow64RevertWow64FsRedirection
    def __enter__(self):
        self.old_value = ctypes.c_long()
        self.success = self._disable(ctypes.byref(self.old_value))
    def __exit__(self, type, value, traceback):
        if self.success:
            self._revert(self.old_value)

def ecmd(command):   
    from subprocess import Popen, PIPE
    import ctypes
    
    with disable_file_system_redirection():
        obj = Popen(command, shell = True, stdout = PIPE, stderr = PIPE)
    out, err = obj.communicate()
    ret=obj.returncode
    return ret,out,err


def Modify_Reg(Option_Name, TurnON_or_TurnOFF, Reg_key, Value_Name, Value_Type): 
    if TurnON_or_TurnOFF.lower()=="off":
        ret,out,err = ecmd('reg add "%s" /v %s /t %s /d 0 /f'%(Reg_key,Value_Name,Value_Type))
        if ret==0:
            if out:
                print(out)
            print('successfully turned off %s'%(Option_Name))
        else:
            print(err)
    elif TurnON_or_TurnOFF.lower()=="on":
        ret,out,err = ecmd('reg add "%s" /v %s /t %s /d 1 /f'%(Reg_key,Value_Name,Value_Type))
        if ret==0:
            if out:
                print(out)
            print('successfully turned on %s'%(Option_Name))
        else:
            print(err)

def Run_Powershell_command(Option_Name,TurnON_or_TurnOFF,on_cmd,off_cmd):
    if TurnON_or_TurnOFF.lower()=="off":
        ret,out,err = ecmd(['powershell', off_cmd])
        if ret==0:
            if out:
                print(out)
            print('successfully turned off %s'%(Option_Name))
        else:
            print(err)
    elif TurnON_or_TurnOFF.lower()=="on":
        ret,out,err = ecmd(['powershell', on_cmd])
        if ret==0:
            if out:
                print(out)
            print('successfully turned on %s'%(Option_Name))
        else:
            print(err)

def add_and_delete_reg(add_or_delete, Reg_key, Value_Name, Value_Type=None,Value_data=None):
    if add_or_delete == "add":
        ret,out,err = ecmd('reg add "%s" /v "%s" /t "%s" /d "%s" /f'%(Reg_key,Value_Name,Value_Type,Value_data))
        if ret==0:
            if out:
                print(out)
        else:
            print(err)
    elif add_or_delete == "delete":
        ret,out,err = ecmd('reg delete "%s" /v "%s" /f'%(Reg_key,Value_Name))
        if ret==0:
            if out:
                print(out)
        else:
            print(err)

Pause_Updates_Data = ['a_d_reg',Pause_Updates,r"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings","REG_SZ"]

IPB_Data = ['reg',Beta_or_Release_Preview_Insider_Preview_Builds,r"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsSelfHost\UI\Selection","OptOutState","REG_DWORD"]

Receive_updates_for_other_Ms_products_Turn_on_command = r'(New-Object -com "Microsoft.Update.ServiceManager").AddService2("7971f918-a847-4430-9279-4a52d1efe18d",7,"")'
Receive_updates_for_other_Ms_products_Turn_off_command = r'(New-Object -com "Microsoft.Update.ServiceManager").RemoveService("7971f918-a847-4430-9279-4a52d1efe18d")'

Rec_Update_MS_Products_Data = ['powershell',Receive_Updates_For_Other_Microsoft_Products,Receive_updates_for_other_Ms_products_Turn_on_command,Receive_updates_for_other_Ms_products_Turn_off_command]

Download_Update_Over_Metered_Conections_Data = ['reg',Download_Updates_Over_Metered_Connections,r"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings","AllowAutoWindowsUpdateDownloadOverMeteredNetwork","REG_DWORD"]

Get_me_up_to_date_Data = ['reg',Get_me_up_to_date, r"HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsUpdate\UX\Settings","IsExpedited","REG_DWORD"]

Notify_me_when_a_restart_is_required_to_finish_updating_Data = ["reg",Notify_me_when_a_restart_is_required_to_finish_updating,r"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings","RestartNotificationsAllowed2","REG_DWORD"]


Option_Name_and_Data = {
    'Pause Updates': Pause_Updates_Data,
    'Stop Getting "Beta" or "Release Preview" Insider Preview Builds': IPB_Data,
    'Receive updates for other Microsoft products when you update Windows': Rec_Update_MS_Products_Data,
    'download updates over metered connections': Download_Update_Over_Metered_Conections_Data,
    'Get me up to date': Get_me_up_to_date_Data,
    'Notify me when a restart is required to finish updating': Notify_me_when_a_restart_is_required_to_finish_updating_Data
}

for Option_name in Option_Name_and_Data:
    Type = Option_Name_and_Data[Option_name][0]
    if Type=="reg":
        Type, Turn_on_or_off_value, Reg_key, Value_Name, Value_type = Option_Name_and_Data[Option_name]
        Modify_Reg(Option_name,Turn_on_or_off_value,Reg_key,Value_Name,Value_type)
    elif Type=="powershell":
        Type, Turn_on_or_off_value, on_cmd, off_cmd = Option_Name_and_Data[Option_name]
        Run_Powershell_command(Option_name,Turn_on_or_off_value,on_cmd,off_cmd)
    elif Type=="a_d_reg":
        Type, Days, Reg_key, Value_type = Option_Name_and_Data[Option_name]
        if Days>0:
            now = datetime.utcnow()
            now_DT_format = now.strftime(r"%Y-%m-%dT%H:%M:%SZ")
            future = now + timedelta(days=Days)
            DT_format = future.strftime(r"%Y-%m-%dT%H:%M:%SZ")
            message = "successfully changed Pause Updates Settings to given days"
            valueName_and_data = {
                "PauseFeatureUpdatesEndTime": DT_format,
                "PauseFeatureUpdatesStartTime": now_DT_format,
                "PauseQualityUpdatesEndTime": DT_format,
                "PauseQualityUpdatesStartTime": now_DT_format,
                "PauseUpdatesExpiryTime": DT_format,
                "PauseUpdatesStartTime": now_DT_format
            }
            for valueName in valueName_and_data:
                add_and_delete_reg('add', Reg_key, valueName, Value_type, valueName_and_data[valueName])
            print(message)
        elif Days<=0:
            message = "successfully changed Pause Updates Settings to unpause the updates"
            name_list = [
                "PauseFeatureUpdatesEndTime", 
                "PauseFeatureUpdatesStartTime", 
                "PauseQualityUpdatesEndTime",
                "PauseQualityUpdatesStartTime",
                "PauseUpdatesExpiryTime",
                "PauseUpdatesStartTime"
            ]
            for valueName in name_list:
                add_and_delete_reg('delete', Reg_key, valueName)
            print(message)