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>
This commit is contained in:
296
winrm-setup-package/README.md
Normal file
296
winrm-setup-package/README.md
Normal file
@@ -0,0 +1,296 @@
|
||||
# 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):
|
||||
|
||||
```powershell
|
||||
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:
|
||||
|
||||
```batch
|
||||
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:
|
||||
|
||||
```cmd
|
||||
Setup-WinRM.bat
|
||||
```
|
||||
|
||||
Or with parameters:
|
||||
```cmd
|
||||
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:
|
||||
|
||||
```powershell
|
||||
# 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:
|
||||
|
||||
```csv
|
||||
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:
|
||||
```powershell
|
||||
# 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
|
||||
|
||||
```powershell
|
||||
# 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:
|
||||
|
||||
```powershell
|
||||
.\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
|
||||
|
||||
```powershell
|
||||
# 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:
|
||||
```powershell
|
||||
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*.logon.ds.ge.com" -Force
|
||||
```
|
||||
|
||||
### Test WinRM Configuration
|
||||
|
||||
On your admin workstation:
|
||||
```powershell
|
||||
# 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:
|
||||
```cmd
|
||||
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:
|
||||
|
||||
```powershell
|
||||
'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.
|
||||
Reference in New Issue
Block a user