First steps on a new Windows server

What to do in the first ten minutes on a new Windows server, starting with the Administrator password.

Windows5 min read

On this page
  1. Why the password is step one
  2. Change the Administrator password
  3. Set the time zone
  4. Set the hostname
  5. Run Windows Update
  6. Check what is listening
  7. What to do next

A new Windows server arrives with a password that was sent to you by email, a clock that may be in the wrong time zone, a generic machine name, and months of missing patches. This page is the first ten minutes: change the password, set the time and the name, patch, and look at what is listening.

Do these in order. The password comes first for a reason, covered below.

Getting into the machine at all is a separate page. See Connecting to your server for the address, the Administrator username, and how to open a Remote Desktop session from Windows or macOS.

Why the password is step one

Port 3389 is scanned continuously. A Windows server that is reachable from the internet starts collecting sign-in attempts within hours of being given an address, and those attempts are automated: they try Administrator first, because it is the account every Windows machine has, against long lists of leaked and common passwords. Nobody has to target you for this to happen.

The password you were given travelled by email, which means it exists in at least one inbox and one mail server. Treat it as a delivery mechanism, not as a secret. Everything else on this page can wait an hour. This cannot.

Once you are signed in, you can see the attempts for yourself:

PowerShell
Get-WinEvent -FilterHashtable @{ LogName = "Security"; Id = 4625 } -MaxEvents 20 |
  Format-Table TimeCreated, Message -Wrap

Event 4625 is a failed sign-in. On a server that has been reachable for a day or two there are usually thousands. An empty result means either nothing has tried yet or failure auditing is switched off on this image, not that the server is hidden.

Change the Administrator password

Open PowerShell as Administrator and run:

PowerShell
$pw = Read-Host -Prompt "New password" -AsSecureString
Set-LocalUser -Name Administrator -Password $pw

Nothing appears on screen while you type. Set-LocalUser is present on Windows Server 2016 and later. On anything older, use:

PowerShell
net user Administrator *

which prompts for the password twice, also without echoing it.

Use a long random password from a password manager. The automated attempts described above are running against password lists, so the only property that matters is that yours is not on one.

The panel can also issue a fresh password for you from the Options tab, where the control is labelled Reset root password and resets Administrator on a Windows image. See Resetting the root password. That is the route to take when you have lost the password entirely. When you still have it, changing it from inside Windows is quicker and the new value never leaves the machine.

Once the password is changed, spend a few minutes on Hardening Remote Desktop. That page is the one that actually stops the automated attempts getting anywhere.

Set the time zone

Windows images are rarely in your time zone, and every log line, scheduled task, and certificate check reads from this clock.

PowerShell
Get-TimeZone
Get-TimeZone -ListAvailable | Select-Object Id, DisplayName
Set-TimeZone -Id "UTC"

The -Id value must be one of the Id strings from the second command, for example UTC, GMT Standard Time, India Standard Time, or Central European Standard Time. tzutil /l and tzutil /s "UTC" do the same job on older builds.

UTC is the better default on a server. It removes daylight-saving jumps from your logs and it matches what most other tooling records. Set it to local time only if a person will read the clock more often than a machine will.

Then confirm the clock is actually synchronised:

PowerShell
w32tm /query /status
w32tm /resync

Set the hostname

The image ships with a generated name such as WIN-4F9K2LQ8B31. Rename it now, while nothing depends on it:

PowerShell
Rename-Computer -NewName "web01" -Restart

The rename needs a reboot, which the -Restart switch performs immediately. Drop that switch if you would rather reboot later, but the old name stays in use until you do.

The name your server has in the panel is a separate label. Renaming Windows does not change it, and changing it in the panel does not rename Windows.

Run Windows Update

A freshly built image is as old as the image, which can be many months. Patch it before you put anything on it.

On Windows Server with Desktop Experience, open Settings, then Windows Update, and check for updates. On Server Core, run sconfig and use the update entry in the menu.

To drive it from PowerShell, install the PSWindowsUpdate module. It is a community module from the PowerShell Gallery rather than part of Windows, so this step involves trusting that source:

PowerShell
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Install-PackageProvider -Name NuGet -Force
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
Install-Module -Name PSWindowsUpdate -Force

Then list and apply:

PowerShell
Get-WindowsUpdate
Install-WindowsUpdate -AcceptAll -AutoReboot

Expect more than one reboot. Cumulative updates often uncover further updates underneath them, so run the check again after the machine comes back and keep going until it reports nothing outstanding.

Check what is listening

The last first-day task is to find out what the machine is offering to the internet, because that is the list an attacker is working from.

PowerShell
Get-NetTCPConnection -State Listen |
  Select-Object LocalAddress, LocalPort,
    @{ Name = "Process"; Expression = { (Get-Process -Id $_.OwningProcess).ProcessName } } |
  Sort-Object LocalPort

For UDP:

PowerShell
Get-NetUDPEndpoint |
  Select-Object LocalAddress, LocalPort,
    @{ Name = "Process"; Expression = { (Get-Process -Id $_.OwningProcess).ProcessName } } |
  Sort-Object LocalPort

Read the LocalAddress column as carefully as the port. 0.0.0.0 or :: means the service is bound to every interface, including the public one. 127.0.0.1 or ::1 means it is bound to the machine itself and nothing outside can reach it, whatever the firewall says.

A stock Windows Server listens on a handful of ports before you install anything: 135 for RPC endpoint mapping, 445 for SMB file sharing, 3389 for Remote Desktop, 5985 for WinRM, and a spread of high ports that RPC hands out dynamically. Anything beyond that set is something you or your software added.

Example output from a fresh server, trimmed. Every line is bound to 0.0.0.0, so each port answers on the public interface unless a firewall says otherwise. Of the stock set, only Remote Desktop belongs on the internet, and restricted; SMB on 445 never does. Example output, trimmed.

Of those, only Remote Desktop has any business being reachable from the internet, and even that should be restricted. SMB on 445 in particular is a standing target and should never be open to the world. Close what you are not using with Windows Firewall, and use Port rules in the panel to control what reaches the machine in the first place.

What to do next

Need a server, or a hand with one?

Pick a plan to deploy a server, or open a ticket in the panel. Support runs 24/7/365.