How to Configure Windows Server 2022 with PowerShell
PowerShell is the primary management interface for Windows Server 2022. Whether you are managing a single server or hundreds, understanding how to configure and use PowerShell effectively is a prerequisite for any Windows Server administrator. This guide covers execution policy, running scripts correctly, essential cmdlets, remoting, service management, registry access, event log queries, scheduled tasks, and the choice between PowerShell ISE and Visual Studio Code for script development.
Understanding PowerShell Versions on Windows Server 2022
Windows Server 2022 ships with Windows PowerShell 5.1 built in. PowerShell 5.1 is the legacy version that comes with Windows and is installed at C:WindowsSystem32WindowsPowerShellv1.0powershell.exe. Microsoft also offers PowerShell 7.x (cross-platform, open source) as a separate install. Both can coexist on the same server. Check which version you are running:
# Check PowerShell version
$PSVersionTable
# Or specifically the version number
$PSVersionTable.PSVersion
For most server administration tasks, PowerShell 5.1 is sufficient. PowerShell 7.x offers better performance and modern language features, but some Windows-specific modules (like the ActiveDirectory module) work best on PowerShell 5.1. You can install PowerShell 7.x alongside 5.1 without conflict.
Setting the Execution Policy
By default, Windows Server 2022 sets the execution policy to Restricted, which prevents all scripts from running. For a server environment, you need to change this to permit administrative scripts while maintaining security. The RemoteSigned policy is the recommended balance — it allows locally written scripts to run freely but requires remote scripts to be digitally signed.
# View current execution policy for all scopes
Get-ExecutionPolicy -List
# Set RemoteSigned for the local machine (applies to all users)
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine -Force
# For a specific user scope only
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force
# Unrestricted (use only in isolated/dev environments)
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope LocalMachine -Force
# Bypass a single script without changing policy
PowerShell.exe -ExecutionPolicy Bypass -File "C:Scriptsdeploy.ps1"
The execution policy scopes from highest to lowest precedence are: MachinePolicy (Group Policy), UserPolicy (Group Policy), Process, CurrentUser, and LocalMachine. Group Policy overrides local settings, so if your policy reverts, check GPO.
Running PowerShell as Administrator
Many administrative cmdlets require elevation. There are several ways to launch an elevated PowerShell session on Server 2022:
# From Run dialog: Win+R, type:
powershell
# Right-click Start > Windows PowerShell (Admin) or Terminal (Admin)
# Launch elevated from an existing (non-elevated) PowerShell session
Start-Process powershell -Verb RunAs
# Check if current session is elevated
$currentPrincipal = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()
$isAdmin = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
Write-Host "Running as Administrator: $isAdmin"
Using Get-Command and Get-Help
Get-Command and Get-Help are the discovery tools that make PowerShell self-documenting. You should know these thoroughly before diving into other cmdlets.
# Find all cmdlets related to networking
Get-Command -Module NetTCPIP
Get-Command -Noun NetIPAddress
Get-Command *firewall*
# Find commands by verb
Get-Command -Verb Get | Where-Object { $_.Module -eq "NetTCPIP" }
# Get help for a specific cmdlet
Get-Help Get-NetIPAddress
Get-Help Get-NetIPAddress -Detailed
Get-Help Get-NetIPAddress -Examples
Get-Help Get-NetIPAddress -Online # Opens browser to docs
# Update help files (run as admin, requires internet)
Update-Help -Force
# Show all parameters of a cmdlet
(Get-Command Set-NetIPAddress).Parameters.Keys
Creating a PowerShell Profile
A PowerShell profile is a script that runs automatically every time you open a new PowerShell session. It is the place to define aliases, functions, and environment setup that you use repeatedly. There are multiple profile types — the most common one for a single user is $PROFILE.CurrentUserCurrentHost.
# Show the profile file paths
$PROFILE | Format-List *
# Check if a profile exists
Test-Path $PROFILE
# Create the profile if it does not exist
If (!(Test-Path $PROFILE)) {
New-Item -Path $PROFILE -ItemType File -Force
}
# Open profile for editing
notepad $PROFILE
# Example profile content to add:
# Set-Location C:
# function ll { Get-ChildItem -Force @args }
# function grep { Select-String @args }
# Set-Alias -Name np -Value notepad
# Write-Host "Server: $env:COMPUTERNAME | PS $($PSVersionTable.PSVersion)" -ForegroundColor Cyan
After saving the profile, reload it without restarting PowerShell:
. $PROFILE
PowerShell Remoting Overview
PowerShell Remoting allows you to run commands on remote computers. It uses the WinRM (Windows Remote Management) protocol over HTTP (port 5985) or HTTPS (port 5986). On Windows Server 2022, remoting is enabled by default for domain-joined machines but must be explicitly enabled for workgroup machines.
# Enable remoting on the local machine
Enable-PSRemoting -Force
# Run a single command on a remote server
Invoke-Command -ComputerName "WEB-SRV-02" -ScriptBlock { Get-Service W32Time }
# Run a command with credentials
$creds = Get-Credential
Invoke-Command -ComputerName "WEB-SRV-02" -Credential $creds -ScriptBlock { hostname }
# Open an interactive remote session
Enter-PSSession -ComputerName "WEB-SRV-02"
# Exit remote session
Exit-PSSession
# Run a local script on a remote machine
Invoke-Command -ComputerName "WEB-SRV-02" -FilePath "C:Scriptsaudit.ps1"
Managing Windows Services
Services are the backbone of Windows Server functionality. PowerShell provides complete control over service state, startup type, and configuration.
# List all services and their status
Get-Service
# Filter by status
Get-Service | Where-Object { $_.Status -eq "Stopped" }
Get-Service | Where-Object { $_.StartType -eq "Automatic" -and $_.Status -ne "Running" }
# Get a specific service
Get-Service -Name "W32Time"
Get-Service -Name "W32Time" | Select-Object *
# Start, stop, and restart services
Start-Service -Name "W32Time"
Stop-Service -Name "W32Time"
Restart-Service -Name "W32Time" -Force
# Change startup type
Set-Service -Name "W32Time" -StartupType Automatic
Set-Service -Name "Spooler" -StartupType Disabled
Set-Service -Name "W32Time" -StartupType Manual
# Start a service and set it to automatic in one block
Set-Service -Name "W32Time" -StartupType Automatic -Status Running
Working with the Windows Registry
PowerShell treats the Windows Registry as a file system drive. The HKLM: and HKCU: drives map to HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER respectively, and you use standard file system cmdlets to navigate and modify registry entries.
# Navigate registry like a file system
Set-Location HKLM:SOFTWAREMicrosoftWindows NTCurrentVersion
Get-ChildItem
# Read a registry value
Get-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersion" `
-Name "ProductName"
# Read all values in a key
Get-ItemProperty -Path "HKLM:SOFTWAREMicrosoftWindows NTCurrentVersion"
# Create a new registry key
New-Item -Path "HKLM:SOFTWAREMyApp" -Force
# Create or set a registry value (string)
Set-ItemProperty -Path "HKLM:SOFTWAREMyApp" -Name "Version" -Value "1.0" -Type String
# Create a DWORD value
Set-ItemProperty -Path "HKLM:SOFTWAREMyApp" -Name "Enabled" -Value 1 -Type DWord
# Delete a registry value
Remove-ItemProperty -Path "HKLM:SOFTWAREMyApp" -Name "Version"
# Delete an entire registry key
Remove-Item -Path "HKLM:SOFTWAREMyApp" -Recurse -Force
Querying Event Logs
Event logs are your primary diagnostic tool. PowerShell provides two ways to query them: the older Get-EventLog cmdlet (works on classic logs like System and Application) and the newer Get-WinEvent (works on all logs including modern ETW-based logs).
# List available classic logs
Get-EventLog -List
# Get the last 20 errors from the System log
Get-EventLog -LogName System -EntryType Error -Newest 20
# Filter by source and time range
Get-EventLog -LogName Application -Source "MSSQLSERVER" `
-After (Get-Date).AddDays(-7) -Newest 50
# Using the newer Get-WinEvent (more powerful)
Get-WinEvent -LogName "System" -MaxEvents 50
# Filter with hashtable (very fast)
Get-WinEvent -FilterHashtable @{
LogName = "System"
Level = 2 # 2 = Error, 3 = Warning, 4 = Information
StartTime = (Get-Date).AddHours(-24)
}
# Search event message for a keyword
Get-WinEvent -FilterHashtable @{ LogName = "Security"; Id = 4625 } |
Select-Object TimeCreated, Message | Format-List
Creating Scheduled Tasks with PowerShell
The ScheduledTasks module replaces the old schtasks command-line tool with proper PowerShell objects. Tasks have three components: a trigger (when to run), an action (what to run), and settings (how to run).
# Create a scheduled task that runs a script daily at 2:00 AM
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
-Argument "-ExecutionPolicy Bypass -File C:Scriptsbackup.ps1"
$Trigger = New-ScheduledTaskTrigger -Daily -At "02:00AM"
$Settings = New-ScheduledTaskSettingsSet `
-ExecutionTimeLimit (New-TimeSpan -Hours 2) `
-RestartCount 3 `
-RestartInterval (New-TimeSpan -Minutes 10) `
-MultipleInstances IgnoreNew
$Principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest
Register-ScheduledTask -TaskName "Daily Backup" `
-Action $Action -Trigger $Trigger `
-Settings $Settings -Principal $Principal `
-Description "Runs nightly backup script"
# List scheduled tasks
Get-ScheduledTask | Where-Object { $_.State -ne "Disabled" }
# Run a task manually
Start-ScheduledTask -TaskName "Daily Backup"
# Get task last run result
(Get-ScheduledTaskInfo -TaskName "Daily Backup").LastTaskResult
# Disable or remove a task
Disable-ScheduledTask -TaskName "Daily Backup"
Unregister-ScheduledTask -TaskName "Daily Backup" -Confirm:$false
PowerShell ISE vs Visual Studio Code
PowerShell ISE (Integrated Scripting Environment) was the traditional editor included with Windows. It is installed by default on Windows Server 2022 Desktop Experience. While functional for simple scripts, it has significant limitations: it only supports PowerShell 5.1, has no extension ecosystem, and receives no new features from Microsoft.
Visual Studio Code with the PowerShell extension is the recommended replacement. Install it on your development workstation and use remoting to target the server, rather than installing VS Code directly on a production server. The PowerShell extension provides IntelliSense, integrated debugging, multi-file editing, Git integration, and support for both PowerShell 5.1 and 7.x.
# Open PowerShell ISE (available on Desktop Experience only)
ise
# Or from PowerShell:
Start-Process powershell_ise.exe
# Install PowerShell 7 (to use with VS Code)
# Download the MSI from GitHub releases or use winget:
winget install Microsoft.PowerShell
# After installing, launch PS7 from VS Code terminal or:
pwsh
For production server work, write and test your scripts in VS Code on your workstation, then deploy them to the server via a file share, Git repository, or PSRemoting. Avoid using text editors on the server itself — Server Core installations have no GUI at all, making VS Code on your admin workstation even more essential.
Output Formatting and Export
PowerShell outputs objects, not text. Understanding how to format and export this output is critical for reporting and scripting.
# Format output as table
Get-Service | Format-Table -AutoSize
# Format as list (more detail per item)
Get-Service -Name "W32Time" | Format-List *
# Select specific properties
Get-Process | Select-Object Name, Id, CPU, WorkingSet | Sort-Object CPU -Descending
# Export to CSV
Get-Service | Export-Csv -Path "C:Reportsservices.csv" -NoTypeInformation
# Export to JSON
Get-NetIPAddress | ConvertTo-Json | Out-File "C:Reportsnetwork.json"
# Export to HTML report
Get-Process | ConvertTo-Html -Title "Process List" | Out-File "C:Reportsprocs.html"
With a solid understanding of execution policy, profile setup, remoting, service management, registry operations, event log querying, scheduled tasks, and scripting tools, you have the PowerShell foundation needed to manage Windows Server 2022 efficiently at scale.