Skip to content

Instantly share code, notes, and snippets.

@wangye
Created January 11, 2016 14:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wangye/bb5f56176086a2da905e to your computer and use it in GitHub Desktop.
Save wangye/bb5f56176086a2da905e to your computer and use it in GitHub Desktop.
'
' File Description : Disable Windows 7/8/8.1 Upgrade to Windows 10
'
' Copyright (c) 2016 WangYe. All rights reserved.
'
' Author: WangYe
' Site: http://wangye.org
' This code is distributed under the BSD license
'
' Usage:
' CScript path/to/this/script
'
' *** 请不要移除此版权信息 ***
'
Option Explicit
Class WinUpdateMgr
Private objSession
Private objCollection
Private Sub Class_Initialize()
Set objSession = WScript.CreateObject("Microsoft.Update.Session")
objSession.ClientApplicationID = "Disable Windows 10 Update Script"
Set objCollection = WScript.CreateObject("Microsoft.Update.UpdateColl")
End Sub
Private Sub Class_Terminate()
Set objCollection = Nothing
Set objSession = Nothing
End Sub
Public Sub AddToCollection(ByRef objUpdateItem)
objCollection.Add objUpdateItem
End Sub
Public Sub ClearCollection()
objCollection.Clear
End Sub
Public Function GetCollectionCount()
GetCollectionCount = objCollection.Count
End Function
Public Function Install()
If objCollection.Count > 0 Then
Dim objInstaller
Set objInstaller = objSession.CreateUpdateInstaller()
objInstaller.Updates = objCollection
Set Install = objInstaller.Install()
ClearCollection
Set objInstaller = Nothing
End If
End Function
Public Function Uninstall()
If objCollection.Count > 0 Then
Dim objInstaller
Set objInstaller = objSession.CreateUpdateInstaller()
objInstaller.Updates = objCollection
Set Uninstall = objInstaller.Uninstall()
ClearCollection
Set objInstaller = Nothing
End If
End Function
Public Function EnumUpdates(ByVal strCallback, ByVal strQuery, ByRef Param)
Dim i
Dim objSearcher, objSearchResult, objUpdateItem
Dim fnCallback
Set fnCallback = GetRef(strCallback)
Set objSearcher = objSession.CreateUpdateSearcher()
Set objSearchResult = objSearcher.Search(strQuery)
For i = 0 To objSearchResult.Updates.Count - 1
Set objUpdateItem = objSearchResult.Updates.Item(i)
if fnCallback(objUpdateItem, Me, Param) Then Exit For
Set objUpdateItem = Nothing
Next
Set objSearcher = Nothing
Set objSearchResult = Nothing
Set fnCallback = Nothing
EnumUpdates = i
End Function
End Class
' KB2990967 and KB3035583
Function RemoveUpdateCallback(ByRef objItem, ByRef objThis, ByRef Param)
Dim i, kbArticleId
For i = 0 To objItem.KBArticleIDs.Count - 1
kbArticleId = objItem.KBArticleIDs(i)
If InStr("," & Param & ",", "," & kbArticleId & ",") Then
WSH.StdOut.Write "Found " & objItem.Title & " ... "
If objItem.IsInstalled Then
WSH.StdOut.Write "Installed"
WSH.StdOut.Write vbCrLf
objThis.AddToCollection objItem
Else
WSH.StdOut.Write "Not Installed"
WSH.StdOut.Write vbCrLf
End If
WSH.StdOut.Write " * Hiding this update now ... "
objItem.IsHidden = True
WSH.StdOut.Write " Completed" & vbCrLf
End If
Next
End Function
Sub RemoveWinUpdates()
Dim objWUMgr, objUninstallResult
Set objWUMgr = New WinUpdateMgr
WSH.Echo "Please wait for checking Windows updates ..."
objWUMgr.EnumUpdates "RemoveUpdateCallback", "Type='Software'", _
"3035583,2952664,3022345,3021917,3068708,3075249,3080149,2990214,3012973,2976978"
WSH.Echo "---------- Check Completed -----------"
If objWUMgr.GetCollectionCount() > 0 Then
WSH.Echo "Please wait for uninstall Windows updates ..."
Set objUninstallResult = objWUMgr.Uninstall()
WSH.Echo "Uninstall completed (ResultCode = " & objUninstallResult.ResultCode & ")"
If objUninstallResult.RebootRequired > 0 Then
WSH.Echo "You need restart computer for complete uninstall steps"
End If
Set objUninstallResult = Nothing
End If
WSH.Echo
Set objWUMgr = Nothing
End Sub
Sub UpdateRegistry()
Const HKLM = &H80000002
Dim strComputer, objRegistry, strKeyPath
WSH.Echo "Update registry now ..."
strComputer = "."
Set objRegistry = GetObject("winmgmts:\\" & _
strComputer & "\root\default:StdRegProv")
strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\OSUpgrade"
objRegistry.CreateKey HKLM, strKeyPath
objRegistry.SetDWORDValue HKLM, strKeyPath, "AllowOSUpgrade", 0
strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\OSUpgrade\State"
objRegistry.CreateKey HKLM, strKeyPath
objRegistry.SetDWORDValue HKLM, strKeyPath, "OSUpgradeState", 1
strKeyPath = "SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
objRegistry.CreateKey HKLM, strKeyPath
objRegistry.SetDWORDValue HKLM, strKeyPath, "DisableOSUpgrade", 1
strKeyPath = "SOFTWARE\Policies\Microsoft\Windows\Gwx"
objRegistry.CreateKey HKLM, strKeyPath
objRegistry.SetDWORDValue HKLM, strKeyPath, "DisableGwx", 1
WSH.Echo "--------- Update Completed -----------"
WSH.Echo
Set objRegistry = Nothing
End Sub
Sub DeleteAll(ByRef fso, ByVal strFileName)
Const DeleteReadonly = True
Dim objFile, objFolder, objSubFolder
If fso.FileExists(strFileName) Then
fso.DeleteFile strFileName, True
Exit Sub
End If
If fso.FolderExists(strFileName) Then
Set objFolder = fso.GetFolder(strFileName)
fso.DeleteFile(fso.BuildPath(objFolder.Path, "*")), DeleteReadonly
fso.DeleteFolder(fso.BuildPath(objFolder.Path, "*")),DeleteReadonly
For Each objFile In objFolder.Files
On Error Resume Next
objFile.Delete True
On Error GoTo 0
Next
For Each objSubFolder In objFolder.SubFolders
On Error Resume Next
objSubFolder.Delete True
On Error GoTo 0
Next
objFolder.Delete True
Set objFolder = Nothing
End If
End Sub
Sub DeleteFiles()
Const WindowsFolder = 0
Const SystemFolder = 1
WSH.Echo "Please wait for Clean up unwanted folders or files ..."
WSH.Echo "--------------------------------------"
Dim objFileSysObj, objFile, strRootDir, strFileName
Set objFileSysObj = WScript.CreateObject("Scripting.FileSystemObject")
WSH.Echo "Clean up GWX folder ..."
Set objFile = objFileSysObj.GetSpecialFolder(SystemFolder)
strFileName = objFileSysObj.BuildPath(objFile.Path, "GWX")
DeleteAll objFileSysObj, strFileName
Set objFile = Nothing
WSH.Echo "Clean up Downloaded Windows 10 folder ..."
Set objFile = objFileSysObj.GetSpecialFolder(WindowsFolder)
strRootDir = objFileSysObj.GetParentFolderName(objFile.Path)
strFileName = objFileSysObj.BuildPath(strRootDir, "$Windows.~BT")
DeleteAll objFileSysObj, strFileName
strFileName = objFileSysObj.BuildPath(strRootDir, "$Windows.~WS")
DeleteAll objFileSysObj, strFileName
Set objFile = Nothing
WSH.Echo "--------- Clean up Completed ---------"
WSH.Echo
Set objFileSysObj = Nothing
End Sub
Sub TerminateProcess(ByVal strProcName)
Const strComputer = "."
Dim objWMIService, colProcessList, objProcess
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcessList = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = '" & strProcName & "'")
For Each objProcess in colProcessList
objProcess.Terminate()
Next
End Sub
Sub KillProcesses()
WSH.Echo "Terminate process now ..."
WSH.Echo "Kill GWX in process list ..."
TerminateProcess "GWX.exe"
TerminateProcess "GWXUX.exe"
TerminateProcess "Gwxgc.exe"
TerminateProcess "Gwxconfigmanager.exe"
TerminateProcess "Gwxdetector.exe"
TerminateProcess "Gwxuxworker.exe"
WSH.Echo "-------- Terminate Completed ---------"
WSH.Echo
End Sub
Function CurrentUserIsAdmin()
Dim objNetwork, strComputer, strUser, objUser, objGroup
Set objNetwork = CreateObject("Wscript.Network")
strComputer = objNetwork.ComputerName
strUser = objNetwork.UserName
CurrentUserIsAdmin = False
Set objGroup = GetObject("WinNT://" & strComputer & "/Administrators")
For Each objUser in objGroup.Members
If objUser.Name = strUser Then
CurrentUserIsAdmin = True
Exit Function
End If
Next
End Function
' http://stackoverflow.com/questions/4765485/how-to-force-vbs-script-to-run-in-cscript-host
' http://stackoverflow.com/questions/4692542/force-a-vbs-to-run-using-cscript-instead-of-wscript
Sub ForceCScriptExecution(ByVal runAsAdmin)
On Error Resume Next
WScript.StdErr.Write(Chr(7))
If Err.Number <> 0 Then
Err.Clear
On Error GoTo 0
Dim WshShell, sh, Arg, Str
Set WshShell = WScript.CreateObject("WScript.Shell")
sh = WshShell.ExpandEnvironmentStrings("%SystemRoot%\System32\CScript.exe")
If InStr(sh,"%") = 1 Then sh="CScript.exe"
For Each Arg In WScript.Arguments
If InStr( Arg, " " ) Then Arg = """" & Arg & """"
Str = Str & " " & Arg
Next
If runAsAdmin Then
Wscript.CreateObject("Shell.Application").ShellExecute _
sh, "//NoLogo """ & _
WScript.ScriptFullName & """ " & Str, "", "runas", 1
Else
WshShell.Run sh & " //NoLogo """ & _
WScript.ScriptFullName & """ " & Str
End If
WScript.Quit()
End If
End Sub
Function GetWindowsVersion()
Dim strComputer, objWMIService
Dim colOperatingSystem, objOperatingSystem
strComputer = "."
Set objWMIService = GetObject( _
"winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\cimv2")
Set colOperatingSystem = _
objWMIService.ExecQuery ("Select * from Win32_OperatingSystem")
Dim Version
For Each objOperatingSystem in colOperatingSystem
Version = objOperatingSystem.Version
Next
GetWindowsVersion = Version
End Function
Sub Pause(strPause)
WScript.Echo (strPause)
WScript.StdIn.Read(1)
End Sub
Function VBMain()
VBMain = 0
Dim strVersion, arrVersion
strVersion = GetWindowsVersion()
arrVersion = Split(strVersion, ".")
' https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms724832(v=vs.85).aspx
If CInt(arrVersion(0)) <> 6 Or _
(CInt(arrVersion(0)) = 6 And _
( CInt(arrVersion(1)) <> 1 And _
CInt(arrVersion(1)) <> 2 And _
CInt(arrVersion(1)) <> 3 )) Then
MsgBox "This Script Must Run under Windows 7/8/8.1"
VBMain = 1
Exit Function
End If
ForceCScriptExecution True
WSH.Echo "Disable Windows 10 Upgrade Tool 1.0" & vbCrLf &_
"Written By WangYe http://wangye.org/" & vbCrLf & vbCrLf
If Not CurrentUserIsAdmin() Then
WSH.Echo "**** Error: This Script Must Run under Administrators Account ****"
Pause "Press any key to exit..."
VBMain = 1
Exit Function
End If
KillProcesses
RemoveWinUpdates
UpdateRegistry
DeleteFiles
End Function
WSH.Quit(VBMain())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment