cmdlets/CommonUtils/CommonUtils.ps1
#01.2018©willynilly #---------------------------------------------------------------------------------------- # Получает согласие пользователя на продолжение function Get-Permission { <# .Synopsis Получить разрешение от пользователя. .Description Задает вопрос пользователю и ожидает ответа Да/Нет клавишами Enter/Esc. .Parameter TextQuestion Текст однозначного вопроса (без знака вопроса) на который можно ответить Да/Нет. По умолчанию: "Продолжить?" Псевдонимы: t, q .Example if (Get-Permision "Очистить экран") {Clear-Host} #> [CmdletBinding()] param( [Alias("t", "q", "Question")][string]$TextQuestion="Продолжить" # текст вопроса ) # в ISE есть глобальная переменная psISE, а в VS Code есть psEditor # в ISE параметр $host.ui.RawUi.KeyAvailable равен NULL $ispsISE = (Test-path variable:psISE) $ispsEditor = (Test-path variable:psEditor) $isNullKeyAvailable = ($host.ui.RawUi.KeyAvailable -eq $null) Write-Verbose "psISE = $ispsISE" Write-Verbose "psEditor = $ispsEditor" Write-Verbose "isNullKeyAvailable = $isNullKeyAvailable" Write-Verbose ('host.ui.RawUi.KeyAvailable = {0}' -f $host.ui.RawUi.KeyAvailable) $Result = $true Write-Host ("`n{0}? (Enter\Esc)" -f $TextQuestion) -ForegroundColor White while($True) { try { $Key = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") # !!!НЕ РАБОТАЕТ в ISE и VS CODE!!! if ($key.VirtualKeyCode -eq 27) {$Result = $false; Break} # нажали Esc - выходим из скрипта if ($key.VirtualKeyCode -eq 13) {Break} # нажали Enter - выходим из цикла и идем удалять } catch { $InputUser = Read-Host ('Да <Enter>\Нет <любой символ>') if($InputUser.Length -gt 0) {$Result = $false} Break } } if (-not $Result){Write-Host "Отказ" -ForegroundColor Red} $Result }# end Get-Permission #---------------------------------------------------------------------------------------- # проверяет параметр скрипта WaitPressAnyKey и ждет нажатия любой клавиши если надо function Wait-PressAnyKey { <# .Synopsis Ждет нажатия любой клавиши. .Description Выводит сообщение "Для выхода нажмите любую клавишу..." и ждет. .Example if ($Wait) {Wait-PressAnyKey} #> [CmdletBinding()] param() # в ISE есть глобальная переменная psISE, а в VS Code есть psEditor # в ISE параметр $host.ui.RawUi.KeyAvailable равен NULL $ispsISE = (Test-path variable:psISE) $ispsEditor = (Test-path variable:psEditor) $isNullKeyAvailable = ($host.ui.RawUi.KeyAvailable -eq $null) Write-Verbose "psISE = $ispsISE" Write-Verbose "psEditor = $ispsEditor" Write-Verbose "isNullKeyAvailable = $isNullKeyAvailable" Write-Verbose ('host.ui.RawUi.KeyAvailable = {0}' -f $host.ui.RawUi.KeyAvailable) if (-not($ispsISE -or $ispsEditor -or $isNullKeyAvailable)) { #Остановка скрипта БЕЗ возможности отмены !!!НЕ РАБОТАЕТ В ISE и VS Code!!! Write-host "`nДля выхода нажмите любую клавишу..." -ForegroundColor White $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown,AllowCtrlC") | Out-Null } }# end Wait-PressAnyKey #---------------------------------------------------------------------------------------- # получает кодировку файла function Get-Encoding { <# .Synopsis Получает кодировку текстового файла. .Description Определяет кодировку переданного текстового файла. .Parameter filePath Полный путь к текстовому файлу. .Outputs [System.Text.Encoding] .Example Get-Encoding C:\Names.txt #> [CmdletBinding()] param( [Parameter(Mandatory=$True)][string]$filePath ) Try { $sr = New-Object System.IO.StreamReader($filePath, $true) [char[]] $buffer = new-object char[] 3 $sr.Read($buffer, 0, 3) | Out-Null # задавим вывод, иначе попадет в результат функции $encoding = $sr.CurrentEncoding $sr.Close() } catch { #ничего делать не надо } #вернем полученную кодировку $encoding }# end Get-Encoding #---------------------------------------------------------------------------------------- #Открывает диалог выбора файла function Select-FileDialog { <# .Synopsis Выбор файла в диалоговом окне. .Description Открывает стандартное диалоговое окно выбора файла и возвращает полный путь выбранного файла. .Parameter Title Заголовок окна выбора файла. .Parameter Directory Начальный каталог выбора файла. .Parameter Filter Фильтр расширений файлов. По умолчанию все файлы. .Outputs [System.String] .Example $FileConfig = Select-FileDialog "Укажите файл настроек" "C:\Settings" "Файлы настроек (*.cfg)|*.cfg|Все файлы (*.*)|*.*" #> param( [string]$Title, [string]$Directory, [string]$Filter="Все файлы (*.*)|*.*" ) [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null $objForm = New-Object System.Windows.Forms.OpenFileDialog $objForm.InitialDirectory = $Directory $objForm.Filter = $Filter $objForm.Title = $Title $objForm.ShowDialog() | Out-Null $objForm.FileName } #---------------------------------------------------------------------------------------- # Показывает диалоговое окно вопроса или предупреждения function Show-Dialog { <# .Synopsis Показывает диалоговое окно вопроса или предупреждения. .Description Показывает диалоговое окно вопроса или предупреждения. .Parameter Text Текст сообщения. .Parameter SecondsToWait Количество секунд, по истечении которого окно будет автоматически закрыто. .Parameter Title Текст заголовка окна сообщения. .Parameter Type Комбинация флагов, определяет тип кнопок и значка. Возможные значения флагов: 0 — кнопка ОК. 1 — кнопки ОК и Отмена. 2 — кнопки Стоп, Повтор, Пропустить. 3 — кнопки Да, Нет, Отмена. 4 — кнопки Да и Нет. 5 — кнопки Повтор и Отмена. 16 — значок Stop. 32 — значок Question. 48 — значок Exclamation. 64 — значок Information. .Outputs Возвращает целое значение, с помощью которого можно узнать, какая кнопка была нажата. Возможные значения: -1 — таймаут. 1 — кнопка ОК. 2 — кнопка Отмена. 3 — кнопка Стоп. 4 — кнопка Повтор. 5 — кнопка Пропустить. 6 — кнопка Да. 7 — кнопка Нет. .Example Example #1 Простая форма предупреждения с одной кнопкой Ок, без и иконок и автозакрытия. Show-Dailog "Отправка завершена" Example #2 Форма вопроса с двумя кнопками Да/Нет, иконкой вопроса и таймаутом на размышление 30 сек. Show-Dailog "Завершить работу?" 30 "Вопрос" (4+32) #> [CmdletBinding()] param( [Parameter(Mandatory=$True)][string]$Text, [int]$SecondsToWait, [string]$Title="Предупреждение", [int]$Type ) $wshell = New-Object -ComObject Wscript.Shell $Output = $wshell.Popup($Text,$SecondsToWait,$Title,$Type) return $Output }# end Show-Dialog #---------------------------------------------------------------------------------------- # Конвертирует PSObject полученный после Convert-FromJSON в обычный Hastable function Convert-PSObjectToHashtable { <# .Synopsis Конвертирует PSObject в Hashtable. .Description Рекурсивно конвертирует PSObject полученный после Convert-FromJSON в полноценный Hashtable. .Parameter InputObject Входной объект (может быть передан по конвейеру). .Outputs [System.Hastable] .Example $Config = Get-Content C:\Config.json | ConvertFrom-Json | Convert-PSObjectToHashtable #> param ( [Parameter(ValueFromPipeline)] $InputObject ) process { if ($null -eq $InputObject) { return $null } if ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string]) { $collection = @( foreach ($object in $InputObject) { Convert-PSObjectToHashtable $object } ) Write-Output -NoEnumerate $collection } elseif ($InputObject -is [psobject]) { $hash = @{} foreach ($property in $InputObject.PSObject.Properties) { $hash[$property.Name] = Convert-PSObjectToHashtable $property.Value } $hash } else { $InputObject } } }# end Convert-PSObjectToHashtable #---------------------------------------------------------------------------------------- # Выполняет перекодировку строки function ConvertTo-Encoding ([string]$From, [string]$To) { Begin { $encFrom = [System.Text.Encoding]::GetEncoding($from) $encTo = [System.Text.Encoding]::GetEncoding($to) } Process { $bytes = $encTo.GetBytes($_) $bytes = [System.Text.Encoding]::Convert($encFrom, $encTo, $bytes) $encTo.GetString($bytes) } }# end ConvertTo-Encoding #---------------------------------------------------------------------------------------- # Выводит результат теста function Write-Test($Name, $Result, $Count=25, $Sym='.'){ $Test = $Name.PadRight($Count, $Sym) if ($Result -is [bool]){ if ($Result) { Write-Host ($Test + "Ok") } else { Write-Host ($Test + "No") -ForegroundColor DarkYellow } } else { Write-Host ($Test + $Result) } }# end Write-Test |