- NetworkDriveManager.ps1: S: drive repair utility - winrm-setup-package: Invoke-RemoteTask helper + Setup-WinRM.bat + HTML guide - remote-execution/udc: UDC_Update.ps1 and batch wrappers for updating DNC controllers on shop-floor PCs - Invoke-RemoteMaintenance.ps1: substantial rework (~1650 lines) - Schedule-Maintenance and complete-asset minor updates - Bump edncfix gitlink to v1.6.0 (2748bfa) - .gitignore: block inventory.csv/xlsx (CUI) and logs_*.txt (per-host logs) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
8.3 KiB
WinRM Setup Package for Shopfloor PCs
This package provides scripts to configure WinRM (Windows Remote Management) on shopfloor PCs and execute remote maintenance tasks.
Contents
| File | Description |
|---|---|
Setup-WinRM.bat |
Run on each PC to enable and configure WinRM |
Invoke-RemoteTask.ps1 |
PowerShell script to execute tasks on remote PCs |
hosts.txt |
List of target computers (edit before use) |
README.md |
This documentation |
Quick Start
Step 1: Configure Your Admin Workstation
Before connecting to remote PCs, run this once on your admin workstation (as Administrator):
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*.logon.ds.ge.com" -Force
This allows your workstation to connect to any PC in the domain.
Step 2: Configure the Setup Script
Edit Setup-WinRM.bat and update these values at the top:
REM Default security group - who can use WinRM to connect
set "DEFAULT_SECURITY_GROUP=logon\groupid"
REM Where to log the inventory CSV (network share recommended)
set "DEFAULT_LOG_PATH=\\server\share\winrm-inventory"
REM Domain suffix for TrustedHosts
set "TRUSTED_DOMAIN=*.logon.ds.ge.com"
REM Optional: Trust a specific subnet (uncomment and set)
REM set "TRUSTED_SUBNET=10.48.130.*"
Step 3: Create Security Group in Active Directory
- Open Active Directory Users and Computers
- Create a new Security Group (or use existing group matching
groupid) - Add users who should have remote management access
Step 4: Run Setup on Each Shopfloor PC
Run as Administrator on each PC:
Setup-WinRM.bat
Or with parameters:
Setup-WinRM.bat "logon\groupid" "\\server\share\winrm-inventory"
The script will:
- Enable WinRM service
- Configure authentication (Negotiate/Kerberos)
- Set firewall rules (domain profile only)
- Restrict access to the security group
- Log hostname/IP to CSV inventory
Step 5: Run Remote Tasks
From your admin workstation, edit hosts.txt with target PCs, then:
# Test connectivity
.\Invoke-RemoteTask.ps1 -Task TestConnection
# Restart print spooler on all hosts
.\Invoke-RemoteTask.ps1 -Task RestartSpooler
# Check disk space
.\Invoke-RemoteTask.ps1 -Task GetDiskSpace
# Run on a single PC
.\Invoke-RemoteTask.ps1 -ComputerName "PC001" -Task FlushDNS
Setup Script Details
What Setup-WinRM.bat Configures
| Setting | Value | Purpose |
|---|---|---|
| WinRM Service | Auto-start | Ensures WinRM starts on boot |
| AllowUnencrypted | false | Security: require encrypted connections |
| Negotiate Auth | true | Enables Kerberos/NTLM authentication |
| CredSSP Auth | true | Enables credential delegation (double-hop) |
| Firewall | Domain profile | Opens port 5985 for domain connections only |
| TrustedHosts | *.logon.ds.ge.com | Trusts domain-joined PCs |
| RootSDDL | Security group | Restricts who can connect |
CSV Inventory
The setup script logs each PC to a CSV file:
Hostname,IPAddress,SetupDate,OSVersion,SecurityGroup
PC001,10.48.130.101,2026-01-08 09:30:00,10.0,logon\groupid
PC002,10.48.130.102,2026-01-08 09:35:00,10.0,logon\groupid
You can use this CSV as your hosts file:
# Extract hostnames from CSV
Import-Csv "\\server\share\winrm-inventory\winrm-inventory.csv" |
Select-Object -ExpandProperty Hostname |
Set-Content .\hosts.txt
Available Remote Tasks
| Task | Description |
|---|---|
TestConnection |
Verify WinRM connectivity |
GetUptime |
Show system uptime and last boot time |
GetDiskSpace |
Show free space on all drives |
RestartSpooler |
Restart Print Spooler service |
FlushDNS |
Clear DNS resolver cache |
ClearTempFiles |
Delete Windows temp files |
DiskCleanup |
Run Windows Disk Cleanup |
OptimizeDisk |
TRIM (SSD) or Defrag (HDD) |
SyncTime |
Force time sync with domain controller |
RestartService |
Restart any Windows service (requires -ServiceName) |
RunCommand |
Run custom PowerShell command (requires -Command) |
RestartComputer |
Restart the remote PC (requires YES confirmation) |
Examples
# Check uptime on all hosts
.\Invoke-RemoteTask.ps1 -Task GetUptime
# Restart a specific service
.\Invoke-RemoteTask.ps1 -Task RestartService -ServiceName "Spooler"
# Run custom command
.\Invoke-RemoteTask.ps1 -Task RunCommand -Command "Get-Process | Sort CPU -Desc | Select -First 5"
# Use custom hosts file
.\Invoke-RemoteTask.ps1 -HostsFile ".\cnc-machines.txt" -Task FlushDNS
# Specify DNS suffix for short hostnames
.\Invoke-RemoteTask.ps1 -DnsSuffix "logon.ds.ge.com" -Task TestConnection
# Restart a remote PC (will prompt for confirmation)
.\Invoke-RemoteTask.ps1 -ComputerName "PC001" -Task RestartComputer
# Increase parallelism for faster execution on many PCs
.\Invoke-RemoteTask.ps1 -Task FlushDNS -ThrottleLimit 20
# Save results to a log file
.\Invoke-RemoteTask.ps1 -Task GetDiskSpace -LogResults
Logging Results
Use -LogResults to save task output to a timestamped log file in the script directory:
.\Invoke-RemoteTask.ps1 -Task RestartSpooler -LogResults
# Creates: RemoteTask_20260108_143022.log
Log files contain:
- Task name and parameters
- Execution time
- Status of each computer (OK/FAIL)
- Result messages
- Summary totals
Targeting Multiple PCs
# Comma-separated list
.\Invoke-RemoteTask.ps1 -ComputerName "PC001","PC002","PC003" -Task GetUptime
# Array variable
$pcs = @("PC001", "PC002", "PC003")
.\Invoke-RemoteTask.ps1 -ComputerName $pcs -Task FlushDNS
# From hosts.txt file (default)
.\Invoke-RemoteTask.ps1 -Task RestartSpooler
# From CSV inventory
$pcs = (Import-Csv "\\server\share\winrm-inventory.csv").Hostname
.\Invoke-RemoteTask.ps1 -ComputerName $pcs -Task GetDiskSpace
# From Active Directory query
$pcs = (Get-ADComputer -Filter "Name -like 'SHOPFLOOR-*'").Name
.\Invoke-RemoteTask.ps1 -ComputerName $pcs -Task SyncTime
All commands run in parallel (default: 10 concurrent connections, adjust with -ThrottleLimit).
Troubleshooting
"Access Denied" when connecting
- Verify you're a member of the WinRM security group
- Check that your credentials are correct
- Verify the target PC ran Setup-WinRM.bat successfully
"WinRM cannot complete the operation"
- Verify the target PC is reachable:
ping PC001 - Check WinRM is running on target:
sc query winrm(on target PC) - Verify firewall allows port 5985
"The WinRM client cannot process the request"
- Add target to TrustedHosts on your admin workstation:
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*.logon.ds.ge.com" -Force
Test WinRM Configuration
On your admin workstation:
# Test basic connectivity
Test-WSMan -ComputerName PC001
# Test with credentials
$cred = Get-Credential
Test-WSMan -ComputerName PC001 -Credential $cred -Authentication Negotiate
# Enter interactive session
Enter-PSSession -ComputerName PC001 -Credential $cred -Authentication Negotiate
On the target PC:
winrm enumerate winrm/config/listener
winrm get winrm/config/service
Security Considerations
- Use Security Groups: Always restrict WinRM access to a specific AD group
- Domain Profile Only: Firewall rules only allow connections on domain networks
- No Unencrypted Traffic: AllowUnencrypted is set to false
- Audit Access: Enable Windows Security auditing for logon events
- Credential Protection: Use dedicated admin accounts, not personal accounts
Adding Custom Tasks
Edit Invoke-RemoteTask.ps1 and add to the $TaskScripts hashtable:
'MyCustomTask' = {
$result = @{
Success = $false
Hostname = $env:COMPUTERNAME
Output = ""
Error = $null
}
try {
# Your code here
$result.Output = "Task completed"
$result.Success = $true
} catch {
$result.Error = $_.Exception.Message
}
return $result
}
Then add the task name to the ValidateSet in the param block.
Support
For issues or questions, contact your IT support team.