Add scheduled maintenance, PC list export, and subnet scanner scripts
- Schedule-Maintenance.ps1: DPAPI credential storage + Task Scheduler integration - Export-PCList.ps1: Pull PC lists from ShopDB API with type/BU filtering - Find-ShopfloorPCs.ps1: Parallel subnet scanner with WinRM and DNS checks - INSTRUCTIONS.txt: Schedule-Maintenance.ps1 documentation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
223
remote-execution/Export-PCList.ps1
Normal file
223
remote-execution/Export-PCList.ps1
Normal file
@@ -0,0 +1,223 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Queries ShopDB API and exports a computer list for Invoke-RemoteMaintenance.ps1.
|
||||
|
||||
.DESCRIPTION
|
||||
Pulls shopfloor PC data from the ShopDB API and writes a text file
|
||||
(one hostname per line) compatible with:
|
||||
Invoke-RemoteMaintenance.ps1 -ComputerListFile "shopfloor-pcs.txt"
|
||||
|
||||
Can filter by PC type, business unit, or export all.
|
||||
|
||||
.PARAMETER PcType
|
||||
Filter by PC type. Omit for all types.
|
||||
|
||||
.PARAMETER BusinessUnit
|
||||
Filter by business unit. Omit for all BUs.
|
||||
|
||||
.PARAMETER OutputFile
|
||||
Output file path (default: shopfloor-pcs.txt in script directory).
|
||||
|
||||
.PARAMETER ApiUrl
|
||||
ShopDB API URL.
|
||||
|
||||
.PARAMETER IncludeDetails
|
||||
Add IP, PC type, and business unit as comments in the output.
|
||||
|
||||
.EXAMPLE
|
||||
.\Export-PCList.ps1
|
||||
# Export all shopfloor PCs
|
||||
|
||||
.EXAMPLE
|
||||
.\Export-PCList.ps1 -PcType Dashboard
|
||||
# Export only Dashboard PCs
|
||||
|
||||
.EXAMPLE
|
||||
.\Export-PCList.ps1 -BusinessUnit Blisk -OutputFile "blisk-pcs.txt"
|
||||
|
||||
.EXAMPLE
|
||||
.\Export-PCList.ps1 -PcType Dashboard,Shopfloor -BusinessUnit Blisk,HPT
|
||||
# Multiple filters (OR logic within each, AND between type/BU)
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[ValidateSet('Standard','Engineer','Shopfloor','CMM','Wax / Trace','Keyence',
|
||||
'Genspect','Heat Treat','Inspection','Dashboard','Lobby Display','Uncategorized')]
|
||||
[string[]]$PcType,
|
||||
|
||||
[ValidateSet('TBD','Blisk','HPT','Spools','Inspection','Venture','Turn/Burn','DT')]
|
||||
[string[]]$BusinessUnit,
|
||||
|
||||
[string]$OutputFile,
|
||||
|
||||
[string]$ApiUrl = "https://tsgwp00525.rd.ds.ge.com/shopdb/api.asp",
|
||||
|
||||
[switch]$IncludeDetails
|
||||
)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Lookup tables (match IDs in ShopDB)
|
||||
# ---------------------------------------------------------------------------
|
||||
$PcTypeLookup = @{
|
||||
'Standard' = 1; 'Engineer' = 2; 'Shopfloor' = 3; 'Uncategorized' = 4;
|
||||
'CMM' = 5; 'Wax / Trace' = 6; 'Keyence' = 7; 'Genspect' = 8;
|
||||
'Heat Treat' = 9; 'Inspection' = 10; 'Dashboard' = 11; 'Lobby Display' = 12
|
||||
}
|
||||
|
||||
$PcTypeReverse = @{}
|
||||
$PcTypeLookup.GetEnumerator() | ForEach-Object { $PcTypeReverse[$_.Value] = $_.Key }
|
||||
|
||||
$BusinessUnitLookup = @{
|
||||
'TBD' = 1; 'Blisk' = 2; 'HPT' = 3; 'Spools' = 4;
|
||||
'Inspection' = 5; 'Venture' = 6; 'Turn/Burn' = 7; 'DT' = 8
|
||||
}
|
||||
|
||||
$BusinessUnitReverse = @{}
|
||||
$BusinessUnitLookup.GetEnumerator() | ForEach-Object { $BusinessUnitReverse[$_.Value] = $_.Key }
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
function Write-Status {
|
||||
param([string]$Message, [string]$Level = "INFO")
|
||||
$timestamp = Get-Date -Format "HH:mm:ss"
|
||||
$color = switch ($Level) {
|
||||
"OK" { "Green" }
|
||||
"WARN" { "Yellow" }
|
||||
"ERROR" { "Red" }
|
||||
default { "Cyan" }
|
||||
}
|
||||
Write-Host "[$timestamp] [$Level] $Message" -ForegroundColor $color
|
||||
}
|
||||
|
||||
function Get-ShopfloorPCsFromApi {
|
||||
param(
|
||||
[string]$Url,
|
||||
[int]$PcTypeId = 0,
|
||||
[int]$BusinessUnitId = 0
|
||||
)
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
|
||||
$queryParams = "action=getShopfloorPCs"
|
||||
if ($PcTypeId -gt 0) {
|
||||
$queryParams += "&pctypeid=$PcTypeId"
|
||||
}
|
||||
if ($BusinessUnitId -gt 0) {
|
||||
$queryParams += "&businessunitid=$BusinessUnitId"
|
||||
}
|
||||
|
||||
$fullUrl = "$Url`?$queryParams"
|
||||
$webClient = New-Object System.Net.WebClient
|
||||
$json = $webClient.DownloadString($fullUrl)
|
||||
$response = $json | ConvertFrom-Json
|
||||
|
||||
if ($response.success -and $response.data) {
|
||||
return $response.data
|
||||
}
|
||||
return @()
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Default output path
|
||||
# ---------------------------------------------------------------------------
|
||||
if (-not $OutputFile) {
|
||||
$OutputFile = Join-Path $PSScriptRoot "shopfloor-pcs.txt"
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Query API
|
||||
# ---------------------------------------------------------------------------
|
||||
Write-Status "Querying ShopDB API..."
|
||||
|
||||
try {
|
||||
$allPCs = Get-ShopfloorPCsFromApi -Url $ApiUrl
|
||||
} catch {
|
||||
Write-Status "Failed to query API: $_" -Level "ERROR"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if ($allPCs.Count -eq 0) {
|
||||
Write-Status "API returned no PCs." -Level "ERROR"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Status "API returned $($allPCs.Count) total PCs" -Level "OK"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Filter
|
||||
# ---------------------------------------------------------------------------
|
||||
$filtered = $allPCs
|
||||
|
||||
if ($PcType) {
|
||||
$typeIds = $PcType | ForEach-Object { $PcTypeLookup[$_] }
|
||||
$filtered = $filtered | Where-Object { $_.pctypeid -in $typeIds }
|
||||
Write-Status "Filtered to PC types: $($PcType -join ', ') -> $($filtered.Count) PCs"
|
||||
}
|
||||
|
||||
if ($BusinessUnit) {
|
||||
$buIds = $BusinessUnit | ForEach-Object { $BusinessUnitLookup[$_] }
|
||||
$filtered = $filtered | Where-Object { $_.businessunitid -in $buIds }
|
||||
Write-Status "Filtered to business units: $($BusinessUnit -join ', ') -> $($filtered.Count) PCs"
|
||||
}
|
||||
|
||||
$filtered = @($filtered | Where-Object { $_.hostname })
|
||||
|
||||
if ($filtered.Count -eq 0) {
|
||||
Write-Status "No PCs match the selected filters." -Level "WARN"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Sort by hostname
|
||||
$filtered = $filtered | Sort-Object hostname
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Write output
|
||||
# ---------------------------------------------------------------------------
|
||||
$lines = [System.Collections.Generic.List[string]]::new()
|
||||
$lines.Add("# Shopfloor PC List - Generated $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')")
|
||||
$lines.Add("# Source: ShopDB API")
|
||||
|
||||
if ($PcType) {
|
||||
$lines.Add("# PC Type filter: $($PcType -join ', ')")
|
||||
}
|
||||
if ($BusinessUnit) {
|
||||
$lines.Add("# Business Unit filter: $($BusinessUnit -join ', ')")
|
||||
}
|
||||
|
||||
$lines.Add("# Total: $($filtered.Count) PCs")
|
||||
$lines.Add("# Usage: .\Invoke-RemoteMaintenance.ps1 -ComputerListFile `"$OutputFile`" -Task Reboot")
|
||||
$lines.Add("")
|
||||
|
||||
foreach ($pc in $filtered) {
|
||||
if ($IncludeDetails) {
|
||||
$typeName = $PcTypeReverse[[int]$pc.pctypeid]
|
||||
$buName = $BusinessUnitReverse[[int]$pc.businessunitid]
|
||||
$ip = if ($pc.ipaddress) { $pc.ipaddress } else { "no IP" }
|
||||
$lines.Add("$($pc.hostname) # $ip | $typeName | $buName")
|
||||
} else {
|
||||
$lines.Add($pc.hostname)
|
||||
}
|
||||
}
|
||||
|
||||
$lines | Out-File -FilePath $OutputFile -Encoding UTF8
|
||||
|
||||
Write-Status "Wrote $($filtered.Count) PCs to: $OutputFile" -Level "OK"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Summary
|
||||
# ---------------------------------------------------------------------------
|
||||
Write-Host ""
|
||||
Write-Host "=== PC LIST ===" -ForegroundColor White
|
||||
|
||||
# Group by type for summary
|
||||
$byType = $filtered | Group-Object pctypeid | Sort-Object Name
|
||||
foreach ($group in $byType) {
|
||||
$typeName = $PcTypeReverse[[int]$group.Name]
|
||||
if (-not $typeName) { $typeName = "Unknown ($($group.Name))" }
|
||||
Write-Host " $($typeName): $($group.Count)" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Output file: $OutputFile" -ForegroundColor Green
|
||||
Write-Host "Next step: .\Invoke-RemoteMaintenance.ps1 -ComputerListFile `"$OutputFile`" -Task Reboot" -ForegroundColor Yellow
|
||||
Reference in New Issue
Block a user