Windows Server Core is a minimal installation option that removes the GUI, reducing the attack surface, resource usage, and patching requirements. All management is done via PowerShell, remote tools, or Windows Admin Center. This guide covers essential PowerShell commands for managing Server Core on your VPS.
Initial Configuration
# Launch Server Configuration Tool (sconfig)
sconfig
# Or configure everything via PowerShell:
# Set hostname
Rename-Computer -NewName "CORE-WEB01" -Restart
# Configure static IP
New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress "10.0.0.50" -PrefixLength 24 -DefaultGateway "10.0.0.1"
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses "10.0.0.10", "1.1.1.1"
# Join domain
$cred = Get-Credential
Add-Computer -DomainName "corp.example.com" -Credential $cred -OUPath "OU=Servers,DC=corp,DC=example,DC=com" -Restart
# Enable Remote Desktop
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -Name "fDenyTSConnections" -Value 0
Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
# Enable remote management
Enable-PSRemoting -Force
winrm quickconfig -q
# Configure Windows Update
Install-Module PSWindowsUpdate -Force
Get-WindowsUpdate
Install-WindowsUpdate -AcceptAll -AutoReboot
Role and Feature Management
# List available roles
Get-WindowsFeature | Where-Object InstallState -eq "Available" | Format-Table Name, DisplayName
# Install roles
Install-WindowsFeature -Name Web-Server -IncludeManagementTools
Install-WindowsFeature -Name DNS -IncludeManagementTools
Install-WindowsFeature -Name Containers
# Remove unnecessary features
Remove-WindowsFeature -Name PowerShell-ISE # Not available on Core anyway
# Install .NET Framework features
Install-WindowsFeature -Name NET-Framework-45-Core
Service Management
# List all services
Get-Service | Sort-Object Status, Name | Format-Table
# Start/Stop/Restart services
Start-Service W3SVC
Stop-Service Spooler
Restart-Service WinRM
# Change startup type
Set-Service -Name Spooler -StartupType Disabled
# View service dependencies
Get-Service W3SVC | Select-Object -ExpandProperty DependentServices
# Create a custom service
New-Service -Name "MyApp" -BinaryPathName "C:\MyApp\app.exe" `
-DisplayName "My Application" -StartupType Automatic -Description "Custom application service"
Network Management
# View network configuration
Get-NetIPConfiguration
Get-NetAdapter | Format-Table Name, Status, LinkSpeed, MacAddress
Get-DnsClientServerAddress
# Firewall management
Get-NetFirewallRule | Where-Object Enabled -eq True | Format-Table DisplayName, Direction, Action
New-NetFirewallRule -DisplayName "Allow HTTP" -Direction Inbound -Protocol TCP -LocalPort 80 -Action Allow
New-NetFirewallRule -DisplayName "Allow HTTPS" -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow
Remove-NetFirewallRule -DisplayName "Allow HTTP"
# Test connectivity
Test-NetConnection google.com -Port 443
Test-NetConnection 10.0.0.10 -Port 3389 -InformationLevel Detailed
# View active connections
Get-NetTCPConnection -State Established | Format-Table LocalAddress, LocalPort, RemoteAddress, RemotePort, OwningProcess
Storage Management
# Disk information
Get-Disk | Format-Table Number, PartitionStyle, Size, OperationalStatus
Get-Volume | Format-Table DriveLetter, FileSystem, Size, SizeRemaining
# Initialize and format new disk
Get-Disk | Where-Object PartitionStyle -eq "RAW" | Initialize-Disk -PartitionStyle GPT
New-Partition -DiskNumber 1 -UseMaximumSize -DriveLetter D | Format-Volume -FileSystem NTFS -NewFileSystemLabel "Data"
# Check disk space (percentage used)
Get-Volume | Where-Object DriveLetter | ForEach-Object {
[PSCustomObject]@{
Drive = "$($_.DriveLetter):"
Size = "{0:N1} GB" -f ($_.Size / 1GB)
Free = "{0:N1} GB" -f ($_.SizeRemaining / 1GB)
Used = "{0:P0}" -f (1 - ($_.SizeRemaining / $_.Size))
}
} | Format-Table
Process and Performance Monitoring
# View running processes
Get-Process | Sort-Object CPU -Descending | Select-Object -First 20 Name, Id, CPU, @{N="Memory(MB)";E={[math]::Round($_.WorkingSet64/1MB)}} | Format-Table
# System uptime
(Get-CimInstance Win32_OperatingSystem).LastBootUpTime
$uptime = (Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
"Uptime: $($uptime.Days) days, $($uptime.Hours) hours"
# CPU and memory usage
$cpu = (Get-CimInstance Win32_Processor).LoadPercentage
$mem = Get-CimInstance Win32_OperatingSystem
$memUsed = [math]::Round(($mem.TotalVisibleMemorySize - $mem.FreePhysicalMemory) / 1MB, 1)
$memTotal = [math]::Round($mem.TotalVisibleMemorySize / 1MB, 1)
Write-Host "CPU: $cpu% | Memory: $memUsed/$memTotal GB"
# Performance counters
Get-Counter '\Processor(_Total)\% Processor Time', '\Memory\Available MBytes' -SampleInterval 2 -MaxSamples 5
Remote Management
# Manage Server Core from another machine
Enter-PSSession -ComputerName CORE-WEB01 -Credential (Get-Credential)
# Run commands on multiple servers
Invoke-Command -ComputerName CORE-WEB01, CORE-WEB02 -ScriptBlock {
Get-Service W3SVC
Get-Process | Sort-Object CPU -Desc | Select-Object -First 5
}
# Copy files to/from Server Core
Copy-Item "C:\local\file.txt" -Destination "C:\remote\file.txt" -ToSession $session
Copy-Item "C:\remote\logs\*.log" -Destination "C:\local\logs\" -FromSession $session
# Windows Admin Center (web-based GUI management)
# Install on a management server, connect to Server Core remotely
# Download from: https://aka.ms/wacdownload
Scheduled Tasks
# Create a scheduled task
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
-Argument "-ExecutionPolicy Bypass -File C:\Scripts\maintenance.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "3:00AM"
$settings = New-ScheduledTaskSettingsSet -RunOnlyIfNetworkAvailable -WakeToRun
Register-ScheduledTask -TaskName "Daily Maintenance" `
-Action $action -Trigger $trigger -Settings $settings `
-User "SYSTEM" -RunLevel Highest
# List tasks
Get-ScheduledTask | Where-Object State -eq "Ready" | Format-Table TaskName, State, LastRunTime
# Run task immediately
Start-ScheduledTask -TaskName "Daily Maintenance"
Best Practices
- Use Windows Admin Center for a web-based GUI when PowerShell is inconvenient
- Enable PowerShell remoting for remote management from a workstation
- Script everything: Document all configuration as PowerShell scripts for reproducibility
- Use Server Core for all production workloads — smaller attack surface, fewer updates
- Monitor with RSAT: Install Remote Server Administration Tools on your management workstation
- Regular updates: Server Core has significantly fewer updates than Desktop Experience