Files
cproudlock 86b32d8597 Add fixnetworkshare, winrm-setup-package, udc remote-execution suites
- 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>
2026-04-17 12:04:40 -04:00
..

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

  1. Open Active Directory Users and Computers
  2. Create a new Security Group (or use existing group matching groupid)
  3. 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

  1. Verify you're a member of the WinRM security group
  2. Check that your credentials are correct
  3. Verify the target PC ran Setup-WinRM.bat successfully

"WinRM cannot complete the operation"

  1. Verify the target PC is reachable: ping PC001
  2. Check WinRM is running on target: sc query winrm (on target PC)
  3. Verify firewall allows port 5985

"The WinRM client cannot process the request"

  1. 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

  1. Use Security Groups: Always restrict WinRM access to a specific AD group
  2. Domain Profile Only: Firewall rules only allow connections on domain networks
  3. No Unencrypted Traffic: AllowUnencrypted is set to false
  4. Audit Access: Enable Windows Security auditing for logon events
  5. 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.