Кілька корисних трюків в арсеналі PowerShell'ьщика

У всього є свій потенціал, розкриття якого можливе завдяки інтелектуальній роботі деякого юніта. Звичайно ж все не розкривається відразу і юніту потрібен час, щоб розібратися що до чого, це в свою чергу виливається в досвід, а там дивись і почесна грамота зі статусом MVP. Якщо ж серйозно, робота дослідника заснована на одному лише ентузіазмі, а досвід — безцінний.

Кожен мисливець бажає знати...
До появи PowerShell яких тільки хитрощів не робилося різними юнітами, щоб змусити командний рядок заграти кольорами веселки. Втім, поява PowerShell мало що змінило, принаймні у свідомості вищеозначених юнітів, бо незважаючи на наявність можливості виведення кольорових сполучень, наприклад:

Write-Host ('0x{0:X}' -f 12) -ForegroundColor green

це не було здатне когось здивувати. А як на рахунок чогось надприродного? Скажімо, розліновка при виведенні даних деякої команди.

$line = {
param(
[Int32]$x, #координати по осі X
[Int32]$y, #координати по осі Y
[String]$msg = $null, #вивести повідомлення чи ні
[ConsoleColor]$fc = 'White', #колір тексту
[ConsoleColor]$bc = 'Black' #колір фону
)

#розташування вікна, а також його розмір
$pos = ($raw = $host.UI.RawUI).WindowPosition
$con = $raw.WindowSize
#задаємо координати лінії
$pos.X += $x
$pos.Y += $y
#вирівнювання відносно довжини тексту
switch ([String]::IsNullOrEmpty($msg)) {
$true { $msg = "$([Char]32)" * $con.Width }
$false { $msg += "$([Char]32)" * ($con.Width - $msg.Length) }
}
$row = $raw.NewBufferCellArray(@($msg) $fc, $bc)
#отрисовка
$raw.SetBufferContents($pos, $row)
}

($$ = Get-ChildItem) | ForEach-Object {
$i = 0
[Console]::SetCursorPosition(0, $$.Count)
}{
if ($i % 2 -eq 0) {
&$line 0 $i $_.FullName 'Black' 'Magenta'
}
else { &$line 0 $i $_.FullName 'Yellow' 'Black'}
$i++
}

Як вам такі пряники? Причому малюванням ліній справа зовсім не обмежується, так як при наявності часу та належного стимулу можна цілком виводити в хості більш складні з точки зору геометрії об'єкти.

Зе титлі...
Головна відмінність PowerShell від звичайної командного рядка — можна вертіти заголовком хоста в догоду своїм потребам. Так, ще з PowerShell v2 пам'ятний простий трюк моніторингу часу роботи з хостом.

[void]([PowerShell]::Create()).AddScript({
$st = (Get-Process Id $PID).StartTime #час запуску хоста

while ($true) { #безперервно оновлюємо заголовок
[Console]::Title = '{0}.{1:D2}:{2:D2}:{3:D2}' -f (
$$ = [DateTime]::Now - $st
).Days, $$.Hours, $$.Minutes, $$.Seconds
Start-Sleep -Seconds 1
}
}).BeginInvoke()

less дрімучий
Мають досвід роботи в Bash або Cygwin знають про такій команді, як less, примітною головним чином своєю функцією пошуку по тексту. У Windows такої команди немає, але є Alt+Space->Змінити->Знайти… але! Щоб не грати пальцями в «Твіст», можна поступити наступним чином.

$find = {
#хендл поточного хоста
$href = New Object Runtime.InteropServices.HandleRef(
(New-Object IntPtr),
[PSObject].Assembly.GetType(
'System.Management.Automation.ConsoleVisibility'
).GetMethod(
'GetConsoleWindow', [Reflection.BindingFlags]40
).Invoke($null @())
)

#шолом хосту повідомлення 0xfff4 - Знайти...
[void][Regex].Assembly.GetType(
'Microsoft.Win32.UnsafeNativeMethods'
).GetMethod('SendMessage').Invoke($null @(
[Runtime.InteropServices.HandleRef]$href,
0x0111, [IntPtr]0xfff4, [IntPtr]::Zero
))
}

Якщо код вище був набитий в самому хості, можна задати макрос:

doskey /exename=powershell.exe find=`&$find

Так як макрос має більш високий пріоритет перед командами, замість штатної консольної утиліти find.exe буде викликаний все той же пункт меню «Знайти...»; можна те ж помістити в профіль користувача (man about_Profiles). Варто зауважити — змінюючи значення 0xfff4, можна викликати і інші пункти меню.

0xfff1 - Вставити
0xfff2 - Позначити
0xfff3 - Прокрутити
0xfff5 - Виділити все

Наостанок...
… приклад того, як можна дізнатися поточний рівень заряду батареї ноутбука в обхід WMI.

Add-Type -AssemblyName System.Windows.Forms
[Windows.Forms.PowerStatus].GetConstructor(
[Reflection.BindingFlags]36, $null, [Type[]]@(), $null
).Invoke($null)

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.