-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwindows-services-restore.ps1
174 lines (165 loc) · 5.49 KB
/
windows-services-restore.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
<# ::
@echo off
:: Rename this file to .ps1.cmd to have this NT script wrapper take effect
set PSSCRIPT=%~dpnx0
set PSSCRIPT=%PSSCRIPT:.cmd=%
@echo on
copy /y "%~dpnx0" "%PSSCRIPT%" > nul
PowerShell.exe -ExecutionPolicy Bypass -NoLogo -NoProfile -File "%PSSCRIPT%" %*
set ERR=%ERRORLEVEL%
del /f "%PSSCRIPT%" > nul
@exit /b %ERR%
#>
#Requires -Version 6.0
Set-StrictMode -Version Latest
Set-PSDebug -Off
$VerbosePreference = "continue"
function ShowHeader()
{
<#
Reading actual Windows version from KUSER_SHARED_DATA
xref: http://terminus.rewolf.pl/terminus/structures/ntdll/_KUSER_SHARED_DATA_combined.html
xref: https://msrc-blog.microsoft.com/2022/04/05/randomizing-the-kuser_shared_data-structure-on-windows/
#>
$WinVerMaj = [System.Runtime.InteropServices.Marshal]::ReadInt32((New-Object IntPtr(0x7ffe0000)), 0x026c)
$WinVerMin = [System.Runtime.InteropServices.Marshal]::ReadInt32((New-Object IntPtr(0x7ffe0000)), 0x0270)
$WinVerBld = [System.Runtime.InteropServices.Marshal]::ReadInt32((New-Object IntPtr(0x7ffe0000)), 0x0260)
$IsAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')
Write-Output "Windows: $WinVerMaj.$WinVerMin.$WinVerBld"
Write-Output "Machine: $env:COMPUTERNAME (domain: $env:USERDOMAIN, logon server: $env:LOGONSERVER); admin: $IsAdmin`n"
}
$ServicesToRestore = @{
"ssh-agent"="Disabled";
"XboxGipSvc"="Manual";
"XblAuthManager"="Manual";
"XblGameSave"="Manual";
"XboxNetApiSvc"="Manual";
"bthserv"="Manual";
"BTAGService"="Manual";
"BthAvctpSvc"="Manual";
"Wcmsvc"="Automatic";
"WlanSvc"="Manual";
"WwanSvc"="Manual";
"TabletInputService"="Manual";
"PhoneSvc"="Manual";
"AxInstSV"="Manual";
"AJRouter"="Manual";
"autotimesvc"="Manual";
"perceptionsimulation"="Manual";
"spectrum"="Manual";
"icssvc"="Manual";
"MixedRealityOpenXRSvc"="Manual";
"WMPNetworkSvc"="Manual";
"MapsBroker"="Automatic";
"lfsvc"="Manual";
"lltdsvc"="Manual";
"MSiSCSI"="Manual";
"RemoteAccess"="Disabled";
"RetailDemo"="Manual";
"WinRM"="Manual";
"SstpSvc"="Manual";
"RasMan"="Manual";
"RemoteRegistry"="Disabled";
"PrintNotify"="Manual";
"QWAVE"="Manual";
"PeerDistSvc"="Manual";
"wlidsvc"="Manual";
"EntAppSvc"="Manual";
"NgcSvc"="Manual";
"NgcCtnrSvc"="Manual";
"NcbService"="Manual";
"SensorDataService"="Manual";
"SensrSvc"="Manual";
"SensorService"="Manual";
"ScDeviceEnum"="Manual";
"shpamsvc"="Disabled";
"AppReadiness"="Manual";
"ShellHWDetection"="Automatic";
"SSDPSRV"="Manual";
"WiaRpc"="Manual";
"stisvc"="Manual";
"wisvc"="Manual";
"OneSyncSvc"="Automatic";
"upnphost"="Manual";
"UserDataSvc"="Manual";
"UnistoreSvc"="Manual";
"WalletService"="Manual";
"WpnService"="Automatic";
"dmwappushservice"="Manual";
"RmSvc"="Manual";
"WaaSMedicSvc"="Manual";
"WPDBusEnum"="Manual";
"WSearch"="Manual"; # don't really want this ... defaults to "Automatic", but we keep it at least on "Manual"
"wuauserv"="Manual";
# User services with wildcard and without
"BluetoothUserService"="Manual";
"PrintWorkflowUserSvc"="Manual";
"BcastDVRUserService"="Manual";
"CaptureService"="Manual";
"CredentialEnrollmentManagerUserSvc"="Manual";
"PimIndexMaintenanceSvc"="Manual";
"CDPUserSvc"="Automatic";
"cbdhsvc"="Manual";
# ... wildcards ...
"BluetoothUserService_*"="Manual";
"PrintWorkflowUserSvc_*"="Manual";
"BcastDVRUserService_*"="Manual";
"CaptureService_*"="Manual";
"CredentialEnrollmentManagerUserSvc_*"="Manual";
"PimIndexMaintenanceSvc_*"="Manual";
"CDPUserSvc_*"="Automatic";
"cbdhsvc_*"="Manual"
}
function Restore-Service-StartType
{
Param(
[Parameter(Mandatory=$true)] $Service,
[Parameter(Mandatory=$true)] [string]$startuptype,
[Parameter(Mandatory=$true)] [string]$intstartuptype
)
Write-Host "Setting $($Service.Name) ($($Service.DisplayName)) to $startuptype [Current type/status: $($Service.StartType)/$($Service.Status)]"
$Service|Set-Service -StartupType $startuptype -ErrorAction SilentlyContinue -ErrorVariable SvcCfgError
if ($SvcCfgError)
{
Write-Host "`tTrying to forcibly set via registry ..."
Set-Itemproperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\$name" -Name Start -Value $intstartuptype -Type DWord -ErrorAction SilentlyContinue -ErrorVariable RegError
if($RegError)
{
Write-Host "`tERROR: Unable to set startup type in registry."
$RegError|Write-Verbose
}
}
}
function Restore-Services-StartType
{
Param(
[Parameter(Mandatory=$true)] [string]$name,
[Parameter(Mandatory=$true)] [string]$value
)
$Services = Get-Service $name -ErrorAction SilentlyContinue -ErrorVariable SvcError
if ($SvcError)
{
Write-Host "ERROR: Could not retrieve service '$name'."
$SvcError|Write-Verbose
return
}
foreach($svc in $Services)
{
$intvalue = [int]$($svc.StartType)
Restore-Service-StartType $svc $value $intvalue
}
}
$logpath = "$PSScriptRoot\windows-services-restore.log"
ShowHeader
try
{
Start-Transcript -Path $logpath -Append
foreach($entry in $ServicesToRestore.GetEnumerator())
{
Restore-Services-StartType $($entry.Name) $($entry.Value)
}
}
finally
{
Stop-Transcript
}