Servers Automation

Managing Windows Server Core Headless with Windows Admin Center and PowerShell

The first time an engineer RDPs into a Windows Server Core box, the reaction is always the same: a black screen, one cmd.exe window, no Start menu, no explorer.exe, no Server Manager. It feels broken. It is not — it is the most operationally correct way to run Windows Server, and the missing desktop is the point. Server Core ships roughly half the binaries of the Desktop Experience install, takes a materially smaller slice of the monthly cumulative-update churn, and removes an entire class of “someone clicked the wrong checkbox in a wizard” misconfiguration. What it costs you is the muscle memory of pointing and clicking: every task you used to do in a window — install a role, read the event log, format a disk, change an IP — still exists, but now it is a cmdlet, a remote console, or a browser tab pointed at Windows Admin Center (WAC).

This article is the working model for administering a headless fleet end to end. You bring a box up with sconfig (or an unattend file), lock down WinRM and move PowerShell remoting onto an HTTPS listener, drive day-two work three ways — native PowerShell, the classic RSAT / Server Manager MMC tools pointed remotely, and a hardened Windows Admin Center gateway — and keep the whole thing patched and hardened without ever installing a GUI. We cover the workflows that trip people up specifically because the GUI is gone: drivers with pnputil instead of Device Manager, event logs as an object pipeline instead of Event Viewer, storage with the Storage module instead of Disk Management, and the Features on Demand trick that lets a stubborn app that “needs the GUI” run on Core anyway.

Everything here targets Windows Server 2019 / 2022 / 2025, domain-joined unless stated otherwise. One thing to internalise first: the Server Core install option is chosen at setup and is a one-way door — you cannot convert a running Core box to Desktop Experience (that in-place switch was removed after Server 2012 R2). Pick it deliberately, provision it as cattle, and never plan to “add the GUI later.”

What problem this solves

Most Windows Server roles do not need an interactive desktop. A domain controller, a DNS/DHCP server, a file server, a Hyper-V host, an IIS worker — none of them require a human sitting at explorer.exe. Yet teams keep deploying the Desktop Experience “to be safe,” then inherit a patch surface, a reboot cadence, and a memory/disk footprint they never needed. That install carries Edge, the shell, media components, Paint, and dozens of services that run by default — every one a binary that can carry a CVE you are now obligated to patch and reboot for.

What breaks without the headless skill set is not the servers — it is the operators. A team that has only administered Windows through wizards treats a Core box as an emergency: they RDP in, stare at the black screen, and either bolt the GUI onto the next build or quietly standardise on Desktop Experience, losing all the benefit. The fix is not to avoid Core; it is to learn the three remote surfaces (PowerShell remoting, RSAT/MMC, Windows Admin Center) so well that the missing local GUI is a non-event. Once you administer servers remotely and declaratively — which you should at scale anyway — Core simply forces the good habit and removes the temptation to hand-edit a production box.

Who hits this: anyone running a Windows Server estate past a handful of machines, anyone building golden images at scale, anyone on constrained edge hardware where the extra GUI footprint matters, and any security team shrinking attack surface and reboot count across a fleet. The payoff is measurable — fewer binaries, patches, reboots, and GUI-driven mistakes — for the price of a weekend learning the remote workflows this article lays out.

To frame the whole surface before the deep dive, here is what changes when the desktop disappears, and where the replacement lives:

GUI tool you lose Headless replacement Runs from Notes
Server Manager (local dashboard) sconfig, then PowerShell + remote Server Manager Local console / admin workstation Server Manager still works — pointed at the Core box remotely
Server Manager “Add Roles” wizard Install-WindowsFeature Remote PowerShell One line; add -IncludeManagementTools
Device Manager pnputil, Get-PnpDevice Local or remote Drivers on the live OS, fully scriptable
Event Viewer Get-WinEvent Remote PowerShell / WAC Object pipeline; filter across many nodes
Disk Management Storage module (Get-Disk, New-Partition) Remote PowerShell / WAC End-to-end init → partition → format
Performance Monitor Get-Counter Remote PowerShell / WAC Live counters without perfmon
Local Users and Groups (lusrmgr.msc) Get-LocalUser, RSAT via computer mgmt Remote MMC / PowerShell Domain accounts via AD tools
Services (services.msc) Get-Service / Set-Service, RSAT Remote PowerShell / MMC JEA-friendly for delegated restart
Certificates MMC Cert:\ PSDrive, certlm.msc remote Remote PowerShell / MMC Manage LocalMachine\My etc.
The whole desktop, at a glance Windows Admin Center Any browser GUI-equivalent over the same WinRM plumbing

Learning objectives

By the end of this article you can:

Prerequisites & where this fits

You should be comfortable at a PowerShell prompt (variables, the pipeline, Get-Help), understand the basics of Active Directory (a domain, a DC, an OU, a computer account, Kerberos vs NTLM at a high level), and know what a certificate and an EKU are. Familiarity with TCP ports and the Windows firewall helps, as does having administered some Windows Server before — this is not a “what is a server” article.

This sits in the Windows Server operations track and is upstream of almost everything else in it. Once you can run a headless box, the role-specific deep dives follow naturally: Configuration Management for Windows Server with PowerShell DSC and Ansible is how you make the configuration you set here declarative and enforced; Hardening Windows Server and Building a Reliable WSUS Patch Pipeline is how you patch the fleet you just made leaner; and Eliminating Static Service Credentials with gMSA and Windows LAPS is how the service accounts on these boxes stop being a liability. If your Core boxes are domain controllers, Building an AD DS Forest the Right Way: Deployment, FSMO, and a Tiered Admin Model is the design they slot into. Managing the same fleet from the cloud is Onboarding Servers to Azure Arc: Connected Machine Agent, Service Principals & Bulk Enrollment.

A quick map of the three management surfaces, because choosing the right one per task is half the skill:

Surface What it is Best for Where it runs Auth
sconfig Menu wrapper over local commands First-boot bring-up, break-glass at the console Local Core console only Interactive local logon
Native PowerShell remoting Enter-PSSession / Invoke-Command over WinRM Automation, fleet fan-out, scripted day-two Admin workstation → node(s) Kerberos / cert / NTLM
RSAT + MMC / Server Manager Classic Windows admin tools, pointed remotely Familiar GUI muscle memory; one box at a time Admin workstation (Win10/11 or mgmt server) Kerberos
Windows Admin Center Browser-based, gateway-hosted console GUI-equivalent for a team; dashboards; roles Gateway server → nodes; browser to gateway Kerberos SSO / Entra ID (via Arc)

Core concepts

A few mental models make every later section obvious.

Server Core is a smaller Windows, not a crippled one. It runs the same kernel, drivers, roles, and PowerShell as Desktop Experience. What it omits is the presentation layer: explorer.exe, the MMC snap-in hosts, Edge, media, and the GUI-only consoles. Because those are absent, so are their servicing components — which is why the patch and reboot footprint shrinks. Everything a role does is present; only the way you look at it locally changed.

You administer it from somewhere else. The design assumption is that the box has no human at its console after provisioning; all three surfaces above are remote-first. Even Windows Admin Center, which looks like a local console, is a web app on a gateway server that reaches your nodes over WinRM — no agent on the managed node. Your management plane is centralised, auditable, and does not require RDP to every box.

WinRM is the transport under almost everything. WinRM (Windows Remote Management), Microsoft’s WS-Management implementation, is the pipe — PowerShell remoting and Windows Admin Center both ride it. It listens on HTTP port 5985 and HTTPS port 5986. In a domain, Kerberos authenticates and encrypts the payload even over the HTTP listener, so “HTTP” here is not plaintext — but you still move to HTTPS (5986) for uniformity, for non-domain and cross-forest hops, and so tooling negotiates TLS the same way everywhere.

The GUI tools didn’t die — they moved to your workstation. RSAT (Remote Server Administration Tools) is the package of MMC consoles and PowerShell modules that lets a Windows 10/11 client (or management server) manage remote servers. ADUC, DNS Manager, DHCP, Failover Cluster Manager, Hyper-V Manager — all run on your desktop and connect to the Core box. You never lost Event Viewer; you lost the ability to run it on the server locally. Run it on your workstation, point it at the server, done.

Features on Demand bridge the app-compat gap. Some third-party software links against GUI DLLs (mmc.exe, shell parts, MDAC/OLE components) that Core omits, and refuses to install or run. Rather than reach for Desktop Experience, you add the Server Core App Compatibility Feature on Demand — an optional payload that restores those specific components (and tools like mmc.exe, perfmon.exe, Event Viewer, and Explorer bits) without turning the box into a full desktop. It is the pressure-release valve that keeps you on Core.

The vocabulary in one table

Pin down every moving part before the deep sections; the glossary at the end repeats these for lookup.

Term One-line definition Where it lives Why it matters headless
Server Core Windows Server install option with no desktop shell Chosen at setup (one-way) The whole premise; smaller, leaner, patched less
Desktop Experience Full-GUI install option Chosen at setup The thing you are deliberately not using
sconfig Text-menu wrapper over config commands Runs at the local console First-boot bring-up without memorising cmdlets
WinRM WS-Man remote-management service Service on every node Transport for remoting and WAC
PowerShell remoting Running commands on a remote box over WinRM Enter-PSSession/Invoke-Command Primary automation surface
RSAT Remote admin tools (MMC + modules) On your Win10/11 workstation Classic GUI, pointed at the server
Windows Admin Center (WAC) Browser console served by a gateway Gateway server + browser Team-friendly GUI over WinRM
JEA Just Enough Administration — constrained endpoints Session config on the node Delegate ops without full admin
Features on Demand (FoD) Optional on-demand OS payloads Added post-install App-compat without Desktop Experience
RSAT tools = MMC snap-ins ADUC, DNS, DHCP, Hyper-V Manager, etc. Workstation Manage roles you can’t see locally
Unattend.xml Answer file for hands-off setup Applied at install/sysprep Repeatable, no-console provisioning

Why Server Core: attack surface, patching, and footprint

The argument for Server Core is engineering, not aesthetics. Three axes matter.

Attack surface. Every component you do not install cannot carry a vulnerability you must patch, nor be a foothold for an attacker. Server Core omits the shell (explorer.exe), Edge, Media Player and codecs, the browser stack, and dozens of GUI services and listeners. Fewer running services means fewer open ports and processes to compromise; fewer binaries means fewer CVEs land on your monthly plate at all.

Patch and reboot footprint. Cumulative updates ship fixes across the OS. If a month’s update fixes something in the browser, shell, or a media component, a Core box that lacks that component does not need to apply (or reboot for) that portion. Over a fleet and a year, that is real maintenance-window time recovered and change-risk avoided. The precise number varies month to month — the mechanism is deterministic: absent components generate no servicing.

Disk and memory footprint. A Core install is meaningfully smaller on disk and boots with a smaller working set. On one VM that is a rounding error; across hundreds of VMs, or on constrained edge hardware, the aggregate disk saved and memory freed per host add up to fewer or cheaper hosts.

The trade is that local administration collapses to a single PowerShell window — fine, because at scale you administer remotely and declaratively anyway. The honest comparison:

Dimension Server Core Desktop Experience Practical impact
Local GUI None (one console) Full shell + MMC Core forces remote/declarative admin
Installed binaries ~Half Full Fewer CVEs, smaller patch surface
Monthly reboot exposure Lower (absent components) Higher Recovered maintenance-window time
Disk footprint Smaller Larger (several GB more) Matters at fleet/edge scale
RDP experience Black screen, one cmd window Full desktop Not a problem once you manage remotely
App compatibility Most server workloads; FoD for the rest Everything, including GUI installers Rare vendor GUI-installer dependency
Convertible to the other option No (one-way) No Choose deliberately at setup
Right for… DC, DNS/DHCP, file, Hyper-V, IIS, middleware GUI-only third-party apps, RDS session hosts Match install option to workload

When to pick which, as a decision table:

If the workload is… Choose Because
Domain controller / DNS / DHCP Server Core No local GUI needed; smallest surface for a Tier-0 asset
File server / DFS / scale-out Server Core Storage + shares are fully manageable headless
Hyper-V host / S2D node Server Core Recommended; less to patch on the hypervisor
IIS / .NET / most middleware Server Core Install-WindowsFeature + remote IIS management
App with a hard GUI-installer dependency Core + FoD, or Desktop as last resort Try App Compatibility FoD before conceding the GUI
Remote Desktop Session Host (interactive desktops) Desktop Experience Users literally need the desktop
A vendor appliance that mandates full GUI and refuses support otherwise Desktop Experience (and push the vendor) Support contract trumps preference

The reflex “install the GUI to be safe” is the expensive default. You inherit a patch surface and reboot cadence you did not need, on every box, forever. Default to Core, keep the App Compatibility FoD in your back pocket, and reserve Desktop Experience for the genuine session-host and hard-GUI-installer cases.

Initial configuration with sconfig and unattended provisioning

On first boot, Server Core drops you into a console with sconfig available — a text-menu wrapper over the same commands you would otherwise script. It is genuinely useful for a one-off bring-up or break-glass at the console, and nothing else. In Server 2022/2025 sconfig is a PowerShell script (it launches PowerShell); on older builds it is a .cmd. The menu:

sconfig
 1) Domain/Workgroup                     8) Network Settings
 2) Computer Name                        9) Date and Time
 3) Add Local Administrator             10) Telemetry settings
 4) Configure Remote Management         11) Windows Activation
 5) Windows Update Settings             12) Log Off User
 6) Download and Install Updates        13) Restart Server
 7) Remote Desktop                      14) Shut Down Server
                                        15) Exit to command line

The options you actually use at first boot, and the cmdlet each wraps (so you can script it instead):

sconfig option What it does Underlying cmdlet / command
2) Computer Name Rename the server (needs reboot) Rename-Computer -NewName <name> -Restart
1) Domain/Workgroup Join a domain or workgroup Add-Computer -DomainName <dom> -Credential ...
8) Network Settings Static IP / DNS servers New-NetIPAddress, Set-DnsClientServerAddress
4) Configure Remote Management Enable/allow WinRM + ping Enable-PSRemoting, firewall rules
7) Remote Desktop Allow RDP (to the console) Set-ItemProperty on Terminal Server keys
6) Download and Install Updates Trigger Windows Update UsoClient / PSWindowsUpdate module
5) Windows Update Settings Auto/manual update policy Registry / policy
11) Windows Activation Activate / set KMS key slmgr

Beyond a lab, do not hand-drive sconfig. Bake configuration into an unattend.xml so the box arrives named, addressed, and domain-joined with zero console interaction. Select the Core image in the Microsoft-Windows-Setup pass, and set identity in the specialize pass:

<settings pass="specialize">
  <component name="Microsoft-Windows-Shell-Setup"
             processorArchitecture="amd64"
             language="neutral"
             xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
    <ComputerName>SRV-CORE-01</ComputerName>
  </component>
  <component name="Microsoft-Windows-UnattendedJoin"
             processorArchitecture="amd64" language="neutral">
    <Identification>
      <JoinDomain>corp.example.com</JoinDomain>
      <Credentials>
        <Domain>corp.example.com</Domain>
        <Username>svc-domainjoin</Username>
        <Password>__INJECTED_AT_DEPLOY__</Password>
      </Credentials>
    </Identification>
  </component>
</settings>

Never commit join credentials to the unattend file in source control. Inject them at deploy time from your secrets store (a CI variable group, a vault, or an offline-domain-join blob). For a truly credential-free join, use djoin /provision to generate a blob on a DC and reference it from <OfflineIdentification> in the answer file. For golden images, run sysprep /oobe /generalize /unattend:unattend.xml so each clone gets a unique SID and machine identity.

To configure an already-running box from another machine, PowerShell beats sconfig. Set a static IP, point DNS at your domain controllers, and join the domain — all remotely if WinRM is up, or at the local console for the very first hop:

# Static IP + DNS (run at the console on first boot, or remotely once WinRM works)
New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress 10.20.0.21 `
  -PrefixLength 24 -DefaultGateway 10.20.0.1
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses 10.20.0.10,10.20.0.11

# Rename and join in one reboot
Rename-Computer -NewName "SRV-CORE-01"
Add-Computer -DomainName corp.example.com -Credential (Get-Credential) -Restart

Find the interface alias first if you are not sure of it — Get-NetAdapter lists them. A common first-boot gotcha: the default interface is often named Ethernet but can be Ethernet0/Ethernet 2 on some hypervisors, and using the wrong alias silently fails.

Enabling and securing PowerShell remoting and WinRM over HTTPS

In a domain, Enable-PSRemoting is effectively already done — WinRM runs and the firewall rule is open for the domain profile out of the box on Windows Server. The real work is moving off the default HTTP listener (port 5985) to an authenticated, encrypted HTTPS listener (port 5986) backed by a real certificate, then closing the HTTP path.

Kerberos already encrypts PowerShell remoting traffic on a domain HTTP listener, so HTTP-in-domain is not plaintext — this is a common misconception. You still want HTTPS for non-domain endpoints, for cross-forest and workgroup management, and so WAC and other tooling can negotiate TLS uniformly. Standardise on 5986; keep 5985 only if a specific tool requires it, and even then scope it tightly.

First, get a certificate with the server’s FQDN in the subject (or a SAN) and the Server Authentication EKU. With an enterprise CA, request it from the host itself:

# Request a Server Authentication cert from an enterprise CA (WebServer template)
Get-Certificate -Template "WebServer" `
  -DnsName "srv-core-01.corp.example.com" `
  -CertStoreLocation Cert:\LocalMachine\My

Then create the HTTPS listener bound to that certificate’s thumbprint and open the firewall for 5986:

$cert = Get-ChildItem Cert:\LocalMachine\My |
  Where-Object { $_.Subject -match "srv-core-01" } | Select-Object -First 1

New-Item -Path WSMan:\localhost\Listener -Transport HTTPS -Address * `
  -HostName "srv-core-01.corp.example.com" `
  -CertificateThumbPrint $cert.Thumbprint -Force

New-NetFirewallRule -DisplayName "WinRM HTTPS (5986)" -Direction Inbound `
  -Protocol TCP -LocalPort 5986 -Action Allow

Once HTTPS works fleet-wide, disable the HTTP listener so nothing silently falls back to it, and harden the WinRM service to reject Basic auth and unencrypted traffic:

# Remove the HTTP listener AFTER confirming HTTPS connectivity end to end
Get-ChildItem WSMan:\localhost\Listener |
  Where-Object { $_.Keys -contains "Transport=HTTP" } |
  Remove-Item -Recurse

Set-Item WSMan:\localhost\Service\AllowUnencrypted $false
Set-Item WSMan:\localhost\Service\Auth\Basic       $false

The WinRM authentication and transport settings, what each does, and the secure value:

WinRM setting (WSMan:\localhost\...) Controls Default Secure value Note
Service\AllowUnencrypted Allow unencrypted traffic $false $false Keep off; never enable to “make it work”
Service\Auth\Basic Basic (username/password) auth $false $false Sends creds; disable
Service\Auth\Kerberos Kerberos auth $true $true The domain default; keep on
Service\Auth\Negotiate Negotiate (Kerberos→NTLM) $true $true (domain) NTLM fallback for non-Kerberos
Service\Auth\Certificate Client-certificate auth $false $true for workgroup Enables cert-based auth to non-domain nodes
Service\Auth\CredSSP Credential delegation (double-hop) $false Prefer off Use RBCD/resource-based delegation instead
Client\TrustedHosts Hosts to trust without Kerberos empty Named FQDNs only Never *
Listener Transport=HTTP (5985) Cleartext-capable listener present Removed in prod Remove after HTTPS proven
Listener Transport=HTTPS (5986) TLS listener absent Present, CA-issued cert The standard target

Verify the connection from your admin workstation before you rely on it. Test-WSMan confirms the listener answers; Enter-PSSession proves end-to-end auth over TLS:

Test-WSMan -ComputerName srv-core-01.corp.example.com -UseSSL
Enter-PSSession -ComputerName srv-core-01.corp.example.com -UseSSL -Credential (Get-Credential)

For a non-domain / workgroup node, there is no Kerberos to provide mutual authentication, so you must explicitly trust the host by FQDN and use HTTPS (or client-certificate auth). Scope TrustedHosts to named hosts — never *:

# On the admin/management host — enumerate specific FQDNs, never use '*'
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "edge-core-09.dmz.example.com" -Concatenate

Delegated administration with Just Enough Administration (JEA)

The mistake most teams make on headless fleets is granting operators full local admin “just to restart a service.” JEA (Just Enough Administration) fixes this and is more valuable on Core than anywhere else, because there is no local GUI to fall back on — the JEA endpoint is the interface an operator gets. JEA exposes a constrained PowerShell endpoint where the user runs as a temporary virtual account with only the cmdlets you whitelist, and every command is transcribed to disk.

JEA has two artifacts: a role capability file (.psrc) defining what is allowed, and a session configuration file (.pssc) mapping AD groups to roles. Build the role first:

# On the managed node: scaffold the module + role capability
$module = "$env:ProgramFiles\WindowsPowerShell\Modules\OpsRoles"
New-Item "$module\RoleCapabilities" -ItemType Directory -Force | Out-Null

New-PSRoleCapabilityFile -Path "$module\RoleCapabilities\ServiceOperator.psrc" `
  -VisibleCmdlets 'Restart-Service','Get-Service','Get-WinEvent',
                  @{ Name='Stop-Service'; Parameters=@{ Name='Name'; ValidateSet='Spooler','W3SVC' } }

That ValidateSet is the point: a service operator may stop only Spooler or W3SVC — not WinRM, not the cluster service. Now bind the role to an AD group and register it as a constrained endpoint:

New-PSSessionConfigurationFile -Path .\JeaServiceOps.pssc `
  -SessionType RestrictedRemoteServer `
  -RunAsVirtualAccount `
  -TranscriptDirectory "C:\JEA-Transcripts" `
  -RoleDefinitions @{ 'CORP\ServiceOperators' = @{ RoleCapabilities = 'ServiceOperator' } }

Register-PSSessionConfiguration -Name "ServiceOps" `
  -Path .\JeaServiceOps.pssc -Force

A member of CORP\ServiceOperators connects to the constrained endpoint and can do exactly what the role allows and nothing else — Get-Command returns only the whitelisted cmdlets, whoami shows the virtual account, and Stop-Service -Name WinRM is rejected. Windows Admin Center can also target a JEA endpoint, so the browser experience inherits the same guardrails:

Enter-PSSession -ComputerName srv-core-01.corp.example.com -UseSSL `
  -ConfigurationName "ServiceOps" -Credential (Get-Credential)

The JEA session-configuration knobs that matter most:

.pssc setting What it does Typical value Why
SessionType Base language mode of the endpoint RestrictedRemoteServer Locks the session to no-language + visible cmdlets
RunAsVirtualAccount Run commands as an ephemeral admin identity $true Operator never holds standing admin
RunAsVirtualAccountGroups Scope the virtual account’s group membership e.g. specific role group Least privilege for the ephemeral account
RoleDefinitions Map AD groups → role capabilities @{ 'CORP\Grp' = @{ RoleCapabilities='...' } } The delegation itself
TranscriptDirectory Where every session is recorded C:\JEA-Transcripts Audit trail; ship to SIEM
LanguageMode (implied) PowerShell language restriction NoLanguage (via type) Blocks arbitrary script

Managing roles, features, and drivers without a GUI

Everything Server Manager’s “Add Roles and Features” wizard did is a one-liner. Roles and features install with Install-WindowsFeature, run remotely against any node:

Install-WindowsFeature -Name Web-Server,Web-Mgmt-Service `
  -ComputerName srv-core-02.corp.example.com -IncludeManagementTools

