- 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>
425 lines
16 KiB
HTML
425 lines
16 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>WinRM Setup Package for Shopfloor PCs</title>
|
|
<style>
|
|
* { box-sizing: border-box; }
|
|
body {
|
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
line-height: 1.6;
|
|
max-width: 900px;
|
|
margin: 0 auto;
|
|
padding: 20px;
|
|
background: #f5f5f5;
|
|
color: #333;
|
|
}
|
|
h1 {
|
|
color: #0078d4;
|
|
border-bottom: 3px solid #0078d4;
|
|
padding-bottom: 10px;
|
|
}
|
|
h2 {
|
|
color: #106ebe;
|
|
border-bottom: 1px solid #ddd;
|
|
padding-bottom: 5px;
|
|
margin-top: 30px;
|
|
}
|
|
h3 {
|
|
color: #333;
|
|
margin-top: 25px;
|
|
}
|
|
code {
|
|
background: #e8e8e8;
|
|
padding: 2px 6px;
|
|
border-radius: 3px;
|
|
font-family: 'Consolas', 'Courier New', monospace;
|
|
font-size: 0.9em;
|
|
}
|
|
pre {
|
|
background: #1e1e1e;
|
|
color: #d4d4d4;
|
|
padding: 15px;
|
|
border-radius: 5px;
|
|
overflow-x: auto;
|
|
font-family: 'Consolas', 'Courier New', monospace;
|
|
font-size: 0.85em;
|
|
line-height: 1.4;
|
|
}
|
|
pre code {
|
|
background: none;
|
|
padding: 0;
|
|
color: inherit;
|
|
}
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
margin: 15px 0;
|
|
background: white;
|
|
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
|
}
|
|
th, td {
|
|
padding: 10px 12px;
|
|
text-align: left;
|
|
border: 1px solid #ddd;
|
|
}
|
|
th {
|
|
background: #0078d4;
|
|
color: white;
|
|
font-weight: 600;
|
|
}
|
|
tr:nth-child(even) { background: #f9f9f9; }
|
|
tr:hover { background: #f0f7ff; }
|
|
hr {
|
|
border: none;
|
|
border-top: 1px solid #ddd;
|
|
margin: 30px 0;
|
|
}
|
|
.warning {
|
|
background: #fff3cd;
|
|
border-left: 4px solid #ffc107;
|
|
padding: 10px 15px;
|
|
margin: 15px 0;
|
|
}
|
|
.info {
|
|
background: #e7f3ff;
|
|
border-left: 4px solid #0078d4;
|
|
padding: 10px 15px;
|
|
margin: 15px 0;
|
|
}
|
|
ol, ul { padding-left: 25px; }
|
|
li { margin: 5px 0; }
|
|
.toc {
|
|
background: white;
|
|
padding: 15px 20px;
|
|
border-radius: 5px;
|
|
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
|
margin-bottom: 30px;
|
|
}
|
|
.toc h3 { margin-top: 0; }
|
|
.toc ul { list-style: none; padding-left: 0; }
|
|
.toc li { margin: 8px 0; }
|
|
.toc a { color: #0078d4; text-decoration: none; }
|
|
.toc a:hover { text-decoration: underline; }
|
|
.comment { color: #6a9955; }
|
|
.string { color: #ce9178; }
|
|
.keyword { color: #569cd6; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<h1>WinRM Setup Package for Shopfloor PCs</h1>
|
|
|
|
<p>This package provides scripts to configure WinRM (Windows Remote Management) on shopfloor PCs and execute remote maintenance tasks.</p>
|
|
|
|
<div class="toc">
|
|
<h3>Contents</h3>
|
|
<ul>
|
|
<li><a href="#quick-start">Quick Start</a></li>
|
|
<li><a href="#setup-details">Setup Script Details</a></li>
|
|
<li><a href="#tasks">Available Remote Tasks</a></li>
|
|
<li><a href="#troubleshooting">Troubleshooting</a></li>
|
|
<li><a href="#security">Security Considerations</a></li>
|
|
<li><a href="#custom-tasks">Adding Custom Tasks</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<h2>Package Contents</h2>
|
|
|
|
<table>
|
|
<tr><th>File</th><th>Description</th></tr>
|
|
<tr><td><code>Setup-WinRM.bat</code></td><td>Run on each PC to enable and configure WinRM</td></tr>
|
|
<tr><td><code>Invoke-RemoteTask.ps1</code></td><td>PowerShell script to execute tasks on remote PCs</td></tr>
|
|
<tr><td><code>hosts.txt</code></td><td>List of target computers (edit before use)</td></tr>
|
|
<tr><td><code>WinRM-Setup-Guide.html</code></td><td>This documentation</td></tr>
|
|
</table>
|
|
|
|
<hr>
|
|
|
|
<h2 id="quick-start">Quick Start</h2>
|
|
|
|
<h3>Step 1: Configure Your Admin Workstation</h3>
|
|
|
|
<p>Before connecting to remote PCs, run this <strong>once</strong> on your admin workstation (as Administrator):</p>
|
|
|
|
<pre><code>Set-Item WSMan:\localhost\Client\TrustedHosts -Value <span class="string">"*.logon.ds.ge.com"</span> -Force</code></pre>
|
|
|
|
<p>This allows your workstation to connect to any PC in the domain.</p>
|
|
|
|
<h3>Step 2: Configure the Setup Script</h3>
|
|
|
|
<p>Edit <code>Setup-WinRM.bat</code> and update these values at the top:</p>
|
|
|
|
<pre><code><span class="comment">REM Default security group - who can use WinRM to connect</span>
|
|
set "DEFAULT_SECURITY_GROUP=<span class="string">logon\groupid</span>"
|
|
|
|
<span class="comment">REM Where to log the inventory CSV (network share recommended)</span>
|
|
set "DEFAULT_LOG_PATH=<span class="string">\\server\share\winrm-inventory</span>"
|
|
|
|
<span class="comment">REM Domain suffix for TrustedHosts</span>
|
|
set "TRUSTED_DOMAIN=<span class="string">*.logon.ds.ge.com</span>"
|
|
|
|
<span class="comment">REM Optional: Trust a specific subnet (uncomment and set)</span>
|
|
<span class="comment">REM set "TRUSTED_SUBNET=10.48.130.*"</span></code></pre>
|
|
|
|
<h3>Step 3: Create Security Group in Active Directory</h3>
|
|
|
|
<ol>
|
|
<li>Open <strong>Active Directory Users and Computers</strong></li>
|
|
<li>Create a new Security Group (or use existing group matching <code>groupid</code>)</li>
|
|
<li>Add users who should have remote management access</li>
|
|
</ol>
|
|
|
|
<h3>Step 4: Run Setup on Each Shopfloor PC</h3>
|
|
|
|
<p>Run as Administrator on each PC:</p>
|
|
|
|
<pre><code>Setup-WinRM.bat</code></pre>
|
|
|
|
<p>Or with parameters:</p>
|
|
|
|
<pre><code>Setup-WinRM.bat "logon\groupid" "\\server\share\winrm-inventory"</code></pre>
|
|
|
|
<p>The script will:</p>
|
|
<ul>
|
|
<li>Enable WinRM service</li>
|
|
<li>Configure authentication (Negotiate/Kerberos)</li>
|
|
<li>Set firewall rules (domain profile only)</li>
|
|
<li>Restrict access to the security group</li>
|
|
<li>Log hostname/IP to CSV inventory</li>
|
|
</ul>
|
|
|
|
<h3>Step 5: Run Remote Tasks</h3>
|
|
|
|
<p>From your admin workstation, edit <code>hosts.txt</code> with target PCs, then:</p>
|
|
|
|
<pre><code><span class="comment"># Test connectivity</span>
|
|
.\Invoke-RemoteTask.ps1 -Task TestConnection
|
|
|
|
<span class="comment"># Restart print spooler on all hosts</span>
|
|
.\Invoke-RemoteTask.ps1 -Task RestartSpooler
|
|
|
|
<span class="comment"># Check disk space</span>
|
|
.\Invoke-RemoteTask.ps1 -Task GetDiskSpace
|
|
|
|
<span class="comment"># Run on a single PC</span>
|
|
.\Invoke-RemoteTask.ps1 -ComputerName <span class="string">"PC001"</span> -Task FlushDNS</code></pre>
|
|
|
|
<hr>
|
|
|
|
<h2 id="setup-details">Setup Script Details</h2>
|
|
|
|
<h3>What Setup-WinRM.bat Configures</h3>
|
|
|
|
<table>
|
|
<tr><th>Setting</th><th>Value</th><th>Purpose</th></tr>
|
|
<tr><td>WinRM Service</td><td>Auto-start</td><td>Ensures WinRM starts on boot</td></tr>
|
|
<tr><td>AllowUnencrypted</td><td>false</td><td>Security: require encrypted connections</td></tr>
|
|
<tr><td>Negotiate Auth</td><td>true</td><td>Enables Kerberos/NTLM authentication</td></tr>
|
|
<tr><td>CredSSP Auth</td><td>true</td><td>Enables credential delegation (double-hop)</td></tr>
|
|
<tr><td>Firewall</td><td>Domain profile</td><td>Opens port 5985 for domain connections only</td></tr>
|
|
<tr><td>TrustedHosts</td><td>*.logon.ds.ge.com</td><td>Trusts domain-joined PCs</td></tr>
|
|
<tr><td>RootSDDL</td><td>Security group</td><td>Restricts who can connect</td></tr>
|
|
</table>
|
|
|
|
<h3>CSV Inventory</h3>
|
|
|
|
<p>The setup script logs each PC to a CSV file:</p>
|
|
|
|
<pre><code>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</code></pre>
|
|
|
|
<p>You can use this CSV as your hosts file:</p>
|
|
|
|
<pre><code><span class="comment"># Extract hostnames from CSV</span>
|
|
Import-Csv <span class="string">"\\server\share\winrm-inventory\winrm-inventory.csv"</span> |
|
|
Select-Object -ExpandProperty Hostname |
|
|
Set-Content .\hosts.txt</code></pre>
|
|
|
|
<hr>
|
|
|
|
<h2 id="tasks">Available Remote Tasks</h2>
|
|
|
|
<table>
|
|
<tr><th>Task</th><th>Description</th></tr>
|
|
<tr><td><code>TestConnection</code></td><td>Verify WinRM connectivity</td></tr>
|
|
<tr><td><code>GetUptime</code></td><td>Show system uptime and last boot time</td></tr>
|
|
<tr><td><code>GetDiskSpace</code></td><td>Show free space on all drives</td></tr>
|
|
<tr><td><code>RestartSpooler</code></td><td>Restart Print Spooler service</td></tr>
|
|
<tr><td><code>FlushDNS</code></td><td>Clear DNS resolver cache</td></tr>
|
|
<tr><td><code>ClearTempFiles</code></td><td>Delete Windows temp files</td></tr>
|
|
<tr><td><code>DiskCleanup</code></td><td>Run Windows Disk Cleanup</td></tr>
|
|
<tr><td><code>OptimizeDisk</code></td><td>TRIM (SSD) or Defrag (HDD)</td></tr>
|
|
<tr><td><code>SyncTime</code></td><td>Force time sync with domain controller</td></tr>
|
|
<tr><td><code>RestartService</code></td><td>Restart any Windows service (requires <code>-ServiceName</code>)</td></tr>
|
|
<tr><td><code>RunCommand</code></td><td>Run custom PowerShell command (requires <code>-Command</code>)</td></tr>
|
|
<tr><td><code>RestartComputer</code></td><td>Restart the remote PC (requires YES confirmation)</td></tr>
|
|
</table>
|
|
|
|
<h3>Examples</h3>
|
|
|
|
<pre><code><span class="comment"># Check uptime on all hosts</span>
|
|
.\Invoke-RemoteTask.ps1 -Task GetUptime
|
|
|
|
<span class="comment"># Restart a specific service</span>
|
|
.\Invoke-RemoteTask.ps1 -Task RestartService -ServiceName <span class="string">"Spooler"</span>
|
|
|
|
<span class="comment"># Run custom command</span>
|
|
.\Invoke-RemoteTask.ps1 -Task RunCommand -Command <span class="string">"Get-Process | Sort CPU -Desc | Select -First 5"</span>
|
|
|
|
<span class="comment"># Use custom hosts file</span>
|
|
.\Invoke-RemoteTask.ps1 -HostsFile <span class="string">".\cnc-machines.txt"</span> -Task FlushDNS
|
|
|
|
<span class="comment"># Specify DNS suffix for short hostnames</span>
|
|
.\Invoke-RemoteTask.ps1 -DnsSuffix <span class="string">"logon.ds.ge.com"</span> -Task TestConnection
|
|
|
|
<span class="comment"># Restart a remote PC (will prompt for confirmation)</span>
|
|
.\Invoke-RemoteTask.ps1 -ComputerName <span class="string">"PC001"</span> -Task RestartComputer
|
|
|
|
<span class="comment"># Increase parallelism for faster execution on many PCs</span>
|
|
.\Invoke-RemoteTask.ps1 -Task FlushDNS -ThrottleLimit 20
|
|
|
|
<span class="comment"># Save results to a log file</span>
|
|
.\Invoke-RemoteTask.ps1 -Task GetDiskSpace -LogResults</code></pre>
|
|
|
|
<h3>Targeting Multiple PCs</h3>
|
|
|
|
<pre><code><span class="comment"># Comma-separated list</span>
|
|
.\Invoke-RemoteTask.ps1 -ComputerName <span class="string">"PC001"</span>,<span class="string">"PC002"</span>,<span class="string">"PC003"</span> -Task GetUptime
|
|
|
|
<span class="comment"># Array variable</span>
|
|
$pcs = @(<span class="string">"PC001"</span>, <span class="string">"PC002"</span>, <span class="string">"PC003"</span>)
|
|
.\Invoke-RemoteTask.ps1 -ComputerName $pcs -Task FlushDNS
|
|
|
|
<span class="comment"># From hosts.txt file (default)</span>
|
|
.\Invoke-RemoteTask.ps1 -Task RestartSpooler
|
|
|
|
<span class="comment"># From CSV inventory</span>
|
|
$pcs = (Import-Csv <span class="string">"\\server\share\winrm-inventory.csv"</span>).Hostname
|
|
.\Invoke-RemoteTask.ps1 -ComputerName $pcs -Task GetDiskSpace
|
|
|
|
<span class="comment"># From Active Directory query</span>
|
|
$pcs = (Get-ADComputer -Filter <span class="string">"Name -like 'SHOPFLOOR-*'"</span>).Name
|
|
.\Invoke-RemoteTask.ps1 -ComputerName $pcs -Task SyncTime</code></pre>
|
|
|
|
<div class="info">
|
|
<strong>Parallel Execution:</strong> All commands run in parallel (default: 10 concurrent connections). Adjust with <code>-ThrottleLimit</code> parameter.
|
|
</div>
|
|
|
|
<h3>Logging Results</h3>
|
|
|
|
<p>Use <code>-LogResults</code> to save task output to a timestamped log file in the script directory:</p>
|
|
|
|
<pre><code>.\Invoke-RemoteTask.ps1 -Task RestartSpooler -LogResults
|
|
<span class="comment"># Creates: RemoteTask_20260108_143022.log</span></code></pre>
|
|
|
|
<p>Log files contain:</p>
|
|
<ul>
|
|
<li>Task name and parameters</li>
|
|
<li>Execution time</li>
|
|
<li>Status of each computer (OK/FAIL)</li>
|
|
<li>Result messages</li>
|
|
<li>Summary totals</li>
|
|
</ul>
|
|
|
|
<hr>
|
|
|
|
<h2 id="troubleshooting">Troubleshooting</h2>
|
|
|
|
<h3>"Access Denied" when connecting</h3>
|
|
|
|
<ol>
|
|
<li>Verify you're a member of the WinRM security group</li>
|
|
<li>Check that your credentials are correct</li>
|
|
<li>Verify the target PC ran Setup-WinRM.bat successfully</li>
|
|
</ol>
|
|
|
|
<h3>"WinRM cannot complete the operation"</h3>
|
|
|
|
<ol>
|
|
<li>Verify the target PC is reachable: <code>ping PC001</code></li>
|
|
<li>Check WinRM is running on target: <code>sc query winrm</code> (on target PC)</li>
|
|
<li>Verify firewall allows port 5985</li>
|
|
</ol>
|
|
|
|
<h3>"The WinRM client cannot process the request"</h3>
|
|
|
|
<p>Add target to TrustedHosts on your admin workstation:</p>
|
|
|
|
<pre><code>Set-Item WSMan:\localhost\Client\TrustedHosts -Value <span class="string">"*.logon.ds.ge.com"</span> -Force</code></pre>
|
|
|
|
<h3>Test WinRM Configuration</h3>
|
|
|
|
<p>On your admin workstation:</p>
|
|
|
|
<pre><code><span class="comment"># Test basic connectivity</span>
|
|
Test-WSMan -ComputerName PC001
|
|
|
|
<span class="comment"># Test with credentials</span>
|
|
$cred = Get-Credential
|
|
Test-WSMan -ComputerName PC001 -Credential $cred -Authentication Negotiate
|
|
|
|
<span class="comment"># Enter interactive session</span>
|
|
Enter-PSSession -ComputerName PC001 -Credential $cred -Authentication Negotiate</code></pre>
|
|
|
|
<p>On the target PC:</p>
|
|
|
|
<pre><code>winrm enumerate winrm/config/listener
|
|
winrm get winrm/config/service</code></pre>
|
|
|
|
<hr>
|
|
|
|
<h2 id="security">Security Considerations</h2>
|
|
|
|
<div class="warning">
|
|
<strong>Important Security Notes:</strong>
|
|
</div>
|
|
|
|
<ol>
|
|
<li><strong>Use Security Groups</strong>: Always restrict WinRM access to a specific AD group</li>
|
|
<li><strong>Domain Profile Only</strong>: Firewall rules only allow connections on domain networks</li>
|
|
<li><strong>No Unencrypted Traffic</strong>: AllowUnencrypted is set to false</li>
|
|
<li><strong>Audit Access</strong>: Enable Windows Security auditing for logon events</li>
|
|
<li><strong>Credential Protection</strong>: Use dedicated admin accounts, not personal accounts</li>
|
|
</ol>
|
|
|
|
<hr>
|
|
|
|
<h2 id="custom-tasks">Adding Custom Tasks</h2>
|
|
|
|
<p>Edit <code>Invoke-RemoteTask.ps1</code> and add to the <code>$TaskScripts</code> hashtable:</p>
|
|
|
|
<pre><code><span class="string">'MyCustomTask'</span> = {
|
|
$result = @{
|
|
Success = <span class="keyword">$false</span>
|
|
Hostname = $env:COMPUTERNAME
|
|
Output = <span class="string">""</span>
|
|
Error = <span class="keyword">$null</span>
|
|
}
|
|
<span class="keyword">try</span> {
|
|
<span class="comment"># Your code here</span>
|
|
$result.Output = <span class="string">"Task completed"</span>
|
|
$result.Success = <span class="keyword">$true</span>
|
|
} <span class="keyword">catch</span> {
|
|
$result.Error = $_.Exception.Message
|
|
}
|
|
<span class="keyword">return</span> $result
|
|
}</code></pre>
|
|
|
|
<p>Then add the task name to the <code>ValidateSet</code> in the param block.</p>
|
|
|
|
<hr>
|
|
|
|
<h2>Support</h2>
|
|
|
|
<p>For issues or questions, contact your IT support team.</p>
|
|
|
|
<p style="text-align: center; color: #666; margin-top: 40px; font-size: 0.9em;">
|
|
WinRM Setup Package © 2026 | Generated from README.md
|
|
</p>
|
|
|
|
</body>
|
|
</html>
|