ITGSerialTerminalTools.psm1
Function Invoke-RemoteCommand { <# .Synopsis Выполняет в удалённой консоли команду и возвращает результат. Генерирует исключение в случае таймаута. .Description Выполняет в удалённой консоли команду Command и возвращает результат. Генерирует исключение в случае таймаута. Следует использовать для подачи команды на удалённую консоль. С ключом PassThru возвращает в качестве результата вывод удалённой консоли до строки, соответствующей PromptPattern. #> [CmdletBinding()] Param( # Читатель потока удалённой консоли [Parameter( Mandatory = $true )] [System.IO.TextReader] $ConsoleStreamReader, # Писатель потока удалённой консоли [Parameter( Mandatory = $true )] [System.IO.TextWriter] $ConsoleStreamWriter, # Шаблон строки, ожидаемой в выводе удалённой консоли [Parameter( Mandatory = $true, ValueFromPipeLine = $true )] [AllowEmptyString()] [String] $Command, # Шаблон строки, ожидаемой в выводе удалённой консоли [Parameter()] [ValidateNotNullOrEmpty()] [string] $PromptPattern = '\[.+?\] >', # Ключ, определяющий необходимость возврата вывода удалённой консоли [Switch] $PassThru, # Таймаут [Parameter()] [System.TimeSpan] $Timeout = ( New-Object System.TimeSpan( 0, 0, 30 ) ) ) $Local:ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop; $ConsoleStreamWriter.WriteLine( $Command ); Write-Verbose ">>>> $Command"; $EscapedCommand = [System.Text.RegularExpressions.Regex]::Escape( $Command ); Wait-ExpectedMessage ` -ConsoleStreamReader $ConsoleStreamReader ` -PromptPattern "$PromptPattern\s*$EscapedCommand" ` -Timeout $Timeout; Wait-ExpectedMessage ` -ConsoleStreamReader $ConsoleStreamReader ` -PromptPattern "$PromptPattern\s*$EscapedCommand" ` -Timeout $Timeout; return Wait-ExpectedMessage ` -ConsoleStreamReader $ConsoleStreamReader ` -PromptPattern $PromptPattern ` -Timeout $Timeout ` -PassThru:$PassThru; } Function Wait-ExpectedMessage { <# .Synopsis Ожидает появления в потоке строки, соответствующей шаблону PromptPattern. Генерирует исключение в случае таймаута. .Description Ожидает появления в потоке строки, соответствующей шаблону PromptPattern. Генерирует исключение в случае таймаута. Следует использовать до подачи команды на удалённую консоль, чтобы убедиться, что консоль готова принимать команды. С ключом PassThru возвращает в качестве результата вывод удалённой консоли до строки, соответствующей PromptPattern. #> [CmdletBinding()] Param( # Читатель потока удалённой консоли [Parameter( Mandatory = $true )] [System.IO.TextReader] $ConsoleStreamReader, # Шаблон строки, ожидаемой в выводе удалённой консоли [Parameter()] [ValidateNotNullOrEmpty()] [string] $PromptPattern = '\[.+?\] >', # Ключ, определяющий необходимость возврата вывода удалённой консоли [Switch] $PassThru, # Таймаут [Parameter()] [System.TimeSpan] $Timeout = ( New-Object System.TimeSpan( 0, 0, 30 ) ) ) $Local:ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop; $Buffer = ''; $VerboseBuffer = ''; $Timer = [Diagnostics.StopWatch]::StartNew(); $RegExp = New-Object System.Text.RegularExpressions.Regex( $PromptPattern ); do { $StreamData = $ConsoleStreamReader.Read(); while ( ( $StreamData -eq -1 ) -and ( $Timer.Elapsed -lt $Timeout ) ) { Start-Sleep -Milliseconds 50; $StreamData = $ConsoleStreamReader.Read(); }; if ( $Timer.Elapsed -ge $Timeout ) { Write-Error -Exception ( New-Object System.TimeoutException ); }; switch ( [char]$StreamData ) { "`r" { if ( $VerboseBuffer ) { Write-Verbose $VerboseBuffer; $VerboseBuffer = ""; }; } "`n" { } Default { $VerboseBuffer += [char] $StreamData; } } $Buffer += [char] $StreamData; $SearchResults = $RegExp.Match( $Buffer ); } while ( -not $SearchResults.Success ); if ( $VerboseBuffer ) { Write-Verbose $VerboseBuffer; $VerboseBuffer = ""; }; $Result = $Buffer.Substring( 0, $SearchResults.Index ); $Buffer = $Buffer.Remove( 0, $SearchResults.Index + $SearchResults.Length ); if ( $PassThru ) { return $Result; }; } Export-ModuleMember -Function Invoke-RemoteCommand, Wait-ExpectedMessage |