The -IncludeManagementTools switch brings in the remote-administration cmdlet modules and RSAT snap-in support for that role — without dragging in the desktop GUI. That distinction is what keeps Core lean: you get the management surface, not explorer.exe. To audit what is installed across the fleet, fan out over a session:

$s = New-PSSession -ComputerName srv-core-01,srv-core-02 -UseSSL
Invoke-Command -Session $s {
  Get-WindowsFeature | Where-Object Installed | Select-Object Name
}

The feature-management cmdlets you actually use, and what each is for:

Cmdlet Purpose Key parameters Notes
Install-WindowsFeature Add a role/feature -Name, -IncludeManagementTools, -Restart, -Source -Source points at a WIM for offline payload
Uninstall-WindowsFeature Remove a role/feature -Name, -Remove -Remove deletes the payload from disk (FoR)
Get-WindowsFeature List / audit features -ComputerName, Installed filter Fleet inventory
Get-WindowsCapability List FoD capabilities -Online, -Name For Features on Demand payloads
Add-WindowsCapability Add a FoD payload -Online, -Name, -Source App-compat FoD lives here
Enable-WindowsOptionalFeature Enable an optional feature (DISM-backed) -Online, -FeatureName e.g. some legacy features

Features on Demand vs Features on Removal. If you Uninstall-WindowsFeature -Name X -Remove, the payload is deleted from the running image, shrinking it further; reinstalling later needs a -Source. Conversely, some capabilities are not present at all by default and must be added on demand (the App Compatibility FoD, RSAT capabilities on clients, .NET 3.5). Know which direction you are going, and stage a -Source (a mounted install WIM or an offline FoD ISO) so an air-gapped box can still add payloads.

Drivers, without Device Manager, use pnputil — fully scriptable — and the PnpDevice cmdlets for querying. Stage a driver package and confirm it landed:

# Add a driver package to the LIVE OS, then list third-party drivers
pnputil /add-driver C:\drivers\vendor-nic\*.inf /install
pnputil /enum-drivers

# Query device state as objects
Get-PnpDevice -Class Net | Select-Object Status, FriendlyName, InstanceId

The driver-management surface headless, tool by tool:

Task Command Target Notes
Add a driver to the running OS pnputil /add-driver *.inf /install Live host Replaces “have disk” in Device Manager
List installed 3rd-party drivers pnputil /enum-drivers Live host Shows OEM##.inf published names
Remove a driver package pnputil /delete-driver oem12.inf /uninstall Live host Use the published OEM name
Enumerate device status Get-PnpDevice Live host Objects, filterable by -Class/-Status
Enable/disable a device Enable-PnpDevice / Disable-PnpDevice Live host By InstanceId
Inject a driver into an OFFLINE image Add-WindowsDriver (DISM) Mounted WIM/VHD For image builds, not the live host

On Server Core, Add-WindowsDriver (DISM) targets offline images; pnputil targets the running OS. Use pnputil for live hosts. For Hyper-V and storage hosts, pin firmware/driver bundles in your image pipeline so a manual pnputil install never silently diverges nodes in the same cluster — driver drift between cluster members is a real outage source, covered in Patching Failover Clusters with Cluster-Aware Updating and Stretch Clusters via Storage Replica.

Remote GUI tooling: Server Manager, RSAT, and the MMC consoles

Native PowerShell is the automation surface; RSAT is how you keep the classic GUI muscle memory when you want it. RSAT is a set of MMC consoles and PowerShell modules that runs on a Windows 10/11 workstation (added as Features on Demand / optional features) or on a management server, and connects to your Core boxes. You did not lose Event Viewer or DNS Manager or Hyper-V Manager — you lost the ability to run them on the server. Run them on your desktop, point them at the server, done.

Install RSAT on a Windows 11 admin workstation:

# List available RSAT capabilities, then add the ones you need
Get-WindowsCapability -Online -Name RSAT* |
  Select-Object Name, State

Add-WindowsCapability -Online -Name "Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0"
Add-WindowsCapability -Online -Name "Rsat.Dns.Tools~~~~0.0.1.0"
Add-WindowsCapability -Online -Name "Rsat.ServerManager.Tools~~~~0.0.1.0"

Server Manager itself works against Core — you run Server Manager on your workstation (or a management server), “Add other servers to manage,” and it dashboards the remote Core boxes, letting you add roles and read status remotely. The key insight beginners miss: Server Manager was never on the Core box; it always managed other servers, and Core is just one of those “other servers.”

The classic consoles and what they manage, all pointed at the remote Core node:

MMC console / tool Manages RSAT capability / source Connect by
Server Manager Roles, features, status dashboard Rsat.ServerManager.Tools Add server → FQDN
Active Directory Users and Computers (dsa.msc) AD objects Rsat.ActiveDirectory.DS-LDS.Tools Targets the domain, not the box
DNS Manager (dnsmgmt.msc) DNS zones/records Rsat.Dns.Tools Connect → server FQDN
DHCP (dhcpmgmt.msc) Scopes/leases Rsat.DHCP.Tools Add server
Hyper-V Manager VMs on a Core host Rsat.Hyper-V.Tools / feature Connect to server
Failover Cluster Manager Clusters/roles Rsat.FailoverCluster.Management.Tools Connect to cluster
Computer Management (compmgmt.msc) Services, disks, event logs, shares Built into Windows Action → Connect to another computer
Event Viewer (eventvwr.msc) Event logs Built in Connect to another computer
Certificates (certlm.msc) Machine cert store Built in Connect to remote machine store

Two things must be true for the MMC consoles to reach a Core box: the relevant firewall rules must be enabled on the server (many are governed by rule groups like “Remote Event Log Management,” “Remote Service Management,” “Remote Volume Management”), and you need name resolution + Kerberos (connect by FQDN, not IP). Enable the rule groups you need on the node:

# On the Core node — allow the MMC consoles' underlying RPC/WMI traffic
Enable-NetFirewallRule -DisplayGroup "Remote Event Log Management"
Enable-NetFirewallRule -DisplayGroup "Remote Service Management"
Enable-NetFirewallRule -DisplayGroup "Remote Volume Management"
Enable-NetFirewallRule -DisplayGroup "Windows Management Instrumentation (WMI)"

Windows Admin Center: gateway, connections, extensions, and roles

Windows Admin Center is the browser-based, GUI-equivalent experience over the same WinRM plumbing — no agent on the managed nodes. The right topology for a team is gateway mode: install WAC as a Windows service on a dedicated management server (which can itself be Server Core), not in desktop mode on someone’s laptop. A gateway is centrally patched, its access is auditable, and everyone points a browser at one URL.

As of 2024+, Windows Admin Center ships as a modern installer (WindowsAdminCenter.exe/MSI) that supersedes the older “Project Honolulu” MSI. The gateway install, the port binding, and the certificate story are the same in spirit; use the current installer and follow its switches. The concepts below — gateway, connections, extensions, JEA target — are stable.

Install silently, generating a self-signed cert only for the first stand-up. In production, supply your own CA-issued certificate:

# Gateway install on a dedicated management host, port 443 (older MSI switches shown)
msiexec /i WindowsAdminCenter.msi /qn /L*v wac-install.log `
  SME_PORT=443 SSL_CERTIFICATE_OPTION=generate

After install, the gateway listens on 443. Replace the generated certificate with a CA-issued one bound to the gateway’s FQDN before anyone uses it — a self-signed gateway cert trains operators to click through TLS warnings, which is exactly the habit you do not want on a management plane.

Add nodes from PowerShell so the inventory is repeatable rather than hand-entered. The WAC ConnectionTools module imports a list of connections:

Import-Module "$env:ProgramFiles\WindowsAdminCenter\PowerShell\Modules\ConnectionTools"

$nodes = "srv-core-01.corp.example.com","srv-core-02.corp.example.com"
$nodes | ForEach-Object {
  "$_|msft.sme.connection-type.server|$_"
} | Set-Content .\wac-connections.txt

Import-Connection -GatewayEndpoint "https://wac.corp.example.com" `
  -FileName .\wac-connections.txt

WAC’s built-in tools cover essentially every headless day-two task through the browser. The most-used ones and what they replace:

