#!/p/kd/fdc/RHEL4/wermit +
#!/p/kd/fdc/solaris9/wermit +
#!/p/sy/subsys/scripts/wermit +
# IMPORTANT: The first line must indicate the path to C-Kermit 8.0.212 or 9.0
and there must be a + sign after the path, separated by a space.
# ilosetup: C-Kermit Script to configure an HP server through its
iLO management interface.
# Author: Frank da Cruz, Columbia University,
.scriptversion = 1.15
.scriptdate =
1.15 : Get to RBSU directly with ESC+9 in iLO3, which
avoids infinite DHCP query loop when machine is
not registered.
1.14 : Add notelnet option meaning don't even try to
connect to iLO with telnet.
1.13 : Allow for different response messages when attempting
to create an account that already exists and also
fix usage message to say ilo_userid
instead of ilo_username.
1.12 : Get iLO version number.
If 3 or higher do not attempt
certain oemhp configurations that have been discontinued.
Renamed MESSAGE macro to PMSG to avoid conflict.
1.11 : Added BIOS and POWERMODE:n options.
1.10 : Allow h
1.09 : Added raid / noraid option to configure RAID (or not);
added telnet and ssh options to specif
added iloonly option to only do iLO commands.
1.08 : Undo 1.07 because the command doesn't work on all models.
Fix echoing of username when typed in manually.
Capture iLO firmware version and record in log.
Don't produce a debug.log unless asked.
1.07 : Enable remote console acquire (spelled "aquire")
1.06 : Handle login failure on Telnet connections.
1.05 : Add 'usepassword' and 'nopassword'
Try both in specified order.
1.04 : Handle console login fai
Allow empty password in serials file.
1.03 : Remove IF WRITEABLE check for log directory
1.02 : Prompt for username if not in environment.
# Usage: [ ilo_userid=x ] [ ilo_userpass=y ] ilosetup hostname [ keywords ]
# After the hostname you can put zero or more of these keywords:
connect - make an interactive connection after logging in
debug - create a debug log (very big, only for Frank)
usepassword - try to log in first with a serials file password
nopassword - try to log in first with a blank password
nopoweroff - don't power the host machine off at the end
noreset - no reset at end
poweroff - power the host machine off at the end (default)
pwrmode:n - set power regulator mode to n (1-4)
raid - set Logical Drive 1 to RAID 1
bios - go straight to the BIOS prompt without doing anything else
noraid - Don't mess with RAID configuration (default)
iloonly - Only do iLO commands and don't reset or power off the server
quiet - only show error, warning, or status messages on the screen
reset - reset at end (default)
verbose - watch the script play on the screen (default)
# The keywords can be abbreviated to any unique left substring.
# Examples for host fillmore:
ilosetup fillmore
ilosetup fillmore poweroff
ilosetup fillmore pow (same as poweroff)
ilosetup fillmore pow q (poweroff and run quietly)
# The hostname should match (case independently) a hostname in the HP
# serials file, which is just the first part of the first field of the
# IP hostname, e.g. fillmore instead of fillmore-console.cc.columbia.edu.
# But if you do include the extra fields, the script allows for it.
# Exit status:
0 1 on failure.
# Creates in the log directory (logdirectory defined below):
A session log file xxx-session.log (xxx is the hostname)
(the log directory itself is created if it doesn't exist)
# Requires: C-Kermit 8.0.212 or later because it uses some recent features.
# Version 8.0.211 or earlier lack at least the following, which are used in
# this script:
. FSEEK /FIND:string
. The \fkwval() function
# (The script could be recoded at some effort to use older ways of doing
the same things.)
# If this script is run directly as if it were a shell command, the C-Kermit
# binary that executes it is the one in the "kerbang line" (the first line in
# the file).
Of course you can move the binary anywhere you want, or rename
# it, but then you have to change the kerbang line to match.
# Other dependencies:
. The HP serial numbers file (path defined a few lines down)
. That the first field in a serials file record is the simple hostname
(e.g. FILLMORE, not FILLMORE-CONSOLE or FILLMORE-CONSOLE.CC.COLUMBIA.EDU)
. That the corresponding iLO console password is the 6th field.
# Documentation: http://kermit.columbia.edu/cudocs/ilosetup.html
###############################################################################
.myname := \fbasename(\v(cmdfile))
# Name of this script without path
0 \flen(\$(DEBUG)) if numeric \$(DEBUG) if \$(DEBUG) .dodebug = 1
if \m(dodebug) {
echo DEBUGGING ON
echo ILO_USERID=[\$(ilo_userid)]
echo ILO_USERPASS=[\$(ilo_userpass)]
if not background set quiet off
# Allow messages (for foreground use)
set session-log text
# filter out escape sequences
set session-log timestamp
# Put timestamps in session log
# "Constant" definitions (that can be changed)...
.iloprompt = ">hpiLO-> "
# HP iLO console prompt
.logdirectory = /var/log/ilosetup
# Directory for session log
.outputpacing = 100
# Intercharter pacing for OUTPUT (msec)
.poweroff = 0
# Whether to power off at end
.connect = 0
# Make an interactive connection
.telnet = 1
# Default connection method is Telnet
.notelnet = 0
# Nonzero means there is no Telnet
.iloonly = 0
# Only do iLO commands
# and is not SSH
.reset = 1
# Reset at end
.dopassword = 1
# Use password from serials file
.doingraid = 0
# Don't configure RAID unless asked
.serialsfile = /p/sy/subsys/HP/serials
# Path of blade serial numbers file
.hostsuffix = -console.cc.columbia.edu
# Hostname suffix
.loginname = Administrator
# iLO login name
# Go straight to BIOS
.pwrmode = 0
# Change power mode value
.saidpwrmode = 0
# For checking power mode value
if equ "\v(user)" "fdc" {
# Development / testing
.logdirectory = ~/net/shrimp # (dev/test)
# if \m(dodebug) .serialsfile = ./serials
if \m(dodebug) show args
# development/test
# COMMAND TABLE: Define command-line option keywords
dcl \&k[] = bios poweroff nopoweroff verbose quiet telnet ssh help iloonly -
connect debug reset noreset usepassword nopassword raid noraid pwrmode -
array sort &k
# Alphabetize them for table lookup
# If command line is invalid give usage message and exit
def usage {
# Give usage message and exit
.verbose = "verbose"
.turnoff = "nopoweroff"
.doreset = "noreset"
.usepass = "nopassword"
.doraid = "raid"
if \m(notelnet) .telnet = 0
.dotelnet = "telnet"
if not \m(telnet) .dotelnet = "ssh"
"Usage: [ ilo_userid=x ] [ ilo_userpass=y ] \m(myname) hostname [ options ]"
echo "Options:"
show array k
if quiet .verbose = "quiet"
if \m(poweroff) .turnoff = "poweroff"
if \m(reset) .doreset = "reset"
if \m(dopassword) .usepass = "usepassword"
xecho "Default options: \m(verbose) \m(turnoff)"
echo " \m(dotelnet) \m(doreset) \m(usepass) \m(doraid)"
echo "Optional environment variables:"
echo " ilo_userid:
user ID to create"
echo " ilo_userpass: password for user ID"
echo " DEBUG=1: turn on debugging"
echo "If created user ID and password are not found in the environment,"
echo "you are prompted for them."
# Parse and validate command line
if not def \%1 {
echo "FATAL - A hostname is required"
# A hostname is required
.hostname := \flower(\fword(\%1,1,.))
# First field of hostname argument
.\%t := \findex(-console,\m(hostname))
# If "-console" found in hostname...
if \%t .hostname := \s(hostname[1:\%t-1]) # remove it.
.fullhost := \m(hostname)\m(hostsuffix) # Make full IP hostname
# Parse optional command-line keywords...
while defined \%2 {
# While we still have trailing commands
.tmp := \%2
# Get the next one
void \fkwval(\%2,=:)
# Split it in case it has an arg
.\%2 := \v(lastkwval)
# This is the command without the arg
if not def \%2 .\%2 := \v(tmp)
# Just in case...
.\%2 := \ftablelook(\%2,&k)
# Look up this keyword and get index
if < \%2 1 {
# Not found or ambiguous
echo "Invalid command-line option: '\m(tmp)'"
.\%2 := \&k[\%2]
# Resolve index to keyword itself
switch \%2 {
# Handle the keyword
# Go straight to BIOS
# Do iLO commands only
.iloonly = 1
.dodebug = 1
# Connect (interactive session)
.connect = 1
# Leave power off at end
.poweroff = 1
:nopoweroff
# Leave power on at end
.poweroff = 0
# Silent running (don't watch session)
set quiet on
set input echo off
# Show session on screen
set quiet off
set input echo on
# Reset at end (default)
.reset = 1
# No reset at end
.reset = 0
:usepassword
# Use password from serials file
.dopassword = 1
:nopassword
# Use empty password
.dopassword = 0
# Configure RAID 1 if RAID 0
.doingraid = 1
# Don't do anything with RAID
.doingraid = 0
# Try Telnet first
.telnet = 1
# Try ssh first
.telnet = 0
# Telnet is not allowed
.notelnet = 1
.telnet = 0
# Change power mode
.saidpwrmode = 1
# Remember they said to do this
# Go straight to BIOS for this
# Shift argument list to the left
if \m(saidpwrmode) {
# If they said "pwrmode"
# validate powermode argument
if not defined pwrmode exit 1 "FATAL - pwrmode requires numeric argument"
if not numeric \m(pwrmode) exit 1 "FATAL - pwrmode nonnumeric argument"
\m(pwrmode) 4 exit 1 "FATAL - pwrmode argument must be 1..4"
if \m(bios) .doingraid = 0
# Avoid conflicts - BIOS wins
# Macro definitions...
define logit {
# Write a message to session log
if not open session-log end 0
.\%1 := \frpad(\%1,7,.)
# Make fields line up
writeln session
# Make sure we're on a new line
writeln session "%% \%1 - \m(myname): \v(timestamp) [\m(hostname)] - \%2"
define pmsg {
# Print and log a progress message
if not quiet echo
# To avoid mixing up screen text
echo "[\v(timestamp)] MESSAGE - \%1" # Write message to screen (stdout)
logit MESSAGE "\%1"
# and to session log
define warn {
# Print and log warning message
if not quiet echo
# To avoid mixing up screen text
echo "WARNING - \%1"
# Write it to to stdout
logit WARNING "\%1"
# and to session log
define fatal {
# Fatal error
# Failure exit code
echo "FATAL - \%1"
# Write error message to screen
if \m(haveconnection) {
# If we have a connection
if not equ "\m(state)" "iLO" {
# but w're not in iLO...
output \{27}\{40}
# ESC+( - Escape back to iLO
input 8 \m(iloprompt)
# and wait 8 sec for the prompt
logit FATAL "\%1"
# write message to session log
logit INFO
"Most recent error: \v(errstring)"
define dotelnet {
set login user
# Force a login prompt
set host \m(fullhost)
# Try Telnet (port 23)
if fail end 1
# Return failure code if no go
input 10 "Login Name: "
# Wait for login prompt
if fail end 1 "Telnet Login Name timeout"
lineout \m(loginname)
# Send user ID
input 10 "password: "
# Wait for password prompt
if fail end 1 "Telnet password timeout"
define dossh {
set host /pty ssh -e none -l \m(loginname) \m(fullhost)
if fail end 1
# Watch out for RSA key fingerprint complaint and "are you sure?" prompt...
minput 20 "password: " "continue connecting (yes/no)? "
if fail end 1 "No response on SSH connection to \m(fullhost)"
if == \v(minput) 2 {
lineout "yes"
input 20 "password: "
if fail end 1 "SSH password timeout"
define getiloprompt {
# Get iLO prompt
if not def \%1 .\%1 = 40
# Default timeout (secs)
if not numeric \%1 fatal "Non-numeric INPUT timeout"
input \%1 \m(iloprompt)
# Wait for the prompt
if fail fatal "Timed out waiting for iLO CLI prompt."
define getiloversion {
# Sets global iloversion
local s &a
# from login herald
.\%9 := \findex({\{10}iLO },\v(input)) # Call this right after
.s := \fsubstring(\v(input),\%9+1,32)
# sending the login password
void \fsplit(\m(s),&a)
# and getting the first iLO prompt.
.iloversion = 0
if ( equ "\&a[1]" "iLO" && match "\&a[3]" "{Standard,Advanced}" ) {
if float \&a[2] .iloversion := \&a[2]
pmsg "iLO VERSION = \m(iloversion)"
define ilocommand {
# Send an iLO command and get response
# Local (stack) variable
.cmd := \fword(\%1,1)
# First word of command
# Pause 10 msec just in case
lineout \%1
# Send the full command
if fail fatal "Output failed"
# Check for i/o error
clear input
# Empty the INPUT result buffer
if equ "\m(cmd)" "vsp" {
clear input
getiloprompt \%2
# Get response and next iLO prompt
# The "power on/off" commands give no response...
if not equ "\%1" "power" {
# But "power" by itself does...
if equ "\m(cmd)" "power" end 0
.status = 9
# Dummy inital status value
.tmp := \freplace(\v(input),\13,)
# Strip carriage returns (but not LFs)
.lines := \fsplit(\m(tmp),&a,\10)
# Split captured text into lines
undef ilofirmware
# iLO firmware version
for i 1 lines 1 {
# Loop through lines
void \fkwval(\&a[i])
# to get status and message values...
if equ "\m(cmd)" "show" {
if def version .ilofirmware := \m(version) [\m(date)]
if def ilofirmware pmsg "iLO Firmware \m(ilofirmware)"
if not numeric \m(status) .status = 9 # Just in case
if == \m(status) 0 end 0
# If status was 0 then OK
if ( equ "\m(cmd)" "create" ) {
# In iLO 3 there is an extra blank line in the response.
if match "\&a[5]\&a[6]" "*Duplicate {login,user} name.*" {
# This is not an error
if ( equ "\m(cmd)" "set" && \findex(shared_console,\%1) ) {
if match "\&a[5]\&a[6]" "*Advanced License required*" {
pmsg "WARNING: HOST LACKS LICENSE for Shared Console"
# Change PMSG to FATAL if Advanced License should be there
# or if anything that follows depends on shared console.
if >= \m(iloversion) 3 {
if ( equ "\m(cmd)" "set" ) {
if \findex(oemhp_server_name,\%1) end 0
fatal "ILO COMMAND \%1: \m(error_tag)" # Fail with nonzero status
define rbsucommand {
# Send a command to RBSU and get next rbsu> prompt.
local i sleep pacing max
# Pause 10 msec just in case
lineout \%1
# Send the command
# Check for error response or next rbsu> prompt.
# Note: RBSU commands have no consist
# There may be some error responses that are not caught here...
minput 30 {rbsu>} {Invalid Command} {Incomplete Command} {Invalid Option}
if fail fatal "RBSU: Timeout after [\%1]"
if == \v(minput) 1 end 0
# No error message - done.
warn "RBSU COMMAND FAILURE [\%1]"
for i 1 \m(max) 1 {
# Try again this many times.
increment pacing 40
# Slower pacing each time.
warn "RETRYING WITH PACING = \m(pacing) msec..."
msleep 10*i
# Pause a little longer each time
lineout \%1
# Send the command
minput 30 {rbsu>} -
{Invalid Command} {Incomplete Command} {Invalid Option}
if fail fatal "RBSU: Timeout [\%1]"
if == \v(minput) 1 break
# No error message - done.
if > \m(i) \m(max) fatal "RBSU command error"
warn "RBSU COMMAND RECOVERY OK"
def xsleep {
# (for debugging display)
if not def \%1 .\%1 = 1
if quiet {
for i 1 \%1 1 { sleep 1, xecho . }
# Execution begins here: Get host password from HP serial numbers file...
.haveconnection = 0
# No connection yet
set input cancellation off
# Essential because of Esc sequences
set exit warning off
# Allow exit without warning
if \m(dodebug) directory \m(serialsfile) # Check and open serials file
if not exist \m(serialsfile) exit 1 "\m(serialsfile) not found"
if not readable \m(serialsfile) exit 1 "\m(serialsfile) not readable"
fopen /read \%c \m(serialsfile)
# Open serials file
if fail fatal
# Check for failure
# Seek to line with this hostname
fseek /find:"^\fupper(\m(hostname))[\9\32]" \%c 0
if fail fatal "Hostname [\m(hostname)] not found in HP serials file"
fread /line \%c line
# Read the line
fclose \%c
# Close the file
.\%n := \fsplit(\m(line),&a,,-)
# Split the line into words
.pass := \&a[6]
# The sixth word is the host password
if \m(dopassword) {
# 2-element password array
dcl \&p[2] = \m(pass) ""
# Try serials file password first
dcl \&p[2] =
"" \m(pass)
# Try blank password first
if \m(dodebug) show array p
# If this is a configuration run open the log file
if not \m(connect) {
if not directory \m(logdirectory) { # Check if log directory exists
fatal "Log directory \m(logdirectory) not found or not a directory"
cd \m(logdirectory)
# cd to the log directory
if fail fatal "cd \m(logdirectory)" # failure is fatal
.sessionlog := \m(logdirectory)/\m(hostname)-session.log # Session log name
log session \m(sessionlog)
# Open and start the session log
# Make session log in current directory
log session \m(hostname)-connect.log
if fail warn "FAILURE TO OPEN \m(sessionlog)"
pmsg "BEGIN ilosetup \m(scriptversion) \m(scriptdate)"
# Open the connection and log in
.protocol = "none"
# No protocol yet
if \m(telnet) {
# Try telnet first
pmsg "TRYING TELNET..."
# If it fails try ssh
# First close Telnet connection
pmsg "TELNET FAILED - TRYING SSH..."
if fail fatal "SSH \m(fullhost) failed."
.protocol = "ssh"
.protocol = telnet
# Try ssh first
pmsg "TRYING SSH..."
# If it fails try Telnet
# First close ssh connection
if \m(notelnet) "SSH \m(fullhost) failed."
pmsg "SSH FAILED - TRYING TELNET..."
if fail fatal "TELNET \m(fullhost) failed."
.protocol = telnet
.protocol = "ssh"
# If we arrive here we should have the password prompt.
# NOTE: This logic will need to be changed if it is possible to log in
# via SSH (or some secure form of Telnet) without a password.
.haveiloprompt = 0
for i 1 2 1 {
lineout \&p[i]
# Send console password
if fail fatal "Output password to \m(fullhost) failed."
minput 30 \m(iloprompt) "Permission denied" "Invalid login."
if fail fatal "Timed out waiting for iLO CLI prompt."
if == \v(minput) 1 {
.haveiloprompt = 1
if \m(dopassword) {
pmsg "Password from serials file failed - trying empty password..."
pmsg "Empty password failed - trying password from serials file..."
# After bad password Telnet prompts again for the username - ssh does not.
if eq "\m(protocol)" "telnet" {
input 10 "Login Name: "
if fail fatal "Telnet Login Name timeout"
lineout \m(loginname)
input 2 "password: "
if not quiet echo
if == \m(i) 2 fatal "Password not accepted"
if quiet continue
if not \m(haveiloprompt) fatal "iLO console login failure"
getiloversion
# Get iLO version number
# CONNECT - Go interactive and do not execute the rest of the script.
.haveconnection = 1
# Have connection
if \m(connect) {
# Interactive session requested
# Send a carriage return
# Connect to remote
if not open connection exit
# Exit from Kermit if connection closed
# Otherwise don't exit
if \m(bios) forward skipilocommands # If "go to Bios" jump ahead
# Automated configuration run...
# Prompt for created-user ID if it wasn't in the environment
.userid := \$(ilo_userid)
.userpass := \$(ilo_userpass)
while not defined userid {
# Prompt for created user ID
ask userid "User ID for created account: "
# Prompt for created-user password if it wasn't in the environment
while not defined userpass {
askq /echo:* userpass "Password for created account: "
if \m(dodebug) {
set debug timestamps on
log debug \m(hostname)-debug.log
# Send iLO commands...
.state = iLO
ilocommand "show /system1/firmware1"
# Get iLO firmware version
ilocommand "create /map1/accounts1 username=\m(userid) -
password=\m(userpass) group=admin,config,oemhp_vm,oemhp_rc,oemhp_power"
if = \m(i) \m(max) fatal "POWER ON DIDN'T TURN POWER ON"
# Enter VSP [virtual serial port]...
pmsg "Attempting to enter VSP..."
ilocommand "vsp"
input 30 "Virtual Serial Port Active"
if fail fatal "FAILURE TO ENTER VSP"
# Here we have to allow for many prompts and responses
# including a Device Status Request escape sequence from the host
# (ESC [ 5 n) which must be replied to.
(NOTE: doublequotes in
# the MINPUT text arguments have to be escaped as \{34}).
.sendesc9 = 0
while true {
minput 300 -
{Press \{34}ESC+9\{34} for ROM-Based Setup Utility} -
{Press \{34}ESC+0\{34} for System Maintenance Menu} -
{\27[5n} -
to run the Option ROM Configuration for Arrays Utility} -
{Requested service is unavailable\, it is already in use} -
{The server is not powered on} -
{The Virtual Serial Port is not available}
# If INPUT fails
output \{27}\{40}
# Escape back to iLO prompt
pmsg "INPUT: \v(inmessage)" # and back out from there.
if open connection {
# Is the connection still open?
fatal "INPUT FAILED WITH CONNECTION STILL OPEN"
fatal "CONNECTION CLOSED BY SERVER"
if == 1 \v(minput) {
# What we want in iLO 3
.sendesc9 = 1
# Remember that we did this
if == 2 \v(minput) break
# What we want in iLO 2...
if == 3 \v(minput) {
# Device Status Report Request
output \27[0n
# Send Device Status Report (I'm OK)
if \m(dodebug) echo SENT ESC [0n
if == 4 \v(minput) {
# If we are configuring RAID
if not \m(doingraid) continue
output \{27}8
# Send Esc 8
# and quit this loop
getiloprompt
# Soak up rest of message
lineout "exit"
# Exit from iLO
fatal "VSP service unavailable"
forward DONE
if not \m(doingraid) goto dorbsu
# If not doing RAID skip to next part
.havecli = 0
# Flag for have CLI prompt
input 20 "CLI> "
# Wait for CLI prompt
pmsg "Arrays CLI> prompt did not appear - skipping..."
forward dorbsu
.havecli = 1
set output pacing 200
# Can't blast characters at CLI prompt
clear input
# Clear INPUT buffer
lineout "physicaldrive * show"
# Show physical arrays
input 30 "CLI> "
# Wait for next CLI prompt
# Count the drives - \v(input) contains the results of the SHOW command"
.drives = 0
if \findex({Unknown Command},\v(input)) {
pmsg "Command 'physicaldrive * show' garbled - increase OUTPUT PACING"
forward dorbsu
if \findex({Invalid physical drive number specified},\v(input)) {
pmsg "Arrays CLI Invalid drive number specified - skipping"
forward dorbsu
.xx := \freplace(\v(input),\32,_)
# This solves a slight syntax problem
if \findex(Physical_Drive_#_1,\m(xx)) incr drives
if \findex(Physical_Drive_#_2,\m(xx)) incr drives
if \findex(Physical_Drive_#_3,\m(xx)) incr drives
if \findex(Physical_Drive_#_4,\m(xx)) incr drives
if \findex(Physical_Drive_#_5,\m(xx)) incr drives
if \findex(Physical_Drive_#_6,\m(xx)) incr drives
if \findex(Physical_Drive_#_7,\m(xx)) incr drives
if \findex(Physical_Drive_#_8,\m(xx)) incr drives
# Wait for next CLI prompt
pmsg "No CLI prompt after 'logicaldrive * show' after \v(inwait) secs"
.havecli = 0
forward dorbsu
.raid = -1
if \findex({Unknown Command},\v(input)) {
pmsg "Command 'logicaldrive * show' garbled - increase OUTPUT PACING"
forward dorbsu
.xx := \fsubstitute(\v(input),\32\44,_:) # Another syntax trick
if \findex({Logical_Drive_#_1:RAID_0},\m(xx)) .raid = 0
if \findex({Logical_Drive_#_1:RAID_1},\m(xx)) .raid = 1
# Wait for next CLI prompt
pmsg "No CLI prompt after 'logicaldrive 1 delete' after \v(inwait) secs"
.havecli = 0
forward dorbsu
clear input
# In case we want to collect text
lineout "controller create type=logicaldrive raid=1 drives=1,2"
# Note: when this succeeds there is no message at all.
# It takes about 20 seconds.
I don't know what any error messages would be.
input 30 "CLI> "
# Wait for next CLI prompt
if \m(havecli) {
# Exit from CLI if we were in it
lineout exit
# and wait for another menu
input 30 {Press "ESC+0" for System Maintenance Menu}
if \m(sendesc9) {
# In iLO 3 we can go straight to RBSU
input 30 {for Network Boot}
# (wait for this...)
# (wait a bit more...)
output \{27}9
# by "pressing" Esc (27) and 9
forward getrbsuprompt
output \{27}0
# Send ESC and 0
# Here it is waiting for a DHCP response which might never come.
input 120 "MMenu> "
# Get MMenu> prompt
fatal "Timed out waiting for MMenu> prompt"
.state = MMenu
# Have MMenu> prompt
# Send the RBSU command one char at a time because this prompt is VERY LOSSY
.sentrbsu = 0
clear input
# Clear the input buffer
for \%9 1 4 1 {
# Echoplex loop - try this four times
input 2*\%9 R
# Wait for the echo
if fail { lineout, continue }
# On failure send CR and start over
input 2*\%9 B
if fail { lineout, continue }
input 2*\%9 S
if fail { lineout, continue }
input 2*\%9 U
if fail { lineout, continue }
# Send carriage return
clear input
.sentrbsu = 1
if not \m(sentrbsu) fatal "Failure to send RBSU Command"
:getrbsuprompt
input 30 "rbsu> "
# Wait for rbsu> prompt
if fail fatal "Timed out waiting for first rbsu> prompt"
.state = rbsu
if ( \m(bios) && NOT \m(pwrmode) ) { # Go interactive to RBSU prompt
pmsg "Attempting to access BIOS..."
# Go interactive
forward DONE
# Upon return skip the rest
set output pacing \m(outputpacing)
# Throttle output speed
if \m(pwrmode) {
# Change power mode
rbsucommand "SHOW CONFIG HP POWER REGULATOR"
rbsucommand "SET CONFIG HP POWER REGULATOR \m(pwrmode)"
# Send the RBSU commands.
# Here we could give a SHOW CONFIG VIRTUAL SERIAL PORT command and parse
# the BIOS Serial Console Port menu choices in case the menu ever changes.
rbsucommand "SET CONFIG VIRTUAL SERIAL PORT 2"
rbsucommand "SET CONFIG BIOS SERIAL CONSOLE PORT 4"
rbsucommand "SET CONFIG BIOS SERIAL CONSOLE BAUD RATE 4"
rbsucommand "SET CONFIG EMS CONSOLE 3"
lineout EXIT
# Exit from RBSU
# Wait a sec and...
output \27(
# Escape back to iLO
getiloprompt
# Get iLO prompt
.state = iLO
# Our return code - assume success.
if not \m(poweroff) {
# Turn power off now?
if not \m(reset) pmsg "LE***ING POWER ON" # No...
forward DONE
pmsg "TURNING POWER OFF"
# How many times to try.
for i 1 \m(max) 1 {
# Loop for each try.
lineout "power off"
# Send power off command.
# Give it a little time
getiloprompt
# Get iLO prompt
lineout "power"
# Send "power" command to check
minput 30 {server power is currently: Off} {server power is currently: On}
if == \v(minput) 1 {
# Power is off
getiloprompt
# Read next iLO prompt
forward DONE
# Exit loop and skip ahead
# Sleep more each time
warn "RETRYING POWER OFF [\m(i)]..."
getiloprompt
warn "WARNING: POWER OFF FAILED AFTER \m(max) TRIES"
define fatal end 0
# No fatal errors from now on
if \m(haveconnection) {
# If we have a connection...
if \m(reset) {
# Reset the machine
.reset = 0
# Prevent recursion in case of error
pmsg "HARD RESET AND CLOSE"
ilocommand "cd /Map1"
lineout "reset"
close connection
# Close our end of the connection
if not \m(rc) {
pmsg "EXIT WITHOUT RESET"
lineout "exit"
# Exit from iLO
input 30 "CLI session stopped" # Wait for final gasp
if open connection hangup
# Close our end too just in case
.haveconnection = 0
pmsg "END: STATUS: \m(rc)"
if open session-log close session-log
# Close log
exit \m(rc)
# Exit from script and Kermit
; Local Variables:
; comment-column:40
; comment-start:"# "