Pause windows update for up to 35 days and find out until which date updates are paused, via powershell - powershell

In Windows 10 it is possible to pause windows updates for up to 35 days using the "Windows Update - Advanced Options" settings dialog (please see screenshot).
Question 1:
How do i accomplish that via powershell or command-line ?
Question 2:
How do i find out until which date windows updates are paused via powershell or commandline? Or alternatively: How do i find out how many days are left until windows updates are resumed ?

Here is an easy way to do it in Powershell by amending the Registry:
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings' -Name 'PauseUpdatesExpiryTime' -Value "2020-07-31T00:00:00Z"
Finally to query the current setting:
Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings'| Select-Object PauseUpdatesExpiryTime
This has been tested, the only side-effect is that the date setting dropdown is greyed out in the Advanced setting page.

one-liner that does it, based on Ozymanduis's comment:
$pause = (Get-Date).AddDays(35); $pause = $pause.ToUniversalTime().ToString( "yyyy-MM-ddTHH:mm:ssZ" ); Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings' -Name 'PauseUpdatesExpiryTime' -Value $pause

Thanks Ozymanduis for the suggestion. I tried it and it worked fine.
Probably windows 10 needs the exact time format to accept the pause updates function and to work properly. However I went looking into the registery where those keys are, after pressing the pause updates function. It seems that there are other REG keys which are created during the "button press". And those are
PauseFeatureUpdatesStartTime (Where the time format is set on "now")
PauseFeatureUpdatesEndTime (Where the time format is set on "in 35 days")
PauseQualityUpdatesStartTime (Where the time format is set on "now")
PauseQualityUpdatesEndTime (Where the time format is set on "in 35 days")
So I just added those keys to the equation like this
$pause = (Get-Date).AddDays(35)
$pause = $pause.ToUniversalTime().ToString( "yyyy-MM-ddTHH:mm:ssZ" )
$pause_start = (Get-Date)
$pause_start = $pause_start.ToUniversalTime().ToString( "yyyy-MM-ddTHH:mm:ssZ" )
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings' -Name 'PauseUpdatesExpiryTime' -Value $pause
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings' -Name 'PauseFeatureUpdatesStartTime' -Value $pause_start
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings' -Name 'PauseFeatureUpdatesEndTime' -Value $pause
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings' -Name 'PauseQualityUpdatesStartTime' -Value $pause_start
Set-itemproperty -Path 'HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings' -Name 'PauseQualityUpdatesEndTime' -Value $pause
Now I hope it will really pause those updates. I remember having tried out the "pause" REG keys function couple of years ago alternatively to the "disable windows updates" function, but somehow it used to resume those updates within the grace period regardless of the date set, which was kind of annoying. I will keep you updated.
EDIT: I added the reg entries in the same ps file to avoid the autoupdate feature to start like this,
New-Item -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' -Force
New-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' -Name 'NoAutoUpdate' -PropertyType DWORD -Value 1
I do it as soon as possible when our machines are deployed to avoid the update process to begin (because if it does you're pretty much screwed) and it seems to work pretty fine now:

Related

How do I add HKCU Regkeys value for each current user in powershell script?

I want a powershell script to run each time a user login to Windows by placed in: Shell:common startup.
This script must add about 50 Regkey's in HKCU, which is setting/path for Presetfolders for a application.
I want to use Powershell and have tried this command adding the RegKey (This command needs to be repeated for each 50 regkeys!):
New-ItemProperty -Path 'HKCU:\Software\AppName' -Name 'PresetFolder' -PropertyType String -Value '$env:userprofile\Documents\AppName\Presets1' -Force
New-ItemProperty -Path 'HKCU:\Software\AppName' -Name 'PresetFolder' -PropertyType String -Value '$env:userprofile\Documents\AppName\Presets2' -Force .......
When using "$env:userprofile" instead of c:\Users\MyUserProfile\Documents\.... the -value in the RegKey will be: "$env:userprofile\Documents\NewFolder\Presets" and not as wanted: "c:\Users\MyUserProfile\Documents\NewFolder\Presets".
I need a Variable for each userprofile!
Alternatively I can after Program installation by using admin-account, I can exported all RegKey's as a .reg-file. Before using the powershell-script to merge the RegKeys everytime a user is logging in Windows, I now need to search and replace the value of the path (-Value) from AdminUserProfil-path into a variable for each user running the script.
Part of the Reg-file:
[HKEY_CURRENT_USER\Software\AppName\Version]
"HelpDocPath"="C:\Users\\AdminUserprofiles\\Documents\\AppName\\Version\\HTML Help\\en"
"ExciterCacheInstallPath"="C:\\Program Files\\AppName\\Version\\Exciter Cache"
"DSPResourceFilesInstallPath"="C:\\Program Files\\AppName\\Version/Resources"
"InstallPath"="C:\\Program Files\\AppName\\InstallFolder"
"PresetFolder"="C:\\Users\\AdminUserprofiles\\Documents\\AppName\\Version\\Presets\\Global Presets"\
Hope anyone can help?
What do I need to type for the right path, so each user will have there own path? Do I need a variable fo rusers or..?
Thank you.
Define $env:USERPROFILE as a variable so you can call it, otherwise PS will just output what you have typed, which is what is happening in this case.
$path = "$env:USERPROFILE"
New-ItemProperty -Path 'HKCU:\Software\AppName' -Name 'PresetFolder' -PropertyType String -Value '$path\Documents\AppName\Presets1' -Force

Powershell Set-MpPreference -DisableRealtimeMonitoring $true not working

To disable the Windows Defender, I am using the PowerShell (as an administrator) in Windows 10 to run the following command:
Set-MpPreference -DisableRealtimeMonitoring $true
But the real time protection is not getting disabled.
Can anyone have any idea about how to disable the real time protection programmatically?
Tamper Protection (when enabled) prevents "Set-MpPreference -DisableRealtimeMonitoring $true" from doing anything.
Although on my Windows 10 machine, the Set-MpPreference -DisableRealtimeMonitoring $true works as expected, you could try manipulating it in the registry directly:
# Windows Defender DisableRealtimeMonitoring
$regpath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender"
if (!(Test-Path $regpath -PathType Container)) {
$null = New-Item -Path $regpath -ItemType Container -Force
}
Set-ItemProperty -Path $regpath -Name "DisableRealtimeMonitoring" -Value 1 -Type DWord -Force
# restart the service
Restart-Service -Name WinDefend -Confirm:$false -Force
To turn it back on, either remove the "DisableRealtimeMonitoring" entry or set its value to DWORD 0
i used key press
ctrl + esc
type string "virus protect"
enter
tab x 4
enter
blahblah = the rest of the key presses to turn off defender and firewall and everything erlse like uninstall avast and avg lol

Use powershell to configure "Use start fullscreen" setting?

Windows 10 allows you to configure Settings > Start > Use Start full screen, I'm trying to find a way to configure this through powershell/dsc scripting/automation. I was able to find the MDM and GPO documentation (https://learn.microsoft.com/en-us/windows/configuration/windows-10-start-layout-options-and-policies) but this does not appear to apply to desktop Windows 10 Pro - powershell has no commands/cmdlets with GP* nouns.
The scripts below, inspired by the .bat-files in this article adjust the local policies and should probably work. I have tested on 10.0.16299.431 (Enterprise).
Based on the article (Created by Shawn Brink, January 24th 2015):
To force fullscreen:
$forceStartSizePath = "\Software\Policies\Microsoft\Windows\Explorer"
New-ItemProperty -Path "HKCU:$forceStartSizePath" -Name "ForceStartSize" -Value 2 -Force
New-ItemProperty -Path "HKLM:$forceStartSizePath" -Name "ForceStartSize" -Value 2 -Force
Stop-Process -name explorer
To force normal mode:
$forceStartSizePath = "\Software\Policies\Microsoft\Windows\Explorer"
New-ItemProperty -Path "HKCU:$forceStartSizePath" -Name "ForceStartSize" -Value 1 -Force
New-ItemProperty -Path "HKLM:$forceStartSizePath" -Name "ForceStartSize" -Value 1 -Force
Stop-Process -name explorer
To reset to default:
$forceStartSizePath = "\Software\Policies\Microsoft\Windows\Explorer"
Remove-ItemProperty -Path "HKCU:$forceStartSizePath" -Name "ForceStartSize"
Remove-ItemProperty -Path "HKLM:$forceStartSizePath" -Name "ForceStartSize"
Stop-Process -name explorer
Note: The last line (making explorer restart) may not desirable, but it will make sure the settings are picked up instantly. Your screen will flicker (if running local) as explorer is restarted.
Also; if parts of the registry-path is missing, you will get an error message. Use Test-Pathand New-Item to check for and create the missing part of the path.

Get Specific Recycling Time For IIS With PowerShell

I'm trying to find the specific time that my app pool is set to recycle on my server using PowerShell. I know it's set to recycle at 1 AM daily on the test server that I'm looking at. I'm running:
Get-ItemProperty -Path IIS:\AppPools\AppPool -Name recycling.periodicRestart.time
and the value that's showing is 00:00:00
For testing purposes, I attempted to run:
Set-ItemProperty -Path IIS:\AppPools\AppPool -Name recycling.periodicRestart.time -Value 3.00:00:00
I checked to see how this changed. The "Specific Time(s)" field still reads 1:00 AM, but now the "Regular Time Intervals (in minutes)" is set to 4320 minutes. So apparently I'm looking at the wrong value... Any idea how I can see the value in the "Specific Time" field?
Here you go:
Set-ItemProperty -Path IIS:\AppPools\DefaultAppPool -Name recycling.periodicRestart.schedule -Value #{value = '03:00:00'}
Get it with:
Get-ItemProperty -Path IIS:\AppPools\DefaultAppPool -Name recycling.periodicRestart.schedule.collection

Automate process of Disk Cleanup cleanmgr.exe without user intervention

I am developing a powershell script file which shall execute some disk cleanup without user intervention. The user shall not be able to configure anything.
When I run cleanmgr.exe /d c: sageset:1 a popup window appears to select files/folders to be cleaned(cleanup options).
This will create a registry entry containing the settings with the cleanup options and after this, you can run cleanmgr.exe /sagerun:1 which will actually execute the cleanup.
Is there a way to specify the cleanup options directly with powerhell/command line(without the need to manually select things to be deleted)?
The following Powershell script automates CleanMgr.exe. In this case, it removes temporary files and runs the Update Cleanup extension to purge superseded Service Pack Backup files (Windows 10 now does this automatically via a scheduled task). To automate other extensions, create a "StateFlags0001" property in the corresponding Registry key, as done in the New-ItemProperty lines. You will find the Registry key names in the "VolumeCaches" branch.
As far as being silent, this script attempts to start CleanMgr.exe in a hidden window. However, at some point CleanMgr spawns new processes which are visible and must be waited on separately.
Write-Host 'Clearing CleanMgr.exe automation settings.'
Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\*' -Name StateFlags0001 -ErrorAction SilentlyContinue | Remove-ItemProperty -Name StateFlags0001 -ErrorAction SilentlyContinue
Write-Host 'Enabling Update Cleanup. This is done automatically in Windows 10 via a scheduled task.'
New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Update Cleanup' -Name StateFlags0001 -Value 2 -PropertyType DWord
Write-Host 'Enabling Temporary Files Cleanup.'
New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Temporary Files' -Name StateFlags0001 -Value 2 -PropertyType DWord
Write-Host 'Starting CleanMgr.exe...'
Start-Process -FilePath CleanMgr.exe -ArgumentList '/sagerun:1' -WindowStyle Hidden -Wait
Write-Host 'Waiting for CleanMgr and DismHost processes. Second wait neccesary as CleanMgr.exe spins off separate processes.'
Get-Process -Name cleanmgr,dismhost -ErrorAction SilentlyContinue | Wait-Process
$UpdateCleanupSuccessful = $false
if (Test-Path $env:SystemRoot\Logs\CBS\DeepClean.log) {
$UpdateCleanupSuccessful = Select-String -Path $env:SystemRoot\Logs\CBS\DeepClean.log -Pattern 'Total size of superseded packages:' -Quiet
}
if ($UpdateCleanupSuccessful) {
Write-Host 'Rebooting to complete CleanMgr.exe Update Cleanup....'
SHUTDOWN.EXE /r /f /t 0 /c 'Rebooting to complete CleanMgr.exe Update Cleanup....'
}
The PowerShell logic provided below is dynamic and ready for use or automation with the sageset options all being selected and no user interaction being required. This was inspired by multiple answers and comments from this post.
Note: I've adjusted for my needs and used successfully without any issues on multiple remote and local Windows 10 systems in particular.
Run on Local System
Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\*' | % {
New-ItemProperty -Path $_.PSPath -Name StateFlags0001 -Value 2 -PropertyType DWord -Force
};
Start-Process -FilePath CleanMgr.exe -ArgumentList '/sagerun:1' ##-WindowStyle Hidden
Run on Remote System
$cred = Get-Credential "domain\administrator";
Invoke-Command -ComputerName "computer004" {
Process {
Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\*' | % {
New-ItemProperty -Path $_.PSPath -Name StateFlags0001 -Value 2 -PropertyType DWord -Force
};
Start-Process -FilePath CleanMgr.exe -ArgumentList '/sagerun:1' -WindowStyle Hidden
}
} -AsJob -Credential $cred
Supporting Resources
cleanmgr
Invoke-Command
-AsJob
Run the command as a background job on a remote computer.
Use this parameter to run commands that take an extensive time to complete.
Get-Credential
Automate process of Disk Cleanup cleanmgr.exe without user intervention
Creating a Disk Cleanup Handler
You can use cleanmgr /verylowdisk to silently automate all the cleanup steps.
The only solution I found is to manually set the registry values like this:
...
#Set StateFlags0012 setting for each item in Windows 8.1 disk cleanup utility
if (-not (get-itemproperty -path 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Active Setup Temp Folders' -name StateFlags0012 -ErrorAction SilentlyContinue)) {
set-itemproperty -path 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Active Setup Temp Folders' -name StateFlags0012 -type DWORD -Value 2
set-itemproperty -path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\BranchCache' -name StateFlags0012 -type DWORD -Value 2
set-itemproperty -path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Downloaded Program Files' -name StateFlags0012 -type DWORD -Value 2
...
see full example
I ran into the same issue. Researching the possible ways, I have found the following:
http://stealthpuppy.com/cleaning-up-and-reducing-the-size-of-your-master-image/
It shows how to create the sageset registry settings via cmd. You can then use the sagerun:# cmd. I have not tried it via script yet, but have validated that it works...
This script will get all the Volume Caches from the Registry, enable them to be cleaned and run the CLEANMGR.EXE for all caches.
$VolumeCachesRegDir = "hklm:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches"
$CacheDirItemNames = Get-ItemProperty "$VolumeCachesRegDir\*" | select -ExpandProperty PSChildName
$CacheDirItemNames |
%{
$exists = Get-ItemProperty -Path "$VolumeCachesRegDir\$_" -Name "StateFlags6553" -ErrorAction SilentlyContinue
If (($exists -ne $null) -and ($exists.Length -ne 0))
{
Set-ItemProperty -Path "$VolumeCachesRegDir\$_" -Name StateFlags6553 -Value 2
}
else
{
New-ItemProperty -Path "$VolumeCachesRegDir\$_" -Name StateFlags6553 -Value 0 -PropertyType DWord
}
}
Start-Sleep -Seconds 3
Write-Host 'Running CleanMgr.exe...'
Start-Process -FilePath CleanMgr.exe -ArgumentList '/sagerun:65535' -WindowStyle Hidden -PassThru
cls
Running CleanMgr.exe in a powershell script or by itself seems to work fine as long as you run it locally with an account that has local admin rights. But try running it remotely via any remote management tool or remote scripting command (Invoke-Command) and it does not run. You might see the process running on the remote system but it doesn't seem to cleanup anything and the process never ends. I would be interested if anyone has been able to get cleanmgr.exe to run remotely without any user interaction. E.G. ConfigMgr Right Click Tools, ConfigMgr App or PKG, Task Scheduler.