With cybersecurity being a hot topic throughout media, business, and IT worlds, I thought that Microsoft would have strengthened their efforts to de-bloat the Windows Server 2016 family, but that doesn’t seem to be the case.
This article is going to take a look at some of the system services found in Microsoft Windows Server 2016 and how the unneeded ones can be disable with Powershell.
Is this a Windows 10 Tablet?
A quick review of the Windows Server 2016 services might have you thinking Microsoft just copy-and-pasted source code for Windows 10 and renamed it to “Yay, server!” You’ll start seeing services that just don’t make sense for a server OS:
BlueTooth Support
GeoLocation
Sensor Monitoring Service
Touch Keyboard and Handwriting Panel Service
Wallet Service
Windows Camera Frame Server
Windows Mobile Hotspot
XBox Live Auth Manager
XBox Live Game Save
Now who doesn’t want to game on a blade with 58 CPU cores and 512GB of ram? Am-I-right?!
Microsoft does have a great article which covers every built-in Windows Server 2016 service, and whether it is recommended, “okay”, or prohibited to disable. If a service isn’t addressed here, please check out “Disabling System Services on Windows Server 2016.”
Use Windows Core?
Yes, I’m sure a lot of people would say “Well… if you’re that worried about it, use Windows Core!”
True true, there’s other slim options out there, but let’s assume you already have a bunch of servers using Desktop Experience, or not all of your admins are very comfortable with command line. One way or another, there’s going to be Windows 2016 servers out there which will have these optional services.
Powershell Script
Forewarning, I do not claim that all services listed are absolutely unneeded; please review services specified and use judgement based on your environment. Also, you can check out “Disabling System Services on Windows Server 2016.”
This script is going help disable some of these services quickly, so you will have more time to “harden” a server based on its role. Not only will there be less vulnerabilities, but hopefully less to run, leading to (hopefull)y better performance.
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 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
############################################################################ # # Script to disable unneccessary services on `Microsoft Windows Server 2016` # # Forrest McFaddin # 2018-09-01 # # Specify log path (Directory of script) $log_path = $PSScriptRoot $log_name = ("DisabledServices_"+(Get-Date -Format 'yyyy-MM-dd')+".txt") $disable_userServices = Read-Host "Do you want this script to also disable user specific services [Y/N]" # Create function to disable service if it is not already disabled and/or has no dependent services function Disable-Service($service_name){ $Service_Confirm = (Get-Service -Name $service_name -ErrorAction SilentlyContinue) IF($Service_Confirm){ IF($Service_Confirm.StartType -ne "Disabled"){ # If service isn't disabled IF($Service_Confirm.DependentServices.Count -ne 0){ # If service has dependent services return ((Get-Date -format "hh:mm:ss")+" | SKIPPED | " + $service_name + " ("+$Service_Confirm.DisplayName+")" + " | Service found to have dependents. Skipped...") }ELSE{ # If service doesn't have dependent services, disable it. $service_state = (Set-Service -Name $service_name -StartupType Disabled) return ((Get-Date -format "hh:mm:ss")+" | DISABLED | " + $service_name + " ("+$Service_Confirm.DisplayName+")" ) } }ELSE{ # IF sevice is already disabled. return ((Get-Date -format "hh:mm:ss")+" | SKIPPED | " + $service_name + " ("+$Service_Confirm.DisplayName+")" + " | Service already disabled. No actions taken.") } } } # Check Operating System $os_version = (Get-WmiObject -Class Win32_operatingSystem).Caption IF($os_version -notlike "*Server 2016*"){ Write-Output "This script is intended for Microsoft Windows Server 2016. If you continue, it's likely errors will be generated for services that don't exist on this machine." $run = Read-Host "Do you wish to continue? [Y/N]" IF($run -ne "Y"){ return } } write-output "Continuing..." # Create an array with names of services to disable. $service_disabled = @() ######################################## ######### SPECIFY SERVICES ############# ######################################## # # Bluetooth Support Service $service_disabled += "bthserv" # # Xbox Live Auth Manager $service_disabled += "XblAuthManager" # # Xbox Live Game Save $service_disabled += "XblGameSave" # $service_disabled += "dmwappushservice" # # Downloaded Maps Manager $service_disabled += "MapsBroker" # # GeoLocationService $service_disabled += "lfsvc" # # Internet Connection Sharing (ICS) $service_disabled += "SharedAccess" # # Link-Layer Topology Discovery Mapper $service_disabled += "lltdsvc" # # Microsoft Account Sign-in Assistant $service_disabled += "wlidsvc" # # Network Connection Broker $service_disabled += "NcbService" # # Phone Service $service_disabled += "PhoneSvc" # # Print Spooler #### Check if print spooler role is insalled IF((Get-WindowsFeature -Name Print-Server -ErrorAction SilentlyContinue).Installed -eq $false){ $service_disabled += "Spooler" } # # Printer Extensions and Notifications #### Check if print spooler role is insalled IF((Get-WindowsFeature -Name Print-Server -ErrorAction SilentlyContinue).Installed -eq $false){ $service_disabled += "PrintNotify" } # # Program Compatibility Assistant Service $service_disabled += "PcaSvc" # # Quality Windows Audio Video Experience $service_disabled += "QWAVE" # # Radio Management Service $service_disabled += "RmSvc" # # Data Service $service_disabled += "SensorDataService" # # Sensor Monitoring Service $service_disabled += "SensrSvc" # # Sensor Service $service_disabled += "SensorService" # # Smart Card Device Enumeration Service $service_disabled += "ScDeviceEnum" # # SSDP Discovery $service_disabled += "SSDPSRV" # # Still Image Acquisition Events $service_disabled += "WiaRpc" # # Touch Keyboard and Handwriting Panel Service $service_disabled += "TabletInputService" # # UPnP Device Host $service_disabled += "upnphost" # # Wallet Service $service_disabled += "WalletService" # # Windows Camera Frame Server $service_disabled += "FrameServer" # # Windows Image Acquisition (WIA) $service_disabled += "stisvc" # # Windows Insider Service $service_disabled += "wisvc" # # Windows Mobile Hotspot Service $service_disabled += "icssvc" # Disable all services Foreach($item in $service_disabled){ $item_action = Disable-Service -service_name $item $item_action | out-file -FilePath ($log_path+"\"+$log_name) -Append Write-Output -InputObject $item_action } # Also disable scheduled tasks for XBOX LIVE # XBLGameSaveTask try{Get-ScheduledTask -TaskName "XBLGameSaveTask" -ErrorAction SilentlyContinue | Disable-ScheduledTask (out-file -FilePath ($log_path+"\"+$log_name) -InputObject ((Get-Date -format "hh:mm:ss")+" | DISABLED | XBLGameSaveTask (Windows Scheduled Task)") -Append) }Catch{ # Unable to disable scheduled task (out-file -FilePath ($log_path+"\"+$log_name) -InputObject ((Get-Date -format "hh:mm:ss")+" | ERROR | XBLGameSaveTask (Windows Scheduled Task) | Failed to disable scheduled task.") -Append) } # XBLGameSaveTaskLogon try{Get-ScheduledTask -TaskName "XBLGameSaveTaskLogon" -ErrorAction SilentlyContinue | Disable-ScheduledTask (out-file -FilePath ($log_path+"\"+$log_name) -InputObject ((Get-Date -format "hh:mm:ss")+" | DISABLED | XBLGameSaveTaskLogon (Windows Scheduled Task)") -Append) }Catch{ # Unable to disable scheduled task (out-file -FilePath ($log_path+"\"+$log_name) -InputObject ((Get-Date -format "hh:mm:ss")+" | ERROR | XBLGameSaveTaskLogon (Windows Scheduled Task) | Failed to disable scheduled task." ) -Append) } # Disable user specific services, which are created upon login. # Reference: https://docs.microsoft.com/en-us/windows/application-management/per-user-services-in-windows IF($disable_userServices -eq "Y"){ try{ REG.EXE ADD HKLM\System\CurrentControlSet\Services\CDPUserSvc /v Start /t REG_DWORD /d 4 /f (out-file -FilePath ($log_path+"\"+$log_name) -InputObject ((Get-Date -format "hh:mm:ss")+" | DISABLED | CDPUserSvc (User Specific Service)" ) -Append) REG.EXE ADD HKLM\System\CurrentControlSet\Services\OneSyncSvc /v Start /t REG_DWORD /d 4 /f (out-file -FilePath ($log_path+"\"+$log_name) -InputObject ((Get-Date -format "hh:mm:ss")+" | DISABLED | OneSyncSvc (User Specific Service)" ) -Append) REG.EXE ADD HKLM\System\CurrentControlSet\Services\PimIndexMaintenanceSvc /v Start /t REG_DWORD /d 4 /f (out-file -FilePath ($log_path+"\"+$log_name) -InputObject ((Get-Date -format "hh:mm:ss")+" | DISABLED | PimIndexMaintenanceSvc (User Specific Service)" ) -Append) REG.EXE ADD HKLM\System\CurrentControlSet\Services\UnistoreSvc /v Start /t REG_DWORD /d 4 /f (out-file -FilePath ($log_path+"\"+$log_name) -InputObject ((Get-Date -format "hh:mm:ss")+" | DISABLED | UnistoreSvc (User Specific Service)" ) -Append) REG.EXE ADD HKLM\System\CurrentControlSet\Services\UserDataSvc /v Start /t REG_DWORD /d 4 /f (out-file -FilePath ($log_path+"\"+$log_name) -InputObject ((Get-Date -format "hh:mm:ss")+" | DISABLED | UserDataSvc (User Specific Service)" ) -Append) REG.EXE ADD HKLM\System\CurrentControlSet\Services\WpnUserService /v Start /t REG_DWORD /d 4 /f (out-file -FilePath ($log_path+"\"+$log_name) -InputObject ((Get-Date -format "hh:mm:ss")+" | DISABLED | WpnUserService (User Specific Service)" ) -Append) }Catch{ (out-file -FilePath ($log_path+"\"+$log_name) -InputObject ((Get-Date -format "hh:mm:ss")+" | ERROR | Could create registry keys to disable user specific services." ) -Append) } } |
The console will receive the output for every action: