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