Use powershell to configure "Use start fullscreen" setting? - powershell

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.

Related

Custom URL for toast notification buttons in registry

I trying to run a command that opens up Software Center on my machine. It works just fine if I run it in Command Prompt but not when I call it from my custom protocol handler in the registry. The main problem is that when called from the protocol handler, via a Toast button, Windows tells me I need a new app to open this.
Here is the command.
"C:\WINDOWS\CCM\ClientUX\SCClient.exe" softwarecenter:Page=Applications FilterType=0 SortType=6 View=Upcoming
Here is how I am setting up the protocol handler in registry
New-item 'HKLM:\SOFTWARE\ToastSoftwareCenter' -force
Set-itemproperty 'HKLM:\SOFTWARE\ToastSoftwareCenter' -name '(DEFAULT)' -value 'url:ToastSoftwareCenter' -force
Set-itemproperty 'HKLM:\SOFTWARE\ToastSoftwareCenter' -name 'URL Protocol' -value '' -force
New-itemproperty -path 'HKLM:\SOFTWARE\ToastSoftwareCenter' -propertytype dword -name 'EditFlags' -value 2162688
New-item 'HKLM:\SOFTWARE\ToastSoftwareCenter\Shell\Open\command' -force
Set-itemproperty 'HKLM:\SOFTWARE\ToastSoftwareCenter\Shell\Open\command' -name '(DEFAULT)' -value '"C:\WINDOWS\CCM\ClientUX\SCClient.exe" softwarecenter:Page=InstallationStatus FilterType=0 SortType=6 View=Upcoming' -force
I have tried appending these other commands on the end of the command to associate it as an exe so it wont ask anymore, but to no avail.
ftype exefile="%1" %*
assoc .exe=exefile\
The commands work when running them from a command prompt but not from the protocol handler. Am I setting it up wrong?
Thank You.
You're creating the protocol in the wrong location. It needs to be created under HKEY_CLASSES_ROOT
You also need to create the PSDrive in order to easily access that location within PowerShell.
New-PSDrive -PSProvider Registry -Root HKEY_CLASSES_ROOT -Name HKCR
New-Item 'HKCR:\ToastSoftwareCenter' -Force
Registering the Application Handling the Custom URI Scheme

Pause windows update for up to 35 days and find out until which date updates are paused, via 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:

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

Windows VM proxy aware at provisioning time

We are currently leveraging a VNet at Azure that is configured to force all traffic over our site-to-site connection to on-premise networks and then out through our corporate firewall. All HTTP/HTTPS traffic is proxied.
This is causing significant issue in that newly-provisioned VMs can not see the outside world to access necessary configuration items like Azure Extensions or even no-proxied internal IPs.
To date, I've created a perverse work-around via PowerShell where I provision the VM, bootstrap it with Chef which overrides the proxy settings in order to get to the Chef server which then configures the proxies.
But, until the user fires up Internet Explorer, it does not set the proxies so that they can be used in PowerShell. Specifically, before IE is fired up, [System.Net.GlobalProxySelection]::Select is empty. Once IE has been started, it is populated.
I also tried preconfiguring an image and sysprep'ing it, but sysprep wipes the proxy settings.
As a final step, I created a PowerShell script which I thought would set the proxies. I was going to use this script via Azure Script Extension (assuming it is on the VM by default), but I can't get it to give me the desired results.
So, my question is, how do I make a Windows 2012 R2 (and Windows 2008 R2) newly provisioned VM proxy aware so that other processes in the provisioning sequence will work (i.e., extensions like the Chef extension)?
Here is the script I created (that doesn't perform as expected):
# See: http://www.geoffchappell.com/notes/windows/ie/firstrun.htm
$regKey = 'HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings'
$proxyServerToDefine = 'http://<PROXY URI>:<PORT>'
Set-ItemProperty -path $regKey ProxyEnable -value 1
Set-ItemProperty -path $regKey ProxyServer -value $proxyServerToDefine
Set-ItemProperty -path $regKey ProxyOverride -value '137.185.235.196;137.185.235.199'
New-Item -Path 'HKLM:\\Software\\Policies\\Microsoft\\Internet Explorer' -Name 'Main' -Force # Does not exist by default
Set-ItemProperty -Path 'HKLM:\Software\Policies\Microsoft\Internet Explorer\Main' -Name DisableFirstRunCustomize -Value 1
(New-Object System.Net.WebClient).Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
The trick here was assigning both the HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings AND system account's Internet Settings.
Suggestion: Set your proxy and overrides up once, confirm that it works and then grab the registry values to use in your script.
Here's the list of values I set to make the Users and the System accounts proxy aware:
$userReg = 'HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings'
Set-ItemProperty -path $userKey ProxyEnable -value 1
Set-ItemProperty -path $userKey ProxyServer -value ''
Set-ItemProperty -path $userKey ProxyOverride -value ''
$sysReg = 'HKU:\\S-1-5-18\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings'
Set-ItemProperty -path $sysReg ProxyEnable -value 1
Set-ItemProperty -path $sysReg ProxyServer -value ''
Set-ItemProperty -path $sysReg ProxyOverride -value ''
$sysRegCon = 'HKU:\\S-1-5-18\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\Connections'
$DefaultConnectionSettings = ([byte[](0x46,0x00,...))
$SavedLegacySettings = ([byte[](0x46,0x00,...))
Set-ItemProperty -path $sysRegCon DefaultConnectionSettings -value $DefaultConnectionSettings
Set-ItemProperty -path $sysRegCon SavedLegacySettings -value $SavedLegacySettings
Hope this helps someone else more rapidly down the path...

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.