Sample code for 30+ languages & platforms
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

SQL Server
-- 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