WAC tool What it does GUI it replaces Underlying mechanism
Overview CPU/RAM/uptime, restart/shutdown, edit env Server Manager dashboard WinRM/CIM
Roles & features Add/remove roles Add Roles wizard Install-WindowsFeature
Events Browse/filter event logs Event Viewer Get-WinEvent
Files & file sharing Browse FS, manage SMB shares Explorer + fsmgmt.msc CIM/WinRM
Storage / Volumes / Disks Init/partition/format, pools Disk Management Storage module
Certificates Machine cert store certlm.msc CIM
Services Start/stop/config services services.msc Get/Set-Service
Performance Monitor Live/recorded counters perfmon.exe Get-Counter / PDH
Registry View/edit registry regedit CIM
PowerShell In-browser remote console PowerShell remoting
Remote Desktop In-browser RDP (to the console) mstsc RDP
Updates View/install Windows Updates Windows Update WU API
Virtual machines / switches Manage Hyper-V Hyper-V Manager Hyper-V WMI

Extensions add capability without re-installing anything. WAC has an extension feed; you add extensions for Cluster management, the SDN/Networking extension, vendor hardware (Dell/HPE/Lenovo) health, and Azure hybrid services (Backup, Monitor, Update Manager, Security). Manage them under Settings → Extensions, or from the gateway host:

# List and install extensions from the configured feed (module name varies by build)
Get-Command -Module *Extension* -ErrorAction SilentlyContinue
# In the UI: Settings > Extensions > choose an extension > Install (gateway restarts the tool)

The topology and its rules, side by side, so you deploy the right shape:

WAC install mode Runs as Who reaches it Use for Certificate
Gateway (service) Windows service on a server A whole team via browser Production; central mgmt of a fleet CA-issued, gateway FQDN
Desktop App on Win10/11 Just that user Ad-hoc, a single admin’s laptop Self-signed local
Failover-cluster (HA) Clustered gateway role A team, highly available Large estates needing HA mgmt plane CA-issued

WAC connects to nodes over WinRM as the signed-in user (single sign-on with Kerberos) when the gateway and nodes are in the same domain. Managing non-domain or cross-domain nodes through the gateway needs CredSSP or a configured resource-based constrained delegation (RBCD) path — the double-hop problem, covered in troubleshooting below. Register the gateway with Azure Arc to front WAC with Entra ID auth and conditional access, and operate the fleet from the Azure portal without opening an inbound management port to the internet.

The missing-GUI workflows: events, performance, storage, users, services, certs

You lost Event Viewer, Performance Monitor, and Disk Management as windows — but every one of them is now an object pipeline, which is strictly more powerful for a fleet. This section is the reference for the tasks that specifically trip people up because the GUI is gone.

Event logs — Get-WinEvent

Query the modern channels with a hashtable filter so you pull only what matters across many nodes at once — the equivalent of setting a custom view in Event Viewer, but scriptable and fannable:

Invoke-Command -ComputerName srv-core-01,srv-core-02 -UseSSL {
  Get-WinEvent -FilterHashtable @{
    LogName   = 'System'
    Level     = 1,2          # 1 = Critical, 2 = Error
    StartTime = (Get-Date).AddHours(-24)
  } -ErrorAction SilentlyContinue
} | Select-Object PSComputerName, TimeCreated, Id, ProviderName, Message

The Get-WinEvent filter fields you will actually use:

Filter key Meaning Example value
LogName Channel to query System, Application, Security, Microsoft-Windows-...
Level Severity 1=Critical, 2=Error, 3=Warning, 4=Info
Id Event ID(s) 4624, 7036
ProviderName Source Service Control Manager
StartTime / EndTime Time window (Get-Date).AddHours(-1)
Data Event data field match provider-specific

Performance — Get-Counter

Pull live counters without opening perfmon. Sample CPU, memory, and disk queue against a node — the same counters, delivered as objects you can threshold and alert on:

Get-Counter -ComputerName srv-core-01.corp.example.com `
  -Counter '\Processor(_Total)\% Processor Time',
           '\Memory\Available MBytes',
           '\PhysicalDisk(_Total)\Avg. Disk Queue Length' `
  -SampleInterval 5 -MaxSamples 3

Storage — the Storage module

The Storage module replaces Disk Management wholesale. Initialize a new disk, partition it, and format it end to end in one pipeline:

Invoke-Command -ComputerName srv-core-02.corp.example.com -UseSSL {
  Get-Disk | Where-Object PartitionStyle -eq 'RAW' |
    Initialize-Disk -PartitionStyle GPT -PassThru |
    New-Partition -AssignDriveLetter -UseMaximumSize |
    Format-Volume -FileSystem NTFS -NewFileSystemLabel 'Data' -Confirm:$false
}

The Disk-Management-equivalent cmdlets, task by task:

Disk Management action Cmdlet Note
See disks/volumes Get-Disk, Get-Volume, Get-Partition Objects, filterable
Initialize a new disk Initialize-Disk -PartitionStyle GPT GPT over MBR for modern disks
Create a partition New-Partition -UseMaximumSize -AssignDriveLetter Or -DriveLetter
Format a volume Format-Volume -FileSystem NTFS -FileSystem ReFS for S2D/Hyper-V
Extend a volume Resize-Partition -Size ... Grow into free space
Bring a disk online / RW Set-Disk -IsOffline $false -IsReadOnly $false Common after attaching
Create a storage pool New-StoragePool Storage Spaces / S2D territory

Users, services, and certificates

Local users (rare on domain-joined boxes, but real for break-glass and workgroup edge), services, and certificates are all cmdlet-driven:

# Local users/groups (workgroup / break-glass)
Get-LocalUser; New-LocalUser -Name "svc-break" -NoPassword:$false
Add-LocalGroupMember -Group "Administrators" -Member "CORP\ServerAdmins"

# Services
Get-Service W3SVC | Select-Object Status, StartType
Set-Service -Name Spooler -StartupType Disabled     # e.g. hardening a print-free server
Restart-Service -Name W3SVC

# Certificates — the Cert: PSDrive is your certlm.msc
Get-ChildItem Cert:\LocalMachine\My |
  Select-Object Subject, NotAfter, Thumbprint, EnhancedKeyUsageList

Application compatibility: Features on Demand and the App Compatibility FoD

The most common objection to Server Core — “our app won’t install, it needs the GUI” — usually has nothing to do with the desktop and everything to do with a handful of GUI DLLs and diagnostic tools the installer or the app links against. Rather than concede to Desktop Experience, add the Server Core App Compatibility Feature on Demand (ServerCore.AppCompatibility). It restores those specific components — mmc.exe, eventvwr.msc, perfmon.exe, resmon.exe, dsregcmd, parts of the shell, and a minimal Explorer — on top of Core, without turning the box into a full Desktop Experience install. You keep the lean base and unblock the app.

Check availability, then add it (online if the box has access to Windows Update, or from an offline FoD ISO with -Source):

# Is the App Compatibility FoD present or available?
Get-WindowsCapability -Online -Name "ServerCore.AppCompatibility*"

# Add it online...
Add-WindowsCapability -Online -Name "ServerCore.AppCompatibility~~~~0.0.1.0"

