This script is intended to create 3 command line windows that repeatedly display ping results to three specific IPs on an intranet network so the status of each connection can be monitored at a glance (It also randomly selects tolerable window colors because it amused me at the time).
For reference this is running on a Windows 7 computer with Powershell 2.0 and is actually being executed via a batch file that uses the execution policy bypass because the computer is used by multiple users and is managed with a usergroup policy that unintentionally prevents the execution of some PS functions.
The problem with this script is it does not properly title each of the generated windows “Server 1”, “Server 2”, “Server 3”. Each window just ends up being titled “Ping 192.168.###.# -t”
The current script is this:
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class WindowManager {
[DllImport("user32.dll")]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
}
"@
$prompt_array = @(
@{Title="Server1"; IP="192.168.51.20"; Width=500; Height=500; Left=0; Top=0},
@{Title="Server2"; IP="192.168.101.20"; Width=500; Height=500; Left=0; Top=0},
@{Title="Server3"; IP="192.168.200.100"; Width=500; Height=500; Left=0; Top=0}
)
$colorsInvalid =@('01','09')
function Random_Colors {
$colors = (48..57 + 65..70) | ForEach-Object { [char]$_ } | ForEach-Object { $_.ToString() }
do {
$color1 = $colors | Get-Random
$color2 = $colors | Get-Random
$colorPair = $color1 + $color2
} while ($color1 -eq $color2 -or $colorsInvalid -contains $colorPair)
return $colorPair
}
$colorsLog = "C:Users1130538DesktopScriptLogcolorsLog.txt"
Set-Content -Path $colorsLog -Value $null
foreach ($window in $prompt_array) {
$prompt_color = Random_Colors
$logEntry = "{0}:{1} - Color Pair: {2}" -f $window.Title, $Window.IP, $prompt_color
Add-Content -Path $colorsLog -Value $logEntry
$cmd_prompt = Start-Process "cmd" -ArgumentList ("/k title " + $window.Title + " & color " + $prompt_color + " & ping " + $window.IP + " -t") -PassThru
Start-Sleep -Milliseconds 50
$hWnd = $cmd_prompt.MainWindowHandle
if ($hWnd -ne [IntPtr]::Zero) {
if ([WindowManager] -and [WindowManager]::MoveWindow) {
[WindowManager]::MoveWindow($hWnd, $window.Left, $window.Top, $window.Width, $window.Height, $true)
} else {
Write-Host "ERROR: Process could not be complete."
}
}
}
On Windows 10 this generates the appropriate windows with the correct titles, on Windows 7 it fails to title the windows at all.
I have re-written this a dozen different ways and I can not get it to work properly.
I tried a bunch of approaches, they all work on Windows 10 but none of them properly title the windows on Windows 7 where I need the script to run.
- Adding the title command to the script:
Start-Process cmd -ArgumentList "/k", "title Server1"
Start-Process cmd -ArgumentList "/k", "title Server2"
Start-Process cmd -ArgumentList "/k", "title Server3"
- Concatenation
$cmd_prompt = Start-Process "cmd" -ArgumentList ("/k title " + $window.Title + " & color " + $prompt_color + " & ping " + $window.IP + " -t") -PassThru
Conditional Chaining
Start-Process "cmd" -ArgumentList ("/k title " + $window.Title + " && color " + $prompt_color + " && ping " + $window.IP + " -t")
Loop Iteration
$titles = @("Server1", "Server2", "Server3")
foreach ($title in $titles) {
Start-Process cmd -ArgumentList "/k", "title $title"
}
Subshell Grouping
Start-Process "cmd" -ArgumentList "/k (title " + $window.Title + " & color " + $prompt_color + " & ping " + $window.IP + " -t)"
Command Pauses
Start-Process "cmd" -ArgumentList ("/k title " + $window.Title + " && timeout /t 1 && color " + $prompt_color + " && ping " + $window.IP + " -t")