SQL Server
SQL Server
SSH to a Cisco Switch - Processing "More" Responses
See more SSH Examples
Demonstrates connecting to a Cisco switch, entering privileged mode with the ena command, and running a command whose response is paged. Each page ends with --More-- and requires a SPACE character to request the next page.
Note: QuickShell allocates a PTY, which is what a network device console expects. The device presents an interactive prompt, and each command's output is read up to the next prompt.
Background: Paged output is the console equivalent of a pager like
more, and a client must reproduce the keypress a human would make. Matching a set of patterns is what makes this tractable: each read ends either at the device prompt (output complete) or at --More-- (another page waiting), and the code branches accordingly. Note the prompt pattern includes the device name rather than a bare #, because that character also appears inside configuration text and would otherwise match far too early.Chilkat SQL Server Downloads
-- Important: See this note about string length limitations for strings returned by sp_OAMethod calls.
--
CREATE PROCEDURE ChilkatSample
AS
BEGIN
DECLARE @hr int
DECLARE @iTmp0 int
DECLARE @sTmp0 nvarchar(4000)
DECLARE @success int
SELECT @success = 0
-- This example requires the Chilkat API to have been previously unlocked.
-- See Global Unlock Sample for sample code.
-- Demonstrates connecting to a Cisco switch, entering privileged mode, and running a command
-- whose response is paged -- each page ends with "--More--" and requires a SPACE character to
-- request the next page.
DECLARE @ssh int
EXEC @hr = sp_OACreate 'Chilkat.Ssh', @ssh OUT
IF @hr <> 0
BEGIN
PRINT 'Failed to create ActiveX component'
RETURN
END
DECLARE @port int
SELECT @port = 22
EXEC sp_OAMethod @ssh, 'Connect', @success OUT, '172.16.16.100', @port
IF @success = 0
BEGIN
EXEC sp_OAGetProperty @ssh, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @ssh
RETURN
END
-- Normally you would not hard-code the password in source. You should instead obtain it
-- from an interactive prompt, environment variable, or a secrets vault.
DECLARE @password nvarchar(4000)
SELECT @password = 'mySshPassword'
EXEC sp_OAMethod @ssh, 'AuthenticatePw', @success OUT, 'mySshLogin', @password
IF @success = 0
BEGIN
EXEC sp_OAGetProperty @ssh, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @ssh
RETURN
END
DECLARE @channelNum int
EXEC sp_OAMethod @ssh, 'QuickShell', @channelNum OUT
IF @channelNum < 0
BEGIN
EXEC sp_OAGetProperty @ssh, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @ssh
RETURN
END
-- IMPORTANT: Set a read timeout before receiving until a match. ReadTimeoutMs defaults to 0,
-- which means no limit -- without it, this call waits forever if the received data never
-- contains a match.
EXEC sp_OASetProperty @ssh, 'ReadTimeoutMs', 15000
DECLARE @caseSensitive int
SELECT @caseSensitive = 1
-- In unprivileged mode the switch prompt ends with ">".
EXEC sp_OAMethod @ssh, 'ChannelReceiveUntilMatch', @success OUT, @channelNum, '>', 'utf-8', @caseSensitive
IF @success = 0
BEGIN
EXEC sp_OAGetProperty @ssh, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @ssh
RETURN
END
DECLARE @received nvarchar(4000)
EXEC sp_OAMethod @ssh, 'GetReceivedText', @received OUT, @channelNum, 'utf-8'
EXEC sp_OAGetProperty @ssh, 'LastMethodSuccess', @iTmp0 OUT
IF @iTmp0 = 0
BEGIN
EXEC sp_OAGetProperty @ssh, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @ssh
RETURN
END
PRINT @received
-- Send "ena" to enter privileged mode. Cisco devices expect a bare CR to terminate a command.
EXEC sp_OAMethod @ssh, 'ChannelSendString', @success OUT, @channelNum, 'ena' + CHAR(13), 'utf-8'
IF @success = 0
BEGIN
EXEC sp_OAGetProperty @ssh, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @ssh
RETURN
END
EXEC sp_OAMethod @ssh, 'ChannelReceiveUntilMatch', @success OUT, @channelNum, 'Password:', 'utf-8', @caseSensitive
IF @success = 0
BEGIN
EXEC sp_OAGetProperty @ssh, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @ssh
RETURN
END
EXEC sp_OAMethod @ssh, 'GetReceivedText', @received OUT, @channelNum, 'utf-8'
EXEC sp_OAGetProperty @ssh, 'LastMethodSuccess', @iTmp0 OUT
IF @iTmp0 = 0
BEGIN
EXEC sp_OAGetProperty @ssh, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @ssh
RETURN
END
PRINT @received
-- The enable password is separate from the login password, and likewise should come from a
-- secure source rather than being hard-coded.
DECLARE @enablePassword nvarchar(4000)
SELECT @enablePassword = 'myEnablePassword'
EXEC sp_OAMethod @ssh, 'ChannelSendString', @success OUT, @channelNum, @enablePassword, 'utf-8'
IF @success = 0
BEGIN
EXEC sp_OAGetProperty @ssh, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @ssh
RETURN
END
EXEC sp_OAMethod @ssh, 'ChannelSendString', @success OUT, @channelNum, CHAR(13), 'utf-8'
IF @success = 0
BEGIN
EXEC sp_OAGetProperty @ssh, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @ssh
RETURN
END
-- In privileged mode the prompt ends with "#" instead of ">".
EXEC sp_OAMethod @ssh, 'ChannelReceiveUntilMatch', @success OUT, @channelNum, '#', 'utf-8', @caseSensitive
IF @success = 0
BEGIN
EXEC sp_OAGetProperty @ssh, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @ssh
RETURN
END
EXEC sp_OAMethod @ssh, 'GetReceivedText', @received OUT, @channelNum, 'utf-8'
EXEC sp_OAGetProperty @ssh, 'LastMethodSuccess', @iTmp0 OUT
IF @iTmp0 = 0
BEGIN
EXEC sp_OAGetProperty @ssh, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @ssh
RETURN
END
PRINT @received
-- Run a command whose output is delivered a page at a time.
EXEC sp_OAMethod @ssh, 'ChannelSendString', @success OUT, @channelNum, 'show running-config' + CHAR(13), 'utf-8'
IF @success = 0
BEGIN
EXEC sp_OAGetProperty @ssh, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @ssh
RETURN
END
-- Each read ends either at the device prompt (output complete) or at "--More--" (another page
-- is waiting). Match the full prompt rather than a bare "#", because "#" also appears inside
-- configuration text and would match too early.
DECLARE @saMatch int
EXEC @hr = sp_OACreate 'Chilkat.StringArray', @saMatch OUT
EXEC sp_OAMethod @saMatch, 'Append', @success OUT, 'MySwitchName#'
EXEC sp_OAMethod @saMatch, 'Append', @success OUT, '--More--'
DECLARE @sbReceived int
EXEC @hr = sp_OACreate 'Chilkat.StringBuilder', @sbReceived OUT
DECLARE @moreComing int
SELECT @moreComing = 1
WHILE @moreComing
BEGIN
EXEC sp_OAMethod @ssh, 'ChannelReceiveUntilMatchN', @success OUT, @channelNum, @saMatch, 'utf-8', @caseSensitive
IF @success = 0
BEGIN
EXEC sp_OAGetProperty @ssh, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @ssh
EXEC @hr = sp_OADestroy @saMatch
EXEC @hr = sp_OADestroy @sbReceived
RETURN
END
EXEC sp_OAMethod @sbReceived, 'Clear', NULL
DECLARE @pageText nvarchar(4000)
EXEC sp_OAMethod @ssh, 'GetReceivedText', @pageText OUT, @channelNum, 'utf-8'
EXEC sp_OAGetProperty @ssh, 'LastMethodSuccess', @iTmp0 OUT
IF @iTmp0 = 0
BEGIN
EXEC sp_OAGetProperty @ssh, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @ssh
EXEC @hr = sp_OADestroy @saMatch
EXEC @hr = sp_OADestroy @sbReceived
RETURN
END
EXEC sp_OAMethod @sbReceived, 'Append', @success OUT, @pageText
PRINT @pageText
-- If this page ended with "--More--", send a SPACE to request the next page.
EXEC sp_OAMethod @sbReceived, 'Contains', @moreComing OUT, '--More--', @caseSensitive
IF @moreComing
BEGIN
EXEC sp_OAMethod @ssh, 'ChannelSendString', @success OUT, @channelNum, ' ', 'utf-8'
IF @success = 0
BEGIN
EXEC sp_OAGetProperty @ssh, 'LastErrorText', @sTmp0 OUT
PRINT @sTmp0
EXEC @hr = sp_OADestroy @ssh
EXEC @hr = sp_OADestroy @saMatch
EXEC @hr = sp_OADestroy @sbReceived
RETURN
END
END
END
EXEC sp_OAMethod @ssh, 'Disconnect', NULL
EXEC @hr = sp_OADestroy @ssh
EXEC @hr = sp_OADestroy @saMatch
EXEC @hr = sp_OADestroy @sbReceived
END
GO