Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
250 changes: 250 additions & 0 deletions .github/pdu/Pdu.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
# ======================================================================
#
# Manufacturer: Eaton Tripp Lite Switched Power Distribution Unit (PDU)
# Website: https://www.eaton.com/us/en-us/skuPage.PDUMH15NET.html
# Model: PDUMH15NET
# SNMP/Web Management Accessory Card: WEBCARDLX
#
# HW Requirements: Ethernet cable or USBA-to-MicroUSB cable.
# SW Requirements: Plink.exe from PuTTY terminal client SW (if Ethernet)
# PuTTY: https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html
#
# Script: PowerShell script for turning ON/OFF and power CYCLING the PDU
# Usage: .\Pdu.ps1 [on | off | cycle] [1-16]
#
# ======================================================================

param(
[Parameter(Mandatory=$true, Position=0)]
[ValidateSet("cycle","on","off")]
[string]$Action,

[Parameter(Mandatory=$true, Position=1)]
[ValidateRange(1,16)]
[int]$LoadNumber
)

# =========================
# Configuration
# =========================
$ComNumber = 3
$ComPort = "COM$ComNumber"

$PduIP = "169.254.0.1"
$SshPort = 22

$Username = "localadmin"
$Password = "@Password123"

$Plink = "C:\Program Files\PuTTY\plink.exe"

# =========================
# Helper Functions
# =========================

function Test-PduSerialConnection
{
[bool]$Connected = $false

try
{
$Port = New-Object System.IO.Ports.SerialPort $ComPort,115200,None,8,one
$Port.ReadTimeout = 3000
$Port.WriteTimeout = 3000
$Port.Open()
Start-Sleep 5
$Port.DiscardOutBuffer()
$Port.DiscardInBuffer()
$null = $Port.ReadExisting()

# Wake up console
$Port.WriteLine("")
Start-Sleep 2

$Banner = $Port.ReadExisting()
if ($Banner -match "login|localadmin|PowerAlert|Ubuntu") {
Write-Host "PDU detected on serial connection at $ComPort"
$Connected = $true
} else {
Write-Host "PDU NOT detected on serial connection at $ComPort" -ForegroundColor Yellow
}
}
catch
{
Write-Host "Unable to communicate on serial connection at $ComPort" -ForegroundColor Yellow
Write-Host $_.Exception.Message
}
finally
{
if ($Port -and $Port.IsOpen) {
$Port.DiscardOutBuffer()
$Port.DiscardInBuffer()
if ($Port.BytesToRead -gt 0) {
$null = $Port.ReadExisting()
}
$Port.Close()
}

$Port.Dispose()
$Port = $null
}
return $Connected
}

function Send-PduSerialCommand
{
param([string]$Action)

$Port = New-Object System.IO.Ports.SerialPort $ComPort,115200,None,8,one

try
{
$Port.ReadTimeout = 3000
$Port.WriteTimeout = 3000

$Port.Open()
Start-Sleep 5
$Port.DiscardOutBuffer()
$Port.DiscardInBuffer()
$null = $Port.ReadExisting()

Write-Host "Using SERIAL connection..." -ForegroundColor Green
$Port.WriteLine("")
Start-Sleep 2

Write-Host "Sending Username to PDU..."
$Port.WriteLine($Username)
Start-Sleep 2

Write-Host "Sending Password to PDU..."
$Port.WriteLine($Password)
Start-Sleep 5

# Sending [ cycle | on | off ] command to PDU.
Write-Host "Sending '$Action' command to PDU..."
$Port.WriteLine("device; load $LoadNumber; $Action force")
Start-Sleep 2

# "Sending Exit command to PDU..."
$Port.WriteLine("exit; exit; exit")
Start-Sleep 2
}
catch
{
Write-Host "Unable to communicate with $ComPort"
Write-Host $_.Exception.Message
}
finally
{
if ($Port -and $Port.IsOpen) {
$Port.DiscardOutBuffer()
$Port.DiscardInBuffer()
if ($Port.BytesToRead -gt 0) {
$null = $Port.ReadExisting()
}
$Port.Close()
Write-Host "Closed serial port $ComPort"
}
if ($Port)
{
$Port.Dispose()
}
$Port = $null
}
}

function Test-PduNetworkConnection
{
[bool]$Connected = $false

try
{
$Client = New-Object System.Net.Sockets.TcpClient
# $Client.Connect($PduIP,$SshPort)

$Result = $Client.BeginConnect($PduIP,$SshPort,$null,$null)
if (-not $Result.AsyncWaitHandle.WaitOne(3000))
{
throw "Connection timeout"
}
$Client.EndConnect($Result)

$Stream = $Client.GetStream()
Start-Sleep 1

$Buffer = New-Object byte[] 1024
$Stream.ReadTimeout = 3000
$Bytes = $Stream.Read($Buffer,0,$Buffer.Length)

$Banner = [System.Text.Encoding]::ASCII.GetString($Buffer,0,$Bytes)

if ($Banner -match "login|localadmin|PowerAlert|Ubuntu") {
Write-Host "PDU detected on network connection at IP: $PduIP, Port: $SshPort"
$Connected = $true
}
else {
Write-Host "PDU NOT detected on network connection at IP: $PduIP, Port: $SshPort" -ForegroundColor Yellow
}

$Client.Close()
}
catch
{
Write-Host "Unable to establish network connection at IP: $PduIP, Port: $SshPort" -ForegroundColor Yellow
Write-Host $_.Exception.Message
}
return $Connected
}

function Send-PduNetworkCommand
{
param([string]$Action)

if (-not (Test-Path $Plink))
{
throw "plink.exe not found: $Plink"
}

Write-Host "Using NETWORK connection..." -ForegroundColor Green

$Command = "device; load $LoadNumber; $Action force; exit; exit; exit"

$Command | & $Plink `
-ssh `
-batch `
-pw $Password `
"$Username@$PduIP" `
}

# =========================
# Main Logic
# =========================

Write-Host ""
Write-Host "Requested Action : $Action"
Write-Host ""

# First choice = Serial
if (Test-PduSerialConnection)
{
Send-PduSerialCommand $Action
exit 0
}

Write-Host "Serial connection not available."
Write-Host "Trying network connection..."

# Second choice = Network
if (Test-PduNetworkConnection)
{
Send-PduNetworkCommand $Action
exit 0
}

Write-Host ""
Write-Host "ERROR: No PDU connection available." -ForegroundColor Red
Write-Host " Serial : $ComPort"
Write-Host " Ethernet : $PduIP"
Write-Host ""

exit 1
65 changes: 65 additions & 0 deletions .github/pdu/PduReadme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# PDU Setup: <br>Eaton Tripp Lite Switched Power Distribution Unit (PDUMH15NET)

## Requirements:
### HW:
- USBA-to-MicroUSB cable, needed for 1st time PDU login and password change, if IP address is unknown.
- Ethernet cable, can be used if the IP address is known.
### SW:
- [Tera Term 5.6.1 terminal client:](https://github.com/TeraTermProject/teraterm/releases/tag/v5.6.1)
- Terminal client for PDU login and configuration via serial.
- [PuTTY 0.84 terminal client:](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html)
- `Plink.exe` needed for PowerShell scripting via network.
- **Note**: PuTTY terminal client GUI does not appear to work, so Tera Term client was used instead, but `Plink.exe` is needed for passing passwords via SSH in PowerShell scripts.

## Serial Connection
### What's my IP address?
- If the PDU is connected to a network with **DHCP**, then we need to find it's IP address first by using serial connection.
- If the PDU is not connected to a network with DHCP, then its default static IP address should be `169.254.0.1`.
- If that's the case, then you can login to the PDU via a browser by skipping the the section Network Connection.

Tera Term:
- Connect the PC to the PDU (CONFIG port) with a USBA-to-MiniUSB cable.
- On the PC, go to Device Manager and verify under `Ports (COM & LPT)`, the `USB Serial Device (COM3)` device is present.
- Download and install Tera Term on PC, if not already present.
- You may use other Terminal Emulation Programs, but this is the one used in the manufacturer's user manual to connect to the WEBCARDLX network interface card.
- Launch Tera Term and select the "Serial" connection type and ensure `Port: "COM3: USB Serial Device (COM3)` is selected, then click "OK".
- When the blinking cursor in the empty prompt stops blinking, hit Enter key to wake up console.
- The `Ubuntu 18.04.6 LTS poweralert-0006674a215f` (<-- MAC Address) should show up in the prompt asking for login.
- Default login is: `localadmin`
- Default 1st time password is: `localadmin`
- Must change password after 1st logon.
- Change password to `@Password123` to match what the `pdu.ps1` PowerShell script uses.
- Once logged in, type `show network` to display network information such as current IP address.
- If on DHCP network, note the IP address assigned to the PDU.
- PDU default if no DHCP:
- IPv4: `169.254.0.1`
- Subnet Mask: `255.255.0.0`
- Test pinging the IPv4 address of the PDU from the PC.
- `ping <IP Address>`
- Now that you have the IP address, it may be easier to switch over to the browser interface to configure the rest of the PDU.

## Network Connection
- Connect an Ethernet cable from the PC to the PDU Ethernet port.
- Since we have the IP of the PDU, it's easier to configure the PDU via a browser interface.
- Open an Internet browser and enter the IPv4 address of the PDU into the browser.
- If it prompts you about any security warnings, just find a way to accept and continue anyway.
- The `Power Alert LX` web interface should prompt for username and password.
- If 1st time login...
- Default login is: `localadmin`
- Default 1st time password is: `localadmin`
- Must change password after 1st logon.
- Change password to `@Password123` to match what the `pdu.ps1` PowerShell script uses.
- Select `Load` tab on the left of screen to see all the loads on the 16 power ports.
- Click on the `State` slider to show the Load options, `Turn Off Load` and `Cycle Load`.
- To enable SSH for PowerShell scripting later, select `Network` tab, then `Services`, then enable `SSH Enabled`.

## Scripting
- The `Pdu.ps1` PowerShell script can be used for automating power ON/OFF/CYCLE of the PDU ports.
- Usage: `.\Pdu.ps1 [on | off | cycle] [1-16]`
- Update the following variables in the `Pdu.ps1` script if necessary.
- `$PduIP = "169.254.0.1"`
- `$Password = "@Password123"`
- The script will check first if there's a serial connection first, then network connection if serial is not present, before issuing the PDU command.

## References
- Eaton Tripp Lite Switched PDU (PDUMH15NET): [Manuals & User Guides](https://www.eaton.com/us/en-us/skuPage.PDUMH15NET.html#tab-2)
Loading