[Powershell]Printserver der Fritzbox neustarten

Hallo,

meine Eltern beklagten sich schon seit längerem darüber, dass ihr Drucker sporadisch nicht drucken bzw. mitten im Druckjob abbrechen würde. Der Drucker ist per USB an eine Fritzbox 7170 angeschlossen und an den Clients per Socket eingebunden.

Ich schaute mir also den Status des USB-Hosts in der Fritzbox an und stellte fest, dass der Drucker im Leerlauf als “beim Drucken” angezeigt wurde.

Da war für mich klar, dass vermutlich der Printserver der Fritzbox das Problem sein würde.

Blöderweise gibt es auf der Fritzbox-Oberfläche keine Möglichkeit, das USB-Subsystem neuzustarten ohne die ganze Fritzbox neu starten zu müssen. Gut, der Anschluss ist keine Komponente, die jederzeit verfübar sein muss, trotzdem ist es nervig.

Ich hatte im Hinterkopf, dass die Fritzbox einen Telnet-Zugang hat. Als alter Linuxer dachte ich mir, dass man über die dann verfügbare Shell das USB-Subsystem per init-skript o.ä durchzustarten.

Genau so funktionierte es auch. Blöderweise verfügen meine Eltern nicht über die Fähigkeit sich per telnet zu connecten und den Service neuzustarten ^^. Ich überlegt also, wie man diesen Vorgang Automatisieren könnte.

Die Lösung: Powershell! Mit der Powershell besteht die Möglichkeit, eine TCP-Verbindung über einen bestimmten Port aufzubauen und darüber Kommandos auszuführen.

Hier also das Skript:

param(
[string] $remoteHost = "",
[int] $port = 23,
[string] $password = "",
[string] $command1 = "/etc/init.d/rc.usbhost stop",
[string] $command2 = "/etc/init.d/rc.usbhost start",
[int] $commandDelay = 1000
)
[string] $output = ""
## Read output from a remote host
function GetOutput
{
## Create a buffer to receive the response
$buffer = new-object System.Byte[] 1024
$encoding = new-object System.Text.AsciiEncoding
$outputBuffer = ""
$foundMore = $false
## Read all the data available from the stream, writing it to the
## output buffer when done.
do
{
## Allow data to buffer for a bit
start-sleep -m 1000
## Read what data is available
$foundmore = $false
$stream.ReadTimeout = 1000
do
{
try
{
$read = $stream.Read($buffer, 0, 1024)
if($read -gt 0)
{
$foundmore = $true
$outputBuffer += ($encoding.GetString($buffer, 0, $read))
}
} catch { $foundMore = $false; $read = 0 }
} while($read -gt 0)
} while($foundmore)
$outputBuffer
}
function Main
{
## Open the socket, and connect to the computer on the specified port
write-host "Connecting to $remoteHost on port $port"
trap { Write-Error "Could not connect to remote computer: $_"; exit }
$socket = new-object System.Net.Sockets.TcpClient($remoteHost, $port)
write-host "Connected. Press ^D followed by [ENTER] to exit.`n"
$stream = $socket.GetStream()
$writer = new-object System.IO.StreamWriter $stream
## Receive the output that has buffered so far
$SCRIPT:output += GetOutput
Start-Sleep -m $commandDelay
$writer.WriteLine($password)
$writer.Flush()
Start-Sleep -m $commandDelay
$writer.WriteLine($command1)
$writer.Flush()
Start-Sleep -m $commandDelay
$writer.WriteLine($command2)
$writer.Flush()
$SCRIPT:output += GetOutput
## Close the streams
$writer.Close()
$stream.Close()
$output | Out-File ("C:\Temp\$remoteHost.txt") #Change this to suit your environment
}
. Main