# ...or from a mounted FoD ISO on an air-gapped box, then reboot
Add-WindowsCapability -Online -Name "ServerCore.AppCompatibility~~~~0.0.1.0" `
  -Source "D:\" -LimitAccess

What the App Compatibility FoD does and does not give you:

Aspect With App Compatibility FoD Full Desktop Experience
mmc.exe + common snap-ins locally Yes Yes
Event Viewer / Perfmon / Resmon locally Yes Yes
Minimal File Explorer Yes (limited) Yes (full shell)
Microsoft Edge / browser No Yes
Start menu / full desktop shell No Yes
Media / Paint / Windows apps No Yes
Footprint added Modest (a few components) Large (full GUI stack)
Patch surface added Small Full GUI servicing
Reversible Yes (Remove-WindowsCapability) No (one-way install choice)

Decide app-compat in this order, escalating only when forced:

Symptom First try Then Last resort
Installer errors on a missing GUI DLL Add App Compatibility FoD Vendor’s silent/headless installer switches Desktop Experience
App needs mmc/perfmon to run Add App Compatibility FoD Manage the app remotely from a workstation Desktop Experience
App needs .NET 3.5 Add-WindowsCapability/Install-WindowsFeature NET-Framework-Core with -Source
App needs a specific legacy component Get-WindowsCapability -Online and add it Vendor support case Desktop Experience

The App Compatibility FoD is the reason “we can’t use Core” is almost never true. Reach for it before you concede the GUI. Reserve Desktop Experience for genuine Remote Desktop Session Hosts and the rare vendor that contractually refuses to support anything but the full desktop — and, as always, push that vendor.

Architecture at a glance

Picture the management plane as three concentric surfaces around a headless node, all riding the same WinRM transport. At the centre sits a Server Core box: no explorer.exe, a single console for break-glass, WinRM listening on 5986 (HTTPS) with the HTTP listener removed, Basic auth and unencrypted traffic disabled, and — if delegated ops are needed — a JEA endpoint (ServiceOps) registered as a constrained, transcribed session. That node is cattle: provisioned by an unattend.xml, named and domain-joined before a human ever touches it.

Around it, three ways in. First, an admin workstation running native PowerShell remotingEnter-PSSession and Invoke-Command -UseSSL fanning commands across many nodes at once; this is the automation surface and the one your runbooks call. Second, the same workstation (or a management server) running RSAT — Server Manager, ADUC, DNS Manager, Hyper-V Manager, Event Viewer, Computer Management — each classic MMC console pointed at the remote node over Kerberos, giving you the familiar GUI without a single GUI byte on the server. Third, a Windows Admin Center gateway: a dedicated (often Core) server running WAC as a service on 443 with a CA-issued certificate, its connection inventory imported from PowerShell, its capability extended by the Cluster/SDN/vendor/Azure extensions, reaching each node over WinRM as the signed-in user via Kerberos SSO — and a whole team pointing a browser at one URL.

The flows all converge on WinRM: PowerShell → 5986; WAC gateway → 5986; RSAT/MMC → the role’s RPC/WMI ports plus WinRM for some tools. Kerberos authenticates and encrypts inside the domain; HTTPS carries the non-domain and cross-forest hops; the double-hop cases (WAC or a front-end node reaching a second server on the user’s behalf) are solved with resource-based constrained delegation scoped to named front-ends, never unconstrained delegation or blanket CredSSP. Follow any path inward and you land on the same lean node — the desktop is gone, but every management capability it used to host now lives one hop away, centralised and auditable.

Real-world scenario

Meridian Freight, a logistics company, ran a 200-node estate — Hyper-V hosts, file servers, domain controllers, and IIS middleware — and standardised on Server Core to cut their patch surface and monthly reboot count. The build went clean: golden images with unattend.xml, WinRM HTTPS listeners rolled out by a startup script, WAC in gateway mode on a dedicated Core box, and RSAT on the ops team’s Windows 11 workstations. For three weeks it was uneventful — fewer patches, faster maintenance windows, exactly the pitch.

Then the operations team started hitting WinRM 0x80090322 errors when WAC reached file servers that, in turn, needed to read from a back-end SMB cluster on the user’s behalf. Single-hop commands worked perfectly; anything touching a second server failed. Classic Kerberos double-hop: the credential WAC delegated to node A could not be reused by node A to authenticate to node B. The on-call engineer’s first instinct — enable CredSSP everywhere, or turn on unconstrained delegation — got flagged in review, because unconstrained delegation lets a compromised intermediary impersonate the operator against any service in the forest, and CredSSP caches credentials on the intermediary. On a fleet this size, that was an unacceptable blast radius.

The correct, scoped fix was resource-based constrained delegation (RBCD), configured on the resource (the back-end node) to trust only the specific front-end nodes:

# On a DC / mgmt host: let the front-end file servers delegate to the back-end cluster node
$frontends = Get-ADComputer -Filter 'Name -like "SRV-FILE-0*"'
Set-ADComputer -Identity "SRV-FILE-BACK01" `
  -PrincipalsAllowedToDelegateToAccount $frontends

Because RBCD is administered on the resource owner’s side, the team that owned the back-end cluster controlled exactly which front-ends could impersonate users against it — no domain-admin change to the front-ends, no forest-wide trust, no credentials cached anywhere. After clearing the stale ticket cache (klist purge) on the front-end nodes, the WAC storage and file-share tools worked through the double hop, and the unconstrained-delegation security finding never had to be opened.

A second, quieter win came from the app-compat side. A legacy monitoring agent the company was contractually stuck with “required the GUI” and nearly forced three of the file servers onto Desktop Experience. Instead, the team added the App Compatibility FoD (ServerCore.AppCompatibility) to those three boxes — the agent’s installer found the mmc and perf DLLs it wanted, installed cleanly, and the boxes stayed on Core. The lesson the team wrote on the wall: when a headless, gateway-fronted fleet hits a wall, the answer is almost always a scoped, native mechanism — RBCD for double-hop, a Feature on Demand for app-compat — not the sledgehammer of unconstrained delegation or a full desktop install.

Advantages and disadvantages

The headless-with-remote-management model both demands discipline and rewards it. Weigh it honestly:

Advantages Disadvantages
Smaller attack surface — fewer binaries, services, and listeners to compromise or patch Steeper learning curve for teams used to wizards; the black screen intimidates
Fewer patches and reboots — absent components generate no servicing The Core install choice is one-way; a wrong call means a rebuild, not a toggle
Smaller disk/memory footprint — matters at fleet and edge scale A stubborn vendor app may still need FoD or (rarely) Desktop Experience
Forces remote, declarative admin — the good habit, removing hand-edited prod boxes Every remote surface (WinRM, RSAT firewall rules, WAC cert) is a thing to configure and secure
Three complementary surfaces (PowerShell, RSAT, WAC) — pick the right tool per task Double-hop and Kerberos-SPN issues appear that a single local session never surfaces
WAC gives a whole team a GUI-equivalent over one auditable gateway, no node agents WAC gateway is another server to patch, cert-manage, and keep highly available
JEA on Core delegates day-two work with no standing admin, fully transcribed JEA role/session files are more upfront design than “just add them to Administrators”

The model is right for essentially every standard Windows Server role — DCs, DNS/DHCP, file, Hyper-V, IIS, middleware — where you want a lean, patch-light, remotely-managed box. It bites hardest on teams that never invest the week to learn the remote surfaces (who then default to Desktop Experience and lose all the benefit), and on estates with a genuine hard-GUI-installer dependency that FoD cannot satisfy. Every disadvantage is manageable — but only if you know it exists before you are staring at a black screen at 2 a.m.

Hands-on lab

Stand up a Server Core-style headless workflow end to end: enable and harden remoting, register a JEA endpoint, do a missing-GUI task (storage), and tear it all down. If you have a spare Server Core VM (2022/2025), run these against it from your workstation; if you only have one box, run the node-side steps locally and the client-side steps from the same PowerShell — the commands are identical. Everything here is free (uses features already in Windows Server).

Step 1 — Confirm the box and its install type. On the node’s console:

# 'Server Core' has no shell; confirm the SKU and that there's no Desktop Experience
Get-ComputerInfo -Property WindowsProductName, OsServerLevel, WindowsInstallationType

Expected: WindowsInstallationType = Server Core.

Step 2 — Enable remoting and verify WinRM. On the node:

Enable-PSRemoting -Force
Get-Service WinRM | Select-Object Status, StartType         # Running / Automatic
Get-ChildItem WSMan:\localhost\Listener                     # note the HTTP (5985) listener

Step 3 — Stand up an HTTPS listener (self-signed for the lab). On the node:

$cert = New-SelfSignedCertificate -DnsName $env:COMPUTERNAME `
  -CertStoreLocation Cert:\LocalMachine\My
New-Item -Path WSMan:\localhost\Listener -Transport HTTPS -Address * `
  -HostName $env:COMPUTERNAME -CertificateThumbPrint $cert.Thumbprint -Force
New-NetFirewallRule -DisplayName "WinRM HTTPS lab (5986)" -Direction Inbound `
  -Protocol TCP -LocalPort 5986 -Action Allow

Expected: a new listener with Transport=HTTPS, Port=5986. (In production you would use a CA-issued cert, not New-SelfSignedCertificate.)

Step 4 — Harden the WinRM service. On the node:

Set-Item WSMan:\localhost\Service\AllowUnencrypted $false
Set-Item WSMan:\localhost\Service\Auth\Basic       $false
Get-Item WSMan:\localhost\Service\Auth\Basic                # should read False

Step 5 — Register a JEA endpoint. On the node:

$m = "$env:ProgramFiles\WindowsPowerShell\Modules\LabOps\RoleCapabilities"
New-Item $m -ItemType Directory -Force | Out-Null
New-PSRoleCapabilityFile -Path "$m\SvcOp.psrc" `
  -VisibleCmdlets 'Get-Service','Restart-Service'
New-PSSessionConfigurationFile -Path .\LabOps.pssc `
  -SessionType RestrictedRemoteServer -RunAsVirtualAccount `
  -RoleDefinitions @{ "$env:COMPUTERNAME\Administrators" = @{ RoleCapabilities = 'SvcOp' } }
Register-PSSessionConfiguration -Name "LabOps" -Path .\LabOps.pssc -Force

Expected: Get-PSSessionConfiguration -Name LabOps returns the endpoint with RunAsVirtualAccount = True.

Step 6 — Prove the constraint. From a client (or the same box):

Invoke-Command -ComputerName $env:COMPUTERNAME -ConfigurationName LabOps { Get-Command } |
  Select-Object -ExpandProperty Name
# Expect ONLY Get-Service, Restart-Service (+ a few default proxy cmdlets) — nothing else

Step 7 — A missing-GUI task: read errors as objects. From a client:

Get-WinEvent -ComputerName $env:COMPUTERNAME -FilterHashtable @{
  LogName='System'; Level=1,2; StartTime=(Get-Date).AddDays(-1)
} -ErrorAction SilentlyContinue | Select-Object TimeCreated, Id, ProviderName -First 10

Step 8 — (Optional) Add the App Compatibility FoD. If the box has Windows Update access:

Get-WindowsCapability -Online -Name "ServerCore.AppCompatibility*" |
  Select-Object Name, State
# Add-WindowsCapability -Online -Name "ServerCore.AppCompatibility~~~~0.0.1.0"   # reboots

Step 9 — Teardown. Remove what the lab created:

Unregister-PSSessionConfiguration -Name "LabOps" -Force
Get-ChildItem WSMan:\localhost\Listener |
  Where-Object { $_.Keys -contains "Transport=HTTPS" } | Remove-Item -Recurse
Remove-NetFirewallRule -DisplayName "WinRM HTTPS lab (5986)"
Get-ChildItem Cert:\LocalMachine\My | Where-Object Subject -match $env:COMPUTERNAME |
  Remove-Item
Remove-Item "$env:ProgramFiles\WindowsPowerShell\Modules\LabOps" -Recurse -Force

You have enabled and hardened remoting, stood up and proven a JEA constraint, and done a real day-two task headless — the full loop, with a clean teardown.

Common mistakes & troubleshooting

Troubleshooting a box you cannot see is the skill that separates comfort from panic. The field guide — symptom, the likely cause, how to confirm it, and the fix — is the centrepiece here:

# Symptom Likely cause Confirm with Fix
1 Test-WSMan -UseSSL fails, HTTP works Cert FQDN/SAN mismatch, expired, or untrusted CA Get-ChildItem Cert:\LocalMachine\My | fl Subject,NotAfter,EnhancedKeyUsageList Reissue with correct DNS name + Server Auth EKU; trust the CA on the client
2 Connecting to remote server failed ... Access is denied Kerberos can’t resolve the SPN; connecting by IP not FQDN setspn -L <computer>; try FQDN Connect by FQDN; ensure HOST/<fqdn> SPN exists
3 WinRM 0x80090322 on multi-server WAC/tools Kerberos double-hop Single-hop works, second-hop fails Configure RBCD on the resource, scoped to named front-ends; klist purge
4 WAC node shows “not accessible” Firewall 5986 closed, or listener on wrong/expired cert Test-NetConnection <node> -Port 5986; check listener thumbprint Open 5986; rebind listener to a valid cert
5 Workgroup/non-domain node unreachable No Kerberos; TrustedHosts not set Get-Item WSMan:\localhost\Client\TrustedHosts Add the node’s FQDN to TrustedHosts (never *) + use HTTPS/cert auth
6 RDP to Core shows a black screen with no window Console session, explorer.exe absent — this is normal You see a cmd/PowerShell window only Not a fault; type powershell, or manage remotely
7 MMC console (Event Viewer, etc.) can’t connect to the node Remote-management firewall rule group disabled Get-NetFirewallRule -DisplayGroup "Remote Event Log Management" Enable-NetFirewallRule -DisplayGroup "Remote Event Log Management" (and peers)
8 App installer aborts: “requires the graphical shell” Missing GUI DLLs, not the whole desktop Installer log names an mmc/shell DLL Add App Compatibility FoD (ServerCore.AppCompatibility), reboot, retry
9 Disk not visible / read-only after attach Disk offline or read-only Get-Disk | ft Number,IsOffline,IsReadOnly Set-Disk -Number N -IsOffline $false -IsReadOnly $false
10 Driver won’t load after pnputil /add-driver Unsigned driver or wrong architecture pnputil /enum-drivers; check signature Use a signed x64 driver; verify the INF architecture matches
11 A service is hung; can’t open services.msc locally No local GUI (expected) Get-Service X; sc.exe queryex X for PID Restart-Service X, or Stop-Process -Id <PID> -Force then start
12 Disk filling; can’t browse in Explorer No shell to click through folders Get-PSDrive C; Get-ChildItem C:\ -Recurse ... | Sort Length -Desc Delete/relocate the largest offenders; clean CBS/temp; Cleanmgr isn’t on Core
13 Can’t confirm what changed / who restarted the box No local event GUI habit Get-WinEvent -LogName System | Where Id -in 6005,6006,1074,41 Read shutdown/boot/Kernel-Power events for the story
14 Time is skewed; Kerberos starts failing W32Time not synced to the domain hierarchy w32tm /query /status; w32tm /monitor Re-sync per Authoritative time sync on Windows and Linux

Two quick diagnostic reflexes worth committing to muscle memory. When Kerberos is suspect, the fastest signal is the ticket cache — a stale or missing service ticket explains most “access is denied” errors after any delegation or SPN change:

klist purge                                          # clear stale tickets
klist get HOST/srv-core-01.corp.example.com          # force a fresh ticket for the SPN

When anything remote fails, confirm the transport before you theorise — is the port even open, and does the listener answer?

Test-NetConnection srv-core-01.corp.example.com -Port 5986      # is 5986 reachable?
Test-WSMan -ComputerName srv-core-01.corp.example.com -UseSSL   # does WinRM answer over TLS?

If Test-WSMan -UseSSL fails but the plain (HTTP) test passes, the certificate is the problem about 90% of the time — wrong FQDN in the subject/SAN, expired, or an issuing CA the client does not trust. Check the cert and the client’s trust chain before touching listeners, firewall, or auth.

Best practices

Security notes

Server Core is a security posture, not just an install option — lean into it. Every component you did not install is one you do not have to patch, monitor, or defend; keep it that way by adding FoD payloads deliberately and removing feature payloads you do not need (Uninstall-WindowsFeature -Remove).

The management plane is now your highest-value surface, so harden it accordingly. WinRM must be HTTPS-only with Basic auth and unencrypted traffic disabled; the HTTP listener removed; and TrustedHosts empty or narrowly enumerated. Delegation is where headless fleets get compromised — never use unconstrained delegation, avoid CredSSP (it caches credentials on the intermediary), and solve every double-hop with resource-based constrained delegation scoped to named front-ends so a single compromised intermediary cannot impersonate operators forest-wide.

Nobody should hold standing local admin. Deliver day-two operations through JEA endpoints running as virtual accounts, with every session transcribed to a write-protected location and shipped to your SIEM as a privileged-access audit trail. Pair this with gMSA and Windows LAPS (Eliminating Static Service Credentials with gMSA and Windows LAPS) so service and local-admin credentials are rotated automatically and never static. Front the Windows Admin Center gateway with a CA-issued certificate and, ideally, register it with Azure Arc so Entra ID authentication and conditional access sit in front of the whole fleet — letting you operate headless boxes without opening an inbound management port to the internet at all. Finally, apply the same hardening baseline you would to any Windows Server (Hardening Windows Server and Building a Reliable WSUS Patch Pipeline); Core gives you a smaller surface to harden, not a pass on hardening.

Cost & sizing

Server Core has no separate license — it is the same Windows Server license as Desktop Experience, chosen at install time — so the “cost” story is entirely about density and operations, not SKUs. The savings are real but indirect:

Cost driver Server Core effect Rough magnitude
Windows Server license Identical to Desktop Experience No difference
Disk per host Smaller base image Several GB saved per host
Memory per host Smaller baseline working set Hundreds of MB freed per host; more VMs per hypervisor
Patch/reboot labour Fewer components → fewer updates/reboots Recovered maintenance-window hours across a fleet
WAC gateway One (or two, for HA) management servers A B-series-equivalent VM or two; negligible vs the estate
RSAT Free (built into Windows 10/11 as FoD) ₹0
Windows Admin Center Free (no per-node license) ₹0

Sizing guidance: the WAC gateway is light — a modest server (2–4 vCPU, 4–8 GB RAM) handles a few hundred nodes comfortably; scale up only for very large estates or when you cluster it for HA. Do not over-provision Core nodes on the assumption they need “GUI headroom” — they need less than the equivalent Desktop Experience box for the same role, so right-size the role’s actual workload and pocket the difference. Across a large estate, the aggregate disk saved, the extra VMs you fit per hypervisor host, and the maintenance-window hours you recover from fewer reboots are where Core pays for the week you spent learning it. In INR terms on a cloud estate, packing even 10–15% more Core VMs onto the same hypervisor hosts, or shrinking hosts, moves the monthly bill by a meaningful margin at scale — while the tooling to manage them all (RSAT, WAC) costs nothing.

Interview & exam questions

Q1. Why is Server Core more secure than Desktop Experience? Fewer installed components means a smaller attack surface — no shell, no Edge, no media, fewer services and listeners — so fewer CVEs apply and there is less to compromise. It also patches and reboots less because absent components generate no servicing. Maps to security-hardening and Windows Server admin objectives.

Q2. Can you convert a Server Core install to Desktop Experience after deployment? No. The install option is chosen at setup and is a one-way door — the in-place feature switch was removed after Server 2012 R2. Changing your mind means a rebuild, so choose deliberately.

Q3. What is the difference between the WinRM HTTP (5985) and HTTPS (5986) listeners, and is HTTP plaintext in a domain? 5985 is HTTP, 5986 is HTTPS. In a domain, Kerberos already encrypts the payload over the HTTP listener, so it is not plaintext — but you standardise on 5986 for non-domain/cross-forest hops and uniform TLS negotiation, then remove the HTTP listener.

Q4. What does Install-WindowsFeature -IncludeManagementTools add, and why does it matter on Core? It adds the role’s remote-administration cmdlet modules and RSAT snap-in support — not the desktop GUI. That distinction is what keeps Core lean: you get the management surface without explorer.exe.

Q5. What is JEA and why is it especially valuable on Server Core? Just Enough Administration exposes a constrained PowerShell endpoint where a user runs as a temporary virtual account with only whitelisted cmdlets, fully transcribed. On Core it is the interface for delegated ops — there is no local GUI to fall back on — so operators never need standing local admin.

Q6. An operator gets WinRM 0x80090322 only when a WAC tool touches a second server. What is happening and how do you fix it correctly? It is the Kerberos double-hop: the credential delegated to the first node can’t be reused to reach the second. The correct fix is resource-based constrained delegation on the resource, scoped to the named front-end nodes — not unconstrained delegation and not blanket CredSSP.

Q7. A vendor app won’t install because it “needs the GUI.” What do you try before Desktop Experience? Add the Server Core App Compatibility Feature on Demand (ServerCore.AppCompatibility), which restores the specific GUI DLLs and tools (mmc, perfmon, Event Viewer, limited Explorer) without a full desktop. Reserve Desktop Experience for session hosts and vendors that contractually refuse Core.

Q8. How do you install a NIC driver on a running Server Core box with no Device Manager? pnputil /add-driver <path>\*.inf /install on the live OS, then pnputil /enum-drivers to confirm. Add-WindowsDriver (DISM) is for offline images, not the running host.

Q9. Windows Admin Center — what is gateway mode and why prefer it over desktop mode in production? Gateway mode runs WAC as a Windows service on a dedicated (often Core) server that a whole team reaches by browser; it is centrally patched, auditable, and its connections are managed centrally. Desktop mode is a single admin’s laptop app — fine for ad-hoc use, wrong for a fleet.

Q10. Test-WSMan -UseSSL fails but the plain test succeeds. What’s the most likely cause and first check? The certificate — wrong FQDN/SAN, expired, or a CA the client doesn’t trust — about 90% of the time. Check the cert’s subject/SAN, expiry, and Server Authentication EKU, and the client’s trust chain, before touching listeners or firewall.

Q11. Why should TrustedHosts never be set to *? It tells WinRM to trust the identity of any host you connect to, defeating mutual authentication and inviting man-in-the-middle. Enumerate specific FQDNs, or better, keep nodes domain-joined (Kerberos) or use certificate auth.

Q12. How do you read the last shutdown/restart cause on a headless box with no Event Viewer window? Get-WinEvent -LogName System | Where-Object Id -in 6005,6006,1074,41 — 6005/6006 are event-log start/stop (boot/clean-shutdown), 1074 is an initiated shutdown/restart with the reason and user, and 41 (Kernel-Power) indicates an unexpected power loss.

Quick check

  1. Can you convert a running Server Core box to Desktop Experience? What does that imply for how you choose the install option?
  2. Which WinRM port and listener should a hardened fleet standardise on, and what two settings do you disable on the WinRM service?
  3. What does the App Compatibility FoD (ServerCore.AppCompatibility) give you, and what does it deliberately not give you?
  4. You get 0x80090322 only on multi-server WAC tools. What is the cause, and what is the correct fix?
  5. Name the three remote-management surfaces for a headless box and one task each is best at.

Answers

  1. No — it is a one-way choice made at setup. So you must pick Core deliberately for the workload; a wrong call means a rebuild, not a toggle.
  2. HTTPS on 5986 (remove the HTTP 5985 listener after proving HTTPS). Disable AllowUnencrypted and Basic auth on the WinRM service.
  3. It restores specific GUI DLLs and diagnostic tools (mmc, perfmon, resmon, Event Viewer, a limited Explorer) so GUI-dependent apps install and run. It does not add Edge, the Start menu / full shell, or the media/Windows apps — it is not Desktop Experience.
  4. The Kerberos double-hop — the credential delegated to the first node can’t reach a second. Fix with resource-based constrained delegation (RBCD) on the resource, scoped to the named front-end nodes; then klist purge. Never unconstrained delegation or blanket CredSSP.
  5. Native PowerShell remoting (best for automation and fleet fan-out), RSAT/MMC (best for familiar one-box GUI tasks like DNS Manager or Hyper-V Manager), and Windows Admin Center (best for a team’s GUI-equivalent dashboards over one auditable gateway).

Glossary

Next steps

windows-serverserver-corewindows-admin-centerpowershellwinrmsconfigrsatremote-management
Need this built for real?

Vinod is a Senior Cloud Architect (22+ yrs) — available for Azure / AWS / GCP architecture, landing zones, and migrations.

Work with me

Comments

Keep Reading