Skip to content

Instantly share code, notes, and snippets.

@1mm0rt41PC
Forked from srz-zumix/WindowsUpdate.ps1
Last active October 13, 2022 12:01
Show Gist options
  • Save 1mm0rt41PC/6f7d2e2ca5d9e0815adc8aece2c8b9d1 to your computer and use it in GitHub Desktop.
Save 1mm0rt41PC/6f7d2e2ca5d9e0815adc8aece2c8b9d1 to your computer and use it in GitHub Desktop.
WindowsUpdate powershell
$x=get-date
# Condition d'execution
if( $x.Day -lt 2 ){
Write-Host "Update not allowed the 1 and 2 of each month"
exit
}
if( $x.DayOfWeek -eq [System.DayOfWeek]::Monday ){
Write-Host "Update not allowed Monday"
exit
}
$RebootAllowed=$true
if( -not(2 -le $x.Hour -and $x.Hour -le 4) ){
Write-Host "Reboot allowed only between 02:00AM <=> 04:00AM"
$RebootAllowed=$false
}
Write-Host "--- Cleaning locked update ---"
net.exe stop wuauserv
net.exe stop bits
net.exe stop appidsvc
net.exe stop cryptsvc
sc.exe config cryptsvc start= auto
rm -Recurse -Force $env:systemroot\SoftwareDistribution\* 2> $null
rm -Recurse -Force $env:systemroot\System32\Catroot2\* 2> $null
rm -Recurse -Force "$($env:ProgramData)\Application Data\Microsoft\Network\Downloader\qmgr*.dat" 2> $null
DISM.exe /Online /Cleanup-image /Restorehealth
net.exe start cryptsvc
net.exe start appidsvc
net.exe start bits
net.exe start wuauserv
REGSVR32 cryptdlg.dll /s
REGSVR32 cryptui.dll /s
REGSVR32 dssenh.dll /s
REGSVR32 gpkcsp.dll /s
REGSVR32 initpki.dll /s
REGSVR32 mssip32.dll /s
REGSVR32 sccbase.dll /s
REGSVR32 softpub.dll /s
REGSVR32 slbcsp.dll /s
REGSVR32 rsaenh.dll /s
REGSVR32 winhttp.dll /s
REGSVR32 wintrust.dll /s
function Test-RegistryKey($Key)
{
return ((Get-Item -Path $Key -ErrorAction Ignore) -and $true);
}
function Test-RegistryValue($Key, $Value)
{
return ((Get-ItemProperty -Path $Key -Name $Value -ErrorAction Ignore) -and $true);
}
function Test-RegistryValueNotNull($Key, $Value)
{
return (($regVal = Get-ItemProperty -Path $Key -Name $Value -ErrorAction Ignore) -and $regVal.($Value));
}
function RebootRequired()
{
$tests = @(
{ Test-RegistryKey -Key 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending' }
{ Test-RegistryKey -Key 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootInProgress' }
{ Test-RegistryKey -Key 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired' }
{ Test-RegistryKey -Key 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\PackagesPending' }
{ Test-RegistryKey -Key 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\PostRebootReporting' }
{ Test-RegistryValueNotNull -Key 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Value 'PendingFileRenameOperations' }
{ Test-RegistryValueNotNull -Key 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Value 'PendingFileRenameOperations2' }
{
# Added test to check first if key exists, using "ErrorAction ignore" will incorrectly return $true
'HKLM:\SOFTWARE\Microsoft\Updates' | Where-Object { test-path $_ -PathType Container } | ForEach-Object {
if(Test-Path "$_\UpdateExeVolatile" ){
(Get-ItemProperty -Path $_ -Name 'UpdateExeVolatile' | Select-Object -ExpandProperty UpdateExeVolatile) -ne 0
}else{
$false
}
}
}
{ Test-RegistryValue -Key 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce' -Value 'DVDRebootSignal' }
{ Test-RegistryKey -Key 'HKLM:\SOFTWARE\Microsoft\ServerManager\CurrentRebootAttempts' }
{ Test-RegistryValue -Key 'HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon' -Value 'JoinDomain' }
{ Test-RegistryValue -Key 'HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon' -Value 'AvoidSpnSet' }
{
# Added test to check first if keys exists, if not each group will return $Null
# May need to evaluate what it means if one or both of these keys do not exist
( 'HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName' | Where-Object { test-path $_ } | % { (Get-ItemProperty -Path $_ ).ComputerName } ) -ne
( 'HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName' | Where-Object { Test-Path $_ } | % { (Get-ItemProperty -Path $_ ).ComputerName } )
}
{
# Added test to check first if key exists
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Services\Pending' | Where-Object {
(Test-Path $_) -and (Get-ChildItem -Path $_) } | ForEach-Object { $true }
}
)
foreach ($test in $tests)
{
Write-Verbose "Running scriptblock: [$($test.ToString())]"
if (& $test) {
$true
break
}
}
}
Write-Host "--- Running Windows Update ---"
Write-Host "Searching for updates..."
$updateSession = new-object -com "Microsoft.Update.Session"
$updateSearcher = $updateSession.CreateupdateSearcher()
$searchResult = $updateSearcher.Search("IsInstalled=0 and Type='Software' and AutoSelectOnWebSites=1")
Write-Host "List of applicable items on the machine:"
if( $searchResult.Updates.Count -eq 0 ){
Write-Host "There are no applicable updates."
if( RebootRequired -and $RebootAllowed ){
Write-Host "Reboot system now !!"
shutdown.exe /r /t 0
}
Exit
}
$downloadReq = $False
$i = 0
foreach ($update in $searchResult.Updates)
{
$i++
if( $update.IsDownloaded ){
Write-Host $i">" $update.Title "(downloaded)"
}else{
$downloadReq = $true
Write-Host $i">" $update.Title "(not downloaded)"
}
}
if ( $downloadReq ) {
Write-Host "Creating collection of updates to download..."
$updatesToDownload = new-object -com "Microsoft.Update.UpdateColl"
foreach ($update in $searchResult.Updates)
{
$updatesToDownload.Add($update) | out-null
}
Write-Host "Downloading updates..."
$downloader = $updateSession.CreateUpdateDownloader()
$downloader.Updates = $updatesToDownload
$downloader.Download()
Write-Host "List of downloaded updates:"
$i = 0
foreach ($update in $searchResult.Updates)
{
$i++
if( $update.IsDownloaded ){
Write-Host $i">" $update.Title "(downloaded)"
}else{
Write-Host $i">" $update.Title "(not downloaded)"
}
}
}else{
Write-Host "All updates are already downloaded."
}
$updatesToInstall = new-object -com "Microsoft.Update.UpdateColl"
Write-Host "Creating collection of downloaded updates to install..."
foreach ($update in $searchResult.Updates)
{
if ( $update.IsDownloaded ) {
$updatesToInstall.Add($update) | out-null
}
}
if ( $updatesToInstall.Count -eq 0 ){
Write-Host "Not ready for installation."
}else{
Write-Host "Installing" $updatesToInstall.Count "updates..."
$installer = $updateSession.CreateUpdateInstaller()
$installer.Updates = $updatesToInstall
$installationResult = $installer.Install()
if( $installationResult.ResultCode -eq 2 ){
Write-Host "All updates installed successfully."
}else{
Write-Host "Some updates could not installed."
}
if ( $installationResult.RebootRequired ) {
Write-Host "One or more updates are requiring reboot."
if( RebootRequired -and $RebootAllowed ){
Write-Host "Reboot system now !!"
shutdown.exe /r /t 0
}
}else{
Write-Host "Finished. Reboot are not required."
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment