ITGSerialTerminalTools.psm1
Function Invoke-RemoteCommand { <# .Synopsis Выполняет в удалённой консоли команду и возвращает результат. Генерирует исключение в случае таймаута. .Description Выполняет в удалённой консоли команду Command и возвращает результат. Генерирует исключение в случае таймаута. Следует использовать для подачи команды на удалённую консоль. С ключом PassThru возвращает в качестве результата вывод удалённой консоли до строки, соответствующей PromptPattern. #> [CmdletBinding()] Param( # Шаблон строки, ожидаемой в выводе удалённой консоли [Parameter( Mandatory = $true, ValueFromPipeLine = $true, Position = 0 )] [AllowEmptyString()] [String] $Command, # Шаблон строки, ожидаемой в выводе удалённой консоли [Parameter()] [ValidateNotNullOrEmpty()] [string] $PromptPattern = '\[.+?\] >', # Читатель потока удалённой консоли [Parameter( Mandatory = $true )] [ValidateNotNull()] [System.IO.TextReader] $ConsoleStreamReader, # Писатель потока удалённой консоли [Parameter( Mandatory = $true )] [ValidateNotNull()] [System.IO.TextWriter] $ConsoleStreamWriter, # Ключ, определяющий необходимость возврата вывода удалённой консоли [Switch] $PassThru, # Таймаут [Parameter()] [System.TimeSpan] $Timeout = 0 ) try { $ConsoleStreamWriter.WriteLine( $Command ); Write-Verbose ">>>> $Command"; $EscapedCommand = [System.Text.RegularExpressions.Regex]::Escape( $Command ); Wait-ExpectedMessage ` -ConsoleStreamReader $ConsoleStreamReader ` -PromptPattern "$PromptPattern\s*$EscapedCommand" ` -Timeout $Timeout ` -ErrorAction 'Stop'; Wait-ExpectedMessage ` -ConsoleStreamReader $ConsoleStreamReader ` -PromptPattern "$PromptPattern\s*$EscapedCommand" ` -Timeout $Timeout ` -ErrorAction 'Stop'; return Wait-ExpectedMessage ` -ConsoleStreamReader $ConsoleStreamReader ` -PromptPattern $PromptPattern ` -PassThru:$PassThru ` -Timeout $Timeout ` -ErrorAction 'Stop'; } catch { Write-Error -ErrorRecord $_; }; } Function Wait-ExpectedMessage { <# .Synopsis Ожидает появления в потоке строки, соответствующей шаблону PromptPattern. Генерирует исключение в случае таймаута. .Description Ожидает появления в потоке строки, соответствующей шаблону PromptPattern. Генерирует исключение в случае таймаута. Следует использовать до подачи команды на удалённую консоль, чтобы убедиться, что консоль готова принимать команды. С ключом PassThru возвращает в качестве результата вывод удалённой консоли до строки, соответствующей PromptPattern. #> [CmdletBinding()] Param( # Шаблон строки, ожидаемой в выводе удалённой консоли [Parameter( Position = 0 )] [ValidateNotNullOrEmpty()] [string] $PromptPattern = '\[.+?\] >', # Читатель потока удалённой консоли [Parameter( Mandatory = $true )] [ValidateNotNull()] [System.IO.TextReader] $ConsoleStreamReader, # Ключ, определяющий необходимость возврата вывода удалённой консоли [Switch] $PassThru, # Таймаут [Parameter()] [System.TimeSpan] $Timeout = 0 ) try { $Buffer = ''; $VerboseBuffer = ''; $Timer = New-Object Diagnostics.StopWatch; if ( $Timeout -ne 0 ) { $Timer.Start(); }; $RegExp = New-Object System.Text.RegularExpressions.Regex( $PromptPattern ); do { $StreamData = $ConsoleStreamReader.Read(); while ( ( $StreamData -eq -1 ) -and ( $Timer.Elapsed -le $Timeout ) ) { Start-Sleep -Milliseconds 50; $StreamData = $ConsoleStreamReader.Read(); }; if ( $Timer.Elapsed -gt $Timeout ) { throw ( 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; }; } catch { Write-Error -ErrorRecord $_; }; } Export-ModuleMember -Function Invoke-RemoteCommand, Wait-ExpectedMessage |