From 918c0aea32e9300dffba5dd5dff69f3774614378 Mon Sep 17 00:00:00 2001 From: adminx Date: Wed, 11 Mar 2026 11:14:05 +0000 Subject: [PATCH] Delete PowerShell_How2_1 --- PowerShell_How2_1 | 834 ---------------------------------------------- 1 file changed, 834 deletions(-) delete mode 100644 PowerShell_How2_1 diff --git a/PowerShell_How2_1 b/PowerShell_How2_1 deleted file mode 100644 index ca13d58..0000000 --- a/PowerShell_How2_1 +++ /dev/null @@ -1,834 +0,0 @@ -# Windows SysAdmin PowerShell Command Reference -> Practical commands for day-to-day Windows Server administration — remote connections, file transfers, system management, and more. - ---- - -## Table of Contents -1. [Connecting to Remote Servers](#connecting-to-remote-servers) -2. [WinRM & PowerShell Remoting](#winrm--powershell-remoting) -3. [SSH from PowerShell](#ssh-from-powershell) -4. [Alternatives When WinRM Is Not Available](#alternatives-when-winrm-is-not-available) -5. [Remote File Copies & Transfers](#remote-file-copies--transfers) -6. [Remote System Administration](#remote-system-administration) -7. [Active Directory](#active-directory) -8. [DNS & DHCP Management](#dns--dhcp-management) -9. [Disk & Storage Management](#disk--storage-management) -10. [Event Logs](#event-logs) -11. [Windows Updates](#windows-updates) -12. [Certificates](#certificates) -13. [Scheduled Tasks (Remote)](#scheduled-tasks-remote) -14. [Registry (Remote)](#registry-remote) -15. [Firewall Management](#firewall-management) -16. [Performance & Health Checks](#performance--health-checks) -17. [Quick Diagnostic One-Liners](#quick-diagnostic-one-liners) - ---- - -## Connecting to Remote Servers - -### Enter-PSSession — Interactive Remote Shell -```powershell -Enter-PSSession -ComputerName SERVER01 -Enter-PSSession -ComputerName SERVER01 -Credential (Get-Credential) -Enter-PSSession -ComputerName SERVER01 -Credential "DOMAIN\adminuser" -``` -> Opens an **interactive PowerShell session** on the remote machine — similar to RDP but command-line only. Everything you type runs on the remote server. Type `Exit-PSSession` to disconnect. Requires WinRM to be enabled on the target. - ---- - -### Invoke-Command — Run Commands Remotely (Non-Interactive) -```powershell -# Run a single command on one server -Invoke-Command -ComputerName SERVER01 -ScriptBlock { Get-Service } - -# Run against multiple servers at once -Invoke-Command -ComputerName SERVER01, SERVER02, SERVER03 -ScriptBlock { - Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 5 -} - -# Pass a variable from your local machine into the remote block -$serviceName = "Spooler" -Invoke-Command -ComputerName SERVER01 -ScriptBlock { - Get-Service -Name $using:serviceName -} - -# Run a local script file on a remote server -Invoke-Command -ComputerName SERVER01 -FilePath "C:\Scripts\CheckHealth.ps1" - -# Run with alternate credentials -Invoke-Command -ComputerName SERVER01 -Credential "DOMAIN\admin" -ScriptBlock { - hostname -} -``` -> Best for **running commands or scripts on one or many servers without an interactive session**. Great for bulk administration — patch checks, service restarts, config audits. The `$using:` prefix passes local variables into the remote script block. - ---- - -### New-PSSession — Persistent Reusable Session -```powershell -# Create a session (stays open) -$session = New-PSSession -ComputerName SERVER01 -Credential "DOMAIN\admin" - -# Use the session multiple times -Invoke-Command -Session $session -ScriptBlock { Get-Process } -Invoke-Command -Session $session -ScriptBlock { Get-EventLog -LogName System -Newest 10 } - -# Copy files using the session (see also Copy-Item section) -Copy-Item "C:\Scripts\deploy.ps1" -Destination "C:\Scripts\" -ToSession $session - -# Enter interactively when needed -Enter-PSSession -Session $session - -# Clean up when done -Remove-PSSession $session - -# Manage multiple open sessions -Get-PSSession -Get-PSSession | Remove-PSSession # Close all sessions -``` -> Use persistent sessions when you need to **run multiple commands against the same server** without re-authenticating each time. Much more efficient than opening a new connection for every command. - ---- - -## WinRM & PowerShell Remoting - -> **WinRM (Windows Remote Management)** is the underlying service that enables PowerShell remoting. It must be configured on the target server before `Enter-PSSession` or `Invoke-Command` will work. - -### Enable WinRM on a Target Server -```powershell -# Run this ON the target server (or via GPO) -Enable-PSRemoting -Force - -# Verify WinRM is running -Get-Service WinRM -Test-WSMan -ComputerName SERVER01 -``` -> `Enable-PSRemoting` starts the WinRM service, sets it to automatic startup, and configures the firewall rules. Run this once on any server you want to manage remotely. - -### Configure Trusted Hosts (Workgroup / Non-Domain) -```powershell -# If servers are NOT domain-joined, you must explicitly trust them -Set-Item WSMan:\localhost\Client\TrustedHosts -Value "SERVER01" -Set-Item WSMan:\localhost\Client\TrustedHosts -Value "SERVER01,SERVER02,10.0.0.5" -Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*" # Trust all (lab use only) - -# View current trusted hosts -Get-Item WSMan:\localhost\Client\TrustedHosts -``` -> Domain-joined machines trust each other automatically via Kerberos. In workgroup or cross-domain environments you must add the target to TrustedHosts. **Avoid `*` in production.** - -### Test WinRM Connectivity -```powershell -Test-WSMan SERVER01 # Quick WinRM connectivity test -Test-WSMan SERVER01 -Credential (Get-Credential) # With credentials -Test-NetConnection SERVER01 -Port 5985 # Test WinRM HTTP port -Test-NetConnection SERVER01 -Port 5986 # Test WinRM HTTPS port -``` - ---- - -## SSH from PowerShell - -> OpenSSH is built into Windows 10/Server 2019 and later. PowerShell 7+ also supports SSH-based remoting natively — useful for Linux servers or when WinRM is unavailable. - -### Basic SSH Connection -```powershell -ssh username@SERVER01 # Connect to server -ssh admin@192.168.1.50 # Connect by IP -ssh -p 2222 admin@SERVER01 # Custom port -ssh admin@SERVER01 "hostname && uptime" # Run a command without interactive shell -``` - -### SSH Key Management -```powershell -# Generate an SSH key pair -ssh-keygen -t ed25519 -C "admin@company.com" - -# Copy public key to remote server (Linux target) -ssh-copy-id admin@linuxserver01 - -# For Windows targets, append to authorized_keys manually -$key = Get-Content "$env:USERPROFILE\.ssh\id_ed25519.pub" -Invoke-Command -HostName SERVER01 -UserName admin -ScriptBlock { - Add-Content "C:\ProgramData\ssh\administrators_authorized_keys" $using:key -} -``` - -### SSH Config File (~/.ssh/config) -``` -# Create C:\Users\YourName\.ssh\config to save connection shortcuts - -Host webserver - HostName 10.0.0.20 - User admin - IdentityFile ~/.ssh/id_ed25519 - -Host jumpbox - HostName bastion.company.com - User sysadmin - ForwardAgent yes -``` -```powershell -ssh webserver # Now connects using saved config -``` -> The SSH config file saves connection shortcuts so you don't need to retype IPs, usernames, and key paths every time. - -### PowerShell 7 SSH Remoting (Invoke-Command over SSH) -```powershell -# Works with both Windows and Linux targets -Invoke-Command -HostName linux01 -UserName root -ScriptBlock { uname -a } -Enter-PSSession -HostName SERVER01 -UserName admin - -# Create persistent SSH-based session -$sshSession = New-PSSession -HostName SERVER01 -UserName admin -Invoke-Command -Session $sshSession -ScriptBlock { Get-Process } -``` -> PowerShell 7 SSH remoting is particularly useful for **managing Linux servers from Windows** using the same PowerShell commands you already know. - ---- - -## Alternatives When WinRM Is Not Available - -> WinRM may be blocked by firewalls, disabled by policy, or not yet configured. These are your options. - -### Option 1 — RDP (Remote Desktop) via PowerShell -```powershell -# Launch RDP session to a server -mstsc /v:SERVER01 -mstsc /v:SERVER01 /admin # Connect to console session -mstsc /v:SERVER01:3390 # Custom RDP port - -# Check if RDP port is open before connecting -Test-NetConnection SERVER01 -Port 3389 - -# Enable RDP on a remote machine (requires admin share access) -Invoke-Command -ComputerName SERVER01 -ScriptBlock { - Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server" ` - -Name "fDenyTSConnections" -Value 0 - Enable-NetFirewallRule -DisplayGroup "Remote Desktop" -} -``` - -### Option 2 — PsExec (Sysinternals) -```powershell -# Download from Microsoft Sysinternals, then: -.\PsExec.exe \\SERVER01 cmd -.\PsExec.exe \\SERVER01 -u DOMAIN\admin -p password cmd -.\PsExec.exe \\SERVER01 powershell -Command "Get-Service" -.\PsExec.exe \\SERVER01 -s powershell # Run as SYSTEM account -``` -> PsExec uses **admin shares (C$, IPC$) over SMB** — it does not need WinRM. Very useful for one-off command execution on servers where remoting isn't set up. Requires the admin$ share to be accessible and the Remote Registry service running. - -### Option 3 — Admin Shares (UNC Path Access) -```powershell -# Access a remote server's filesystem directly via admin shares -Get-ChildItem \\SERVER01\C$\Logs -Get-ChildItem \\SERVER01\C$\Windows\System32\winevt\Logs - -# Copy files to/from remote server -Copy-Item \\SERVER01\C$\Logs\app.log C:\LocalLogs\ -Copy-Item C:\Scripts\fix.ps1 \\SERVER01\C$\Scripts\ - -# Map a drive to a remote share -New-PSDrive -Name S -PSProvider FileSystem -Root \\SERVER01\C$ -Credential "DOMAIN\admin" -Get-ChildItem S:\Logs -Remove-PSDrive S -``` -> Admin shares (`\\server\C$`, `\\server\Admin$`) let you **browse and copy files without WinRM** as long as you have admin rights and SMB (port 445) is accessible. Works even on older servers. - -### Option 4 — WMI / CIM (Windows Management Instrumentation) -```powershell -# Query remote system info via WMI (older, uses DCOM — port 135 + dynamic ports) -Get-WmiObject -Class Win32_OperatingSystem -ComputerName SERVER01 -Get-WmiObject -Class Win32_Service -ComputerName SERVER01 | Where-Object {$_.State -eq "Running"} - -# CIM is the modern replacement for WMI (uses WinRM by default, falls back to DCOM) -Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName SERVER01 -Get-CimInstance -ClassName Win32_LogicalDisk -ComputerName SERVER01 -Get-CimInstance -ClassName Win32_Service -ComputerName SERVER01 -Filter "State='Stopped'" - -# CIM over DCOM session (bypasses WinRM requirement) -$dcomOption = New-CimSessionOption -Protocol Dcom -$cimSession = New-CimSession -ComputerName SERVER01 -SessionOption $dcomOption -Credential "DOMAIN\admin" -Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $cimSession -Remove-CimSession $cimSession -``` -> WMI/CIM is powerful for **querying system info, hardware details, and running processes** without WinRM. CIM over DCOM is the go-to fallback when WinRM is blocked — uses port 135 and dynamic high ports. - -### Option 5 — Remote Registry -```powershell -# Requires Remote Registry service running on target -$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine", "SERVER01") -$key = $reg.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion") -$key.GetValue("ProductName") -$reg.Close() -``` -> Useful for **reading or writing registry keys on remote servers** without any remoting protocol. Requires the Remote Registry service to be started on the target. - -### Option 6 — Scheduled Tasks (Push-and-Run Pattern) -```powershell -# 1. Copy your script to the remote server via admin share -Copy-Item C:\Scripts\RunMe.ps1 \\SERVER01\C$\Scripts\ - -# 2. Register a scheduled task to run it immediately -$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:\Scripts\RunMe.ps1" -$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddSeconds(10) -Register-ScheduledTask -TaskName "AdminRemoteRun" -Action $action -Trigger $trigger ` - -RunLevel Highest -CimSession (New-CimSession SERVER01) -``` -> The **push-and-run** pattern works when you can write files via admin shares but can't run commands interactively. Copy the script over SMB, schedule it to run, and collect output from a log file. - -### Option 7 — PowerShell Web Access (PSWA) -```powershell -# Install on a gateway server (run once, as Admin) -Install-WindowsFeature WindowsPowerShellWebAccess -IncludeManagementTools -Install-PswaWebApplication -UseTestCertificate -Add-PswaAuthorizationRule -UserName "DOMAIN\admin" -ComputerName * -ConfigurationName * -``` -> PSWA provides a **browser-based PowerShell console** over HTTPS — useful when you need remote admin access without VPN or direct RDP. Access via `https://gateway/pswa`. - ---- - -## Remote File Copies & Transfers - -### Copy-Item Over PSSession -```powershell -# Copy FROM remote server TO local machine -$s = New-PSSession -ComputerName SERVER01 -Copy-Item -Path "C:\Logs\app.log" -Destination "C:\LocalLogs\" -FromSession $s - -# Copy FROM local machine TO remote server -Copy-Item -Path "C:\Scripts\deploy.ps1" -Destination "C:\Scripts\" -ToSession $s - -# Copy an entire folder recursively -Copy-Item -Path "C:\App\Config" -Destination "C:\App\" -ToSession $s -Recurse - -Remove-PSSession $s -``` -> The most reliable way to copy files when WinRM is available. **Works through the existing PS session** — no file share needed. - -### Robocopy — Robust File Copy for Servers -```powershell -# Basic copy -robocopy \\SERVER01\C$\Logs C:\LocalLogs - -# Mirror a folder (exact copy, deletes extras at destination) -robocopy \\SERVER01\C$\WebApp C:\Backup\WebApp /MIR - -# Copy with logging -robocopy \\SERVER01\C$\Data C:\Backup\Data /E /LOG:C:\Logs\robocopy.log - -# Copy only changed files, retry on failure -robocopy \\SERVER01\C$\Data C:\Backup /E /Z /R:3 /W:5 - -# Useful flags -# /E = include subdirectories (including empty) -# /MIR = mirror (sync + delete) -# /Z = restartable mode (resume interrupted transfers) -# /R:3 = retry 3 times on failure -# /W:5 = wait 5 seconds between retries -# /LOG = write output to log file -# /NP = no progress (cleaner log output) -# /XF = exclude files, e.g. /XF *.tmp *.log -# /XD = exclude directories -``` -> Robocopy is the **standard tool for large or reliable file transfers** in Windows environments. Handles network interruptions, permissions, and large directory trees far better than Copy-Item. - -### SCP — Secure Copy (SSH-based) -```powershell -# Copy file TO a remote server -scp C:\Scripts\deploy.sh admin@linuxserver01:/opt/scripts/ - -# Copy file FROM a remote server -scp admin@linuxserver01:/var/log/app.log C:\Logs\ - -# Copy entire folder -scp -r C:\Config admin@linuxserver01:/opt/config/ - -# Use a specific identity file -scp -i ~/.ssh/id_ed25519 C:\file.txt admin@server01:/tmp/ -``` -> SCP is ideal for **transferring files to/from Linux servers or any SSH-accessible host**. Available natively in Windows 10/Server 2019+. - -### SFTP — Interactive File Transfer -```powershell -sftp admin@linuxserver01 - -# Inside SFTP session: -# ls - list remote files -# lls - list local files -# get remote.txt - download file -# put local.txt - upload file -# cd /var/log - change remote directory -# lcd C:\Logs - change local directory -# exit - quit -``` - -### BitsTransfer — Background File Transfer -```powershell -# Download a file in the background -Start-BitsTransfer -Source "\\SERVER01\Share\largefile.zip" ` - -Destination "C:\Downloads\largefile.zip" -Asynchronous - -# Check transfer status -Get-BitsTransfer - -# Wait for all transfers to complete -Get-BitsTransfer | Complete-BitsTransfer -``` -> BITS (Background Intelligent Transfer Service) is designed for **large file transfers that can be paused and resumed**, throttled to not saturate the network. Originally designed for Windows Update, it's great for large deployment files. - ---- - -## Remote System Administration - -### Restart & Shutdown -```powershell -Restart-Computer -ComputerName SERVER01 -Force -Restart-Computer -ComputerName SERVER01 -Credential "DOMAIN\admin" -Force -Restart-Computer -ComputerName SERVER01 -Wait -For PowerShell -Timeout 300 # Wait for reboot - -Restart-Computer -ComputerName SERVER01, SERVER02, SERVER03 -Force # Reboot multiple - -Stop-Computer -ComputerName SERVER01 -Force # Shutdown -``` - -### Remote Service Management -```powershell -# Check service status on remote server -Get-Service -ComputerName SERVER01 -Name "Spooler" -Get-Service -ComputerName SERVER01 | Where-Object {$_.Status -eq "Stopped"} - -# Start/stop/restart -(Get-Service -ComputerName SERVER01 -Name "Spooler").Start() -(Get-Service -ComputerName SERVER01 -Name "Spooler").Stop() - -# Via Invoke-Command for more control -Invoke-Command -ComputerName SERVER01 -ScriptBlock { - Restart-Service -Name "W3SVC" -Force - Get-Service "W3SVC" | Select-Object Name, Status -} -``` - -### Remote Process Management -```powershell -# List processes on remote server -Get-Process -ComputerName SERVER01 -Get-Process -ComputerName SERVER01 | Sort-Object CPU -Descending | Select-Object -First 10 - -# Kill a process remotely -Stop-Process -Id 1234 -Force # (Must be inside Invoke-Command for remote) -Invoke-Command -ComputerName SERVER01 -ScriptBlock { Stop-Process -Name "app.exe" -Force } -``` - -### Check Who Is Logged On -```powershell -# Query logged-in users (uses query.exe) -Invoke-Command -ComputerName SERVER01 -ScriptBlock { query user } - -# Via WMI -Get-CimInstance -ClassName Win32_ComputerSystem -ComputerName SERVER01 | Select-Object UserName -``` - -### Remote Hotfix / Patch Check -```powershell -# Check installed patches on a remote server -Get-HotFix -ComputerName SERVER01 -Get-HotFix -ComputerName SERVER01 | Sort-Object InstalledOn -Descending | Select-Object -First 10 - -# Check multiple servers -$servers = @("SERVER01", "SERVER02", "SERVER03") -Invoke-Command -ComputerName $servers -ScriptBlock { - Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 1 -} | Select-Object PSComputerName, HotFixID, InstalledOn -``` - ---- - -## Active Directory - -> Requires the `ActiveDirectory` module (part of RSAT — Remote Server Administration Tools). -> Install: `Add-WindowsCapability -Name Rsat.ActiveDirectory* -Online` - -```powershell -Import-Module ActiveDirectory # Load the module - -# --- Users --- -Get-ADUser -Identity jsmith # Find a user -Get-ADUser -Filter {Name -like "John*"} # Search by name -Get-ADUser -Identity jsmith -Properties * # All properties -Get-ADUser -Filter {Enabled -eq $false} # Disabled accounts -Get-ADUser -Filter * -SearchBase "OU=Staff,DC=corp,DC=com" # Users in specific OU - -# Unlock, enable, disable -Unlock-ADAccount -Identity jsmith -Enable-ADAccount -Identity jsmith -Disable-ADAccount -Identity jsmith - -# Reset password -Set-ADAccountPassword -Identity jsmith -Reset ` - -NewPassword (ConvertTo-SecureString "NewP@ss123!" -AsPlainText -Force) -Set-ADUser -Identity jsmith -ChangePasswordAtLogon $true - -# --- Groups --- -Get-ADGroup -Identity "Domain Admins" -Get-ADGroupMember -Identity "Domain Admins" -Add-ADGroupMember -Identity "VPN_Users" -Members jsmith -Remove-ADGroupMember -Identity "VPN_Users" -Members jsmith -Confirm:$false - -# --- Computers --- -Get-ADComputer -Identity SERVER01 -Get-ADComputer -Filter {OperatingSystem -like "*Server 2022*"} -Get-ADComputer -Filter * | Where-Object {$_.LastLogonDate -lt (Get-Date).AddDays(-90)} # Stale - -# --- Password expiry --- -Get-ADUser -Filter * -Properties PasswordLastSet, PasswordExpired | - Where-Object { $_.PasswordExpired -eq $true } | - Select-Object Name, PasswordLastSet -``` - ---- - -## DNS & DHCP Management - -```powershell -# --- DNS (requires DnsServer module or RSAT) --- -Get-DnsServerZone -ComputerName DNS01 # List DNS zones -Get-DnsServerResourceRecord -ZoneName "corp.com" -ComputerName DNS01 # All records - -# Add an A record -Add-DnsServerResourceRecordA -Name "webserver" -ZoneName "corp.com" ` - -IPv4Address "10.0.0.50" -ComputerName DNS01 - -# Remove a record -Remove-DnsServerResourceRecord -ZoneName "corp.com" -RRType "A" -Name "webserver" -Force - -# Flush DNS cache on remote server -Invoke-Command -ComputerName SERVER01 -ScriptBlock { Clear-DnsClientCache } -Invoke-Command -ComputerName DNS01 -ScriptBlock { Clear-DnsServerCache } - -# --- DHCP (requires DhcpServer module or RSAT) --- -Get-DhcpServerv4Scope -ComputerName DHCP01 # List scopes -Get-DhcpServerv4Lease -ScopeId 10.0.0.0 -ComputerName DHCP01 # Active leases -Get-DhcpServerv4Reservation -ScopeId 10.0.0.0 -ComputerName DHCP01 # Reservations - -# Add a DHCP reservation -Add-DhcpServerv4Reservation -ScopeId 10.0.0.0 -IPAddress 10.0.0.100 ` - -ClientId "AA-BB-CC-DD-EE-FF" -Description "Printer" -ComputerName DHCP01 -``` - ---- - -## Disk & Storage Management - -```powershell -# Local and remote disk info -Get-PSDrive -PSProvider FileSystem # Drives and free space -Get-Volume # Volume details -Get-Disk # Physical disks -Get-Partition # Partition layout - -# Remote disk check via CIM -Get-CimInstance Win32_LogicalDisk -ComputerName SERVER01 | - Select-Object DeviceID, - @{N="SizeGB";E={[math]::Round($_.Size/1GB,1)}}, - @{N="FreeGB";E={[math]::Round($_.FreeSpace/1GB,1)}}, - @{N="Free%";E={[math]::Round($_.FreeSpace/$_.Size*100,1)}} - -# Check all servers for low disk space (under 15% free) -$servers = @("SERVER01","SERVER02","SERVER03") -Invoke-Command -ComputerName $servers -ScriptBlock { - Get-PSDrive -PSProvider FileSystem | - Where-Object { ($_.Free / ($_.Used + $_.Free)) -lt 0.15 } | - Select-Object Name, Used, Free, - @{N="Free%";E={[math]::Round($_.Free/($_.Used+$_.Free)*100,1)}} -} | Select-Object PSComputerName, Name, Free, "Free%" -``` - ---- - -## Event Logs - -```powershell -# Read event logs (local or remote) -Get-EventLog -LogName System -Newest 50 -Get-EventLog -LogName System -ComputerName SERVER01 -Newest 50 -Get-EventLog -LogName Application -EntryType Error -Newest 20 -Get-EventLog -LogName System -Source "Service Control Manager" -Newest 20 -Get-EventLog -LogName System -After (Get-Date).AddHours(-24) # Last 24 hours - -# Modern method using Get-WinEvent (more powerful, supports all logs) -Get-WinEvent -LogName System -MaxEvents 50 -Get-WinEvent -LogName "Microsoft-Windows-TaskScheduler/Operational" -MaxEvents 20 - -# Filter by event ID -Get-WinEvent -FilterHashtable @{ - LogName = "System" - Id = 7036 # Service started/stopped events - StartTime = (Get-Date).AddDays(-1) -} - -# Search for failed logins (Event ID 4625) -Get-WinEvent -ComputerName SERVER01 -FilterHashtable @{ - LogName = "Security" - Id = 4625 - StartTime = (Get-Date).AddHours(-24) -} | Select-Object TimeCreated, Message - -# Export event log to CSV -Get-EventLog -LogName System -Newest 100 | - Select-Object TimeGenerated, EntryType, Source, Message | - Export-Csv "C:\Logs\system-events.csv" -NoTypeInformation -``` - ---- - -## Windows Updates - -> Requires `PSWindowsUpdate` module: `Install-Module PSWindowsUpdate -Force` - -```powershell -Import-Module PSWindowsUpdate - -# Check for available updates -Get-WindowsUpdate - -# Install all updates -Install-WindowsUpdate -AcceptAll -AutoReboot - -# Install on a remote server -Invoke-WUJob -ComputerName SERVER01 -Script { - Import-Module PSWindowsUpdate - Install-WindowsUpdate -AcceptAll -AutoReboot | Out-File C:\Logs\WU.log -} -Confirm:$false - -# Check update history -Get-WUHistory | Select-Object -First 20 -Get-WUHistory -ComputerName SERVER01 | Where-Object {$_.Result -ne "Succeeded"} - -# Check last update time without module -Get-HotFix -ComputerName SERVER01 | Sort-Object InstalledOn -Descending | Select-Object -First 1 -``` - ---- - -## Certificates - -```powershell -# List certificates in local stores -Get-ChildItem Cert:\LocalMachine\My # Personal (server certs) -Get-ChildItem Cert:\LocalMachine\Root # Trusted root CAs -Get-ChildItem Cert:\CurrentUser\My # Current user certs - -# Find expiring certificates (within 60 days) -Get-ChildItem -Path Cert:\LocalMachine\My | - Where-Object { $_.NotAfter -lt (Get-Date).AddDays(60) } | - Select-Object Subject, Thumbprint, NotAfter - -# Check certs on a remote server -Invoke-Command -ComputerName SERVER01 -ScriptBlock { - Get-ChildItem Cert:\LocalMachine\My | - Where-Object { $_.NotAfter -lt (Get-Date).AddDays(60) } | - Select-Object Subject, NotAfter -} - -# Export a certificate (no private key) -Export-Certificate -Cert (Get-Item Cert:\LocalMachine\My\) ` - -FilePath "C:\Certs\server.cer" - -# Import a certificate -Import-Certificate -FilePath "C:\Certs\server.cer" -CertStoreLocation Cert:\LocalMachine\Root -``` - ---- - -## Scheduled Tasks (Remote) - -```powershell -# List tasks on a remote server -Get-ScheduledTask -CimSession (New-CimSession SERVER01) -Get-ScheduledTask -CimSession (New-CimSession SERVER01) | Where-Object {$_.State -eq "Ready"} - -# Run a scheduled task immediately on a remote server -Invoke-Command -ComputerName SERVER01 -ScriptBlock { - Start-ScheduledTask -TaskName "DailyBackup" -} - -# Check last run result of a task -Get-ScheduledTaskInfo -TaskName "DailyBackup" -CimSession (New-CimSession SERVER01) | - Select-Object LastRunTime, LastTaskResult, NextRunTime - -# 0 = success; anything else is an error code -``` - ---- - -## Registry (Remote) - -```powershell -# Read a remote registry key via Invoke-Command -Invoke-Command -ComputerName SERVER01 -ScriptBlock { - Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" | - Select-Object ProductName, CurrentBuild, ReleaseId -} - -# Write a registry value remotely -Invoke-Command -ComputerName SERVER01 -ScriptBlock { - Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` - -Name "SMB1" -Value 0 -Type DWORD -} - -# Check if SMBv1 is enabled across multiple servers -$servers = @("SERVER01","SERVER02","SERVER03") -Invoke-Command -ComputerName $servers -ScriptBlock { - $val = Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" ` - -Name "SMB1" -ErrorAction SilentlyContinue - [PSCustomObject]@{ - Server = $env:COMPUTERNAME - SMBv1 = if ($val.SMB1 -eq 0) { "Disabled" } else { "Enabled or Not Set" } - } -} -``` - ---- - -## Firewall Management - -```powershell -# View rules -Get-NetFirewallRule | Where-Object {$_.Enabled -eq "True" -and $_.Direction -eq "Inbound"} -Get-NetFirewallRule -DisplayName "*Remote*" -Get-NetFirewallRule | Where-Object {$_.Action -eq "Block"} - -# Add a rule -New-NetFirewallRule -DisplayName "Allow HTTPS Inbound" ` - -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow - -New-NetFirewallRule -DisplayName "Block Telnet" ` - -Direction Inbound -Protocol TCP -LocalPort 23 -Action Block - -# Enable/disable a rule -Enable-NetFirewallRule -DisplayName "Remote Desktop - User Mode (TCP-In)" -Disable-NetFirewallRule -DisplayName "Remote Desktop - User Mode (TCP-In)" - -# Remote firewall management via Invoke-Command -Invoke-Command -ComputerName SERVER01 -ScriptBlock { - New-NetFirewallRule -DisplayName "Allow App Port 8080" ` - -Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allow -} -``` - ---- - -## Performance & Health Checks - -```powershell -# CPU usage (top processes) -Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 Name, Id, CPU - -# Memory usage -Get-CimInstance Win32_OperatingSystem | - Select-Object @{N="TotalGB";E={[math]::Round($_.TotalVisibleMemorySize/1MB,1)}}, - @{N="FreeGB"; E={[math]::Round($_.FreePhysicalMemory/1MB,1)}} - -# Remote CPU and memory check across multiple servers -$servers = @("SERVER01","SERVER02","SERVER03") -Invoke-Command -ComputerName $servers -ScriptBlock { - $os = Get-CimInstance Win32_OperatingSystem - $cpu = (Get-CimInstance Win32_Processor | Measure-Object LoadPercentage -Average).Average - [PSCustomObject]@{ - Server = $env:COMPUTERNAME - "CPU%" = $cpu - "MemFreeGB" = [math]::Round($os.FreePhysicalMemory/1MB, 1) - "Uptime" = (Get-Date) - $os.LastBootUpTime - } -} | Select-Object PSComputerName, "CPU%", MemFreeGB, Uptime - -# Check uptime -(Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime - -# Remote uptime check -Invoke-Command -ComputerName SERVER01 -ScriptBlock { - $os = Get-CimInstance Win32_OperatingSystem - $up = (Get-Date) - $os.LastBootUpTime - "Uptime: {0} days, {1} hours, {2} min" -f $up.Days, $up.Hours, $up.Minutes -} -``` - ---- - -## Quick Diagnostic One-Liners - -```powershell -# Is a server reachable? -Test-Connection SERVER01 -Count 2 -Quiet - -# What ports are listening on a server? -Invoke-Command -ComputerName SERVER01 -ScriptBlock { - Get-NetTCPConnection -State Listen | Sort-Object LocalPort -} - -# Who has a file locked? -Invoke-Command -ComputerName FILESERVER01 -ScriptBlock { - Get-SmbOpenFile | Where-Object { $_.Path -like "*report.xlsx*" } -} - -# What's sharing on a server? -Get-SmbShare -CimSession (New-CimSession SERVER01) - -# Which servers in a list are online? -$servers = @("SERVER01","SERVER02","SERVER03","SERVER04") -$servers | ForEach-Object { - [PSCustomObject]@{ - Server = $_ - Online = (Test-Connection $_ -Count 1 -Quiet) - } -} - -# Check if a service exists and is running on multiple servers -$servers = @("SERVER01","SERVER02") -Invoke-Command -ComputerName $servers -ScriptBlock { - Get-Service -Name "W3SVC" -ErrorAction SilentlyContinue | - Select-Object MachineName, Name, Status -} - -# Get last reboot time across servers -$servers = @("SERVER01","SERVER02","SERVER03") -Invoke-Command -ComputerName $servers -ScriptBlock { - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime -} | Select-Object PSComputerName, @{N="LastBoot";E={$_}} - -# Find large files on a remote server -Invoke-Command -ComputerName SERVER01 -ScriptBlock { - Get-ChildItem C:\Logs -Recurse -File | - Sort-Object Length -Descending | - Select-Object FullName, @{N="SizeMB";E={[math]::Round($_.Length/1MB,1)}} | - Select-Object -First 20 -} - -# Check pending reboots -Invoke-Command -ComputerName SERVER01 -ScriptBlock { - $rebootKeys = @( - "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending", - "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" - ) - $pending = $rebootKeys | Where-Object { Test-Path $_ } - if ($pending) { "REBOOT PENDING" } else { "No reboot required" } -} -``` - ---- - -## Connection Method Summary - -| Method | Requires | Port | Best For | -|--------|----------|------|----------| -| `Enter-PSSession` | WinRM enabled | 5985/5986 | Interactive remote shell | -| `Invoke-Command` | WinRM enabled | 5985/5986 | Run scripts on one or many servers | -| SSH (`ssh`) | OpenSSH service | 22 | Linux targets, no WinRM | -| PsExec | Admin share, SMB | 445 | Quick commands, no WinRM setup | -| Admin Shares (`\\server\C$`) | SMB, admin rights | 445 | File access without remoting | -| CIM over DCOM | DCOM, RPC | 135 + dynamic | WMI queries without WinRM | -| RDP (`mstsc`) | RDP enabled | 3389 | GUI access | -| Remote Registry | Remote Registry svc | 445 | Registry edits without remoting | -| PSWA | IIS + PSWA role | 443 | Browser-based shell, no VPN |