Tips & Tricks PowerShell

Mi se pare că PowerShell are parte de mult mai puțină atenție decât merită. Pentru ce fac eu, mi se pare mult mai intuitiv/expresiv/user-friendly/readable decât Bash. Fac comparația asta pentru că (inițial) Microsoft a vrut ceva în genul Bash pe Windows. Și au mers foarte mult pe inspirație: pipes, alias-uri pentru comenzi (astfel încât, până la un punct, poți folosi comenzi Linux care funcționează aproximativ la fel).

Și în ultima vreme am făcut mici utilitare care mă ajută cu una-alta și de care am tot scris pe forum. Am zis să le centralizez aici, poate ajută și pe alții.

Pasul 0: instalarea

Dacă ești pe Windows, nu trebuie să faci nimic, PS este inclus încă de la … Win 7 (sau vista?). Dacă eșți pe altceva, poți instala fără prea mari bătăi de cap.

Pasul 1: un fel de .bashrc

Evident, nu avem așa ceva, avem $profile. Ca să-l edităm: notepad $profile. (sau subl $profile sau ce editor îți place). Aici este fișierul cu chestii, unde punem cod ce va fi accesibil din consolă.

Spre deosebire de Linux, unde avem un fișier ~/.bashrc, în PowerShell avem ~/Documents/PowerShell/Microsoft.PowerShell_profile.ps1. (calea asta este ținută în acel $profile de care am zis mai sus).

⚠️Orice modificare a acestui fișier necestă reîncărcarea acestuia: ori cu un reset al consolei ori cu execuția . $profile

Pasul 2: utilitare făcute de alții

Atât pe Linux cât și pe Mac, există … utilitare (nici nu știu cum să le spun, teme? modificări?) care adaugă tot felul de informații în shell: calea curentă, branch-ul git, ora etc.

Cele mai cunoscute (eu le folosesc doar pe primele două):

Pasul 3: utilitare proprii

Înainte de toate, punem două comenzi la începutul lui $profile:

  1. Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete pentru a avea autocomplete mai deștept la TAB (util în anumite situații)
  2. Start-SshAgent -Quiet dacă folosești ssh

Organizarea fișierelor

La fel cum în .bashrc poți include fișiere externe (source my-file), la fel poți face și în PowerShell folosind Import-Module -Name my-file.ps1. La fel de frumos poți să trântești totul în $profile – nu e nici o supărare – dar spargerea în fișiere permite să dezactivezi rapid module/funcții sau distribuirea acestora.

Funcțiile de mai jos pot fi puse și în $profile și în module separate.

Autocomplete pentru SSH

Codul este luat de aici și îți pune la dispoziție autocomplete pentru host-urile definite în ssh config. Foarte util dacă te ai multe host-uri configurate. Tot în gist-ul ăsta vei găsi și utilitar care-ți oferă autocomplete în baza known_hosts.

function Get-SSHHost($sshConfigPath) {
  Get-Content -Path $sshConfigPath `
  | Select-String -Pattern '^Host ' `
  | ForEach-Object { $_ -replace 'Host ', '' } `
  | ForEach-Object { $_ -split ' ' } `
  | Sort-Object -Unique `
  | Select-String -Pattern '^.*[*!?].*$' -NotMatch
}

Register-ArgumentCompleter -CommandName 'ssh', 'scp', 'sftp' -Native -ScriptBlock {
  param($wordToComplete, $commandAst, $cursorPosition)

  $sshPath = "$env:USERPROFILE\.ssh"

  $hosts = Get-Content -Path "$sshPath\config" `
  | Select-String -Pattern '^Include ' `
  | ForEach-Object { $_ -replace 'Include ', '' }  `
  | ForEach-Object { Get-SSHHost "$sshPath/$_" }

  $hosts += Get-SSHHost "$sshPath\config"
  $hosts = $hosts | Sort-Object -Unique

  $hosts | Where-Object { $_ -like "$wordToComplete*" } `
  | ForEach-Object { $_ }
}

SSH .pub keys

Pentru că am multe chei ssh, se întâmplă uneori să fie nevoie să copiez rapid cheia publică. sshkeys urmat de tab îți va arăta cheile disponibile.

function sshkeys() {
    param($sshKeyName = 'id_rsa')

    if ( [string]::IsNullOrEmpty($sshKeyName) ) { 
      echo 'Empty Key'
      return
    }

    $sshFile = "$env:USERPROFILE\.ssh\$sshKeyName"

    if (-not(Test-Path -Path $sshFile -PathType Leaf)) {
      echo 'Invalid file'
      return
    }

    $keyValue = ssh-keygen -y -f $sshFile

    Set-Clipboard -Value "$keyValue"

    echo "Show public key for: $sshKeyName"
    echo "--------------------------------------------------"
    echo $keyValue
    echo "--------------------------------------------------"
}


Register-ArgumentCompleter  -CommandName sshkeys -Native  -ScriptBlock {
    param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)

    $excluded = 'config', 'known_hosts', 'altă-cheie-privată'

    $sshPath = "$env:USERPROFILE\.ssh"

    $keys = Get-ChildItem -Path $sshPath -File -Name
    $keys = $keys | Sort-Object -Unique

    $keys | Where-Object { 
      -not($excluded -contains $_)
    } |  Where-Object {
      $_ -notlike '*.pub'
    } |  ForEach-Object {
      $_
    }   
}

WP CLI autocomplete

Register-ArgumentCompleter  -CommandName wp, wpms -Native  -ScriptBlock {
    param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)

    Invoke-Expression "wp cli completions --line='$parameterName' --point=100" | ForEach-Object {
       $_
    }
}

Sudo

În lumea Windows există conceptul de a rula ceva elevat, dar nu există și un mod ușor de a face asta. Și pentru că Windows nu permite elevarea unui proces existent, este nevoie să se deschidă o nouă instanță:

function sudo() {
  $curDir = (Get-Location).path
  powershell -command "Start-Process cmd -ArgumentList '/c cd /d $curDir && $args & pause' -Verb runas"
}

În rest se execută la fel ca pe Linux: sudo notepad $profile.


Publicat

în

de către

Etichete:

Comentarii

5 răspunsuri la „Tips & Tricks PowerShell”

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *

Acest site folosește Akismet pentru a reduce spamul. Află cum sunt procesate datele comentariilor tale.

windows apple dropbox facebook twitter