Hello,
in his office, a customer have a few Avocent KVM switches to control some client computers in a remote room. He ask me about the possibility to get a list of all computers connected to these boxes, because he do not want to maintain any list by hand.
I research the documention but there is no (scripting) interface from which I could get such a list. SSH is only for connecting serial consoles, SNMP offers no OIDs for such a case.
Because of the costs, DSView isn’t a option. The only way seems to be to extracting the list by reading the Webfrontend HTML output. Let us do this
I wrote a script in powershell, at least version 2 is needed to handle selfsigned SSL certificates, which do the following:
- Login to the Webfronted with https and SSL encryption by System.Net.HTTPWebRequest class to get the authentification cookie
- Get the Device HTML page by .NET class System.Net.Webclient and using Authentification cookie
- Save HTML do a temporary file
- Open the file with Internet Explorer
- Get the URL to start a KVM session, computername and portnumber by DOM
Script details
Define the User, Password, protocol and the devices:
1 2 3 4 5 6 7 8 | # KVM User [string] $sUser = "Admin" # KVM Password [string] $sPassword = "YourPassword" # Protocol [string] $sProtocol = "https" # Your Devices [String[]] $aAvocentDevices =@( "Console1.domain.local" , "Console2.domain.local" ) |
Built HTTP POST text and disable SSL certificate warnings
1 2 3 4 | [Byte[]] $aBody = [System.Text.Encoding] :: Default .GetBytes( "action=login&loginUsername=" + $sUser + "&loginPassword=" + $sPassword + "&language=de" ) [System.Net.CookieContainer] $oCookieContainer = New-Object System.Net.CookieContainer # Ignore SSL Certificate Warning, requires Powershell 2.0 [System.Net.ServicePointManager] ::ServerCertificateValidationCallback = { $true } |
Built the login POST request by using System.Net.HTTPWebRequest class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [string] $sLoginURL = $sProtocol + "://$sConsole/login.php" [System.Net.HTTPWebRequest] $oWebRequest = [System.Net.WebRequest] ::create( $sLoginURL ) $oWebRequest .AllowAutoRedirect = $false $oWebRequest .Method = "POST" $oWebRequest .Accept= "application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*" $oWebRequest .Headers.Add( "Accept-Encoding: gzip, deflate" ) $oWebRequest .Headers[ "Cache-Control" ] = "no-cache" ; $oWebRequest .UserAgent= "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; MS-RTC LM 8; InfoPath.2)" $oWebRequest .ContentType = "application/x-www-form-urlencoded" $oWebRequest .Timeout = ( [System.TimeSpan] ::FromSeconds(50)).TotalMilliseconds $oWebRequest .CookieContainer = $oCookieContainer $oWebRequest .ContentLength= $aBody .Length $oWebRequest .Referer= $sProtocol + "://$sConsole/login.php" $oWebRequest .CookieContainer.Add(( New-Object System.Net.Cookie( "/home.php-t1s" , "1" ," "," $sConsole "))); |
Getting the authentification cookie and set an avocent specific cookie
1 2 3 4 5 | # Try to login $oReqStream = $oWebRequest .GetRequestStream() $oReqStream .Write( $aBody , 0, $aBody .Length) [System.Net.HTTPWebResponse] $oResponse = $oWebRequest .getResponse() $oResponse .Headers[ "Set-Cookie" ]= "/home.php-t1s=1;" + $oResponse .Headers[ "Set-Cookie" ] |
Get the device list as html by using the authentification cookie
1 2 3 4 5 6 7 8 9 | $oWebClient = new-object system.net.webclient $oWebClient .Headers.add( "Cookie" , $oResponse .Headers[ "Set-Cookie" ]) $oWebClient .Headers.Add( "Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*" ) $oWebClient .Headers.Add( "Accept-Encoding: text/plain, text/html" ) # Devicelist as html $sHTML = $oWebClient .DownloadString( $sProtocol + "://$sConsole/target-table.php?id=1&colcnt=4" ) $oReqStream .Flush() $oReqStream .Close() $oResponse .Close() |
Save the HTML Output in a file and open it with Internet Explorer
1 2 3 4 5 6 7 8 9 10 | $sTempFile = [System.IO.Path] ::GetTempFileName()+ ".html" Set-Content -Path $sTempFile $sHTML $oIE = new-object -Com internetexplorer.application $oIE .Visible=1 write-host "file:///$sTempFile" $oIE .Navigate2( "file:///$sTempFile" ) while ( $oIE .busy){ Start-Sleep 1 write-host -nonewline "." } |
Get all devices by DOM (Document object model)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | for ( $iLoop =1; $iLoop -le 64; $iLoop ++){ $oEntry = $oIE .Document.getElementByID( "name$iLoop" ) if ( $oEntry ){ # Valid Entry $sDeviceName = $oEntry .innerHTML write-host "DEVICE: " $sDeviceName $oEntryLink = $oEntry .parentNode $oRegEx = new-object System.Text.RegularExpressions.Regex( "targetid=(\d{1,2})$" ) [Int16] $iTargetID =0 if ( [System.Int16] ::TryParse( $oRegEx .Match( $oEntryLink .href).Groups[1].Value, [ref] $iTargetID )){ if ( $iTargetID -gt 0){ $sURL = $sProtocol + "://" + $sConsole + "/session_launch.php?action=connect&sessionType=kvmLaunch&targetId=" + $iTargetID .ToString() Write-Host "PORT: " $iTargetID .ToString() write-host "KVM URL: " $sURL } } } } |
Finally quit IE and remove temporary files
1 2 | $oIE .Quit() Remove-Item -Force -Path $sTempFile |
You can download the whole script by opening the post. It should be easy to generate a website with all your devices. Enjoy the script
Michael
I struggled a lot with powershell and fiddler to mimic the login behavior to these avocent devices and was not able to. I did not even thinked the this kind of script will be available on the internet. Thank you very much!!!