PowerShell ściągawka
Moja ściągawka (zapewne tylko do użytku własnego) …
1: Podstawy
2: RegExp
3: Ustawienia
4: Array
5: Pliki
6: Operator @
7: Właściwości mutim. plików
8: Odczyt rejestru Windows
# Nie będziesz używał!
0: skondensowana przypominajka bez objaśnień
($x='coś')
, "2+3=$(2+3)`n"
, @()
, ${a b}
Write-Host "`$x: $x" -ForegroundColor Yellow
1: Podstawy
()
- wykonaj teraz, np. ($x='coś')
podstaw i wyświetl
$()
- wykonaj teraz i potraktuj jak zmienną, np. "2+3=$(2+3)"
@()
- potraktuj jako tablicę (także pustą lub 1-el.)
,
- literał tablicy
&
- wykonaj
.
- wykonaj skrypt ps1 zapamiętując jego zmienne (spacja po kropce)
..
- zakres liczb całk. np. -5.1..1.9
-eq -5..1
${}
- nazwa zmiennej z użyciem znaków niedozwolonych w nazwach, np. ${a b}
(ale $ąćę
jest ok)
`
= \
w innych językach, choć w PowerShell RegExp jest normalnie \
konwersja z wartością domyślną - bez zgłaszania błędów:
$x = $xIn -as [double]; if ($null -eq $x) { $x = 0.0 }
PSCustomObject
$myObj=[PSCustomObject]@{Nm='K'}
, $ht=[ordered]@{Nm='K'};$myObj=[pscustomobject]$ht
$myObj | ConvertTo-Json -depth 10 | Set-Content -Path $Path
- zapis do pliku
$myObj=Get-Content -Path $Path | ConvertFrom-Json
- odczyt z pliku
$myObj | Add-Member -MemberType NoteProperty -Name 'ID' -Value 'KMarquette'
$myObj | Add-Member @{ID='KMarquette'}
(krótko, ale nie wiem, czy to to samo co powyżej)
wszystkie własności:
$myObj | Get-Member -MemberType NoteProperty | Select -ExpandProperty Name
czy własność istnieje? (działa także przy wyższych StrictMode):
if( [bool] $myObj.psobject.Properties['ID'] )
$myObj.Nm
lub $myObj.'Nm'
lub $myObj.$prop
- odczytaj wartość
$b=$myObj.psobject.copy()
- prawdziwa kopia (a nie tylko referencja)
- PowerShell – mini kompendium -> tymoteuszkestowicz.com
- PowerShell Operators $( ) @( ) :: & -> ss64.com
- Getting started with PowerShell -> riptutorial.com
- Powershell: Everything you wanted to know about arrays -> powershellexplained.com
- Everything you wanted to know about PSCustomObject -> docs.microsoft.com
- PowerShell Commands Every Developer Should Know -> stackify.com
2: RegExp
$a -replace $b,$c
to .NET Regex.Replace($a, $b, $c, RegexOptions.IgnoreCase)
; $a.replace($b, $c)
- zwykła zamiana
- Regular Expression Language - Quick Reference; Regex.Replace(…); .NET Replace(String, String), Replace(String, String, StringComparison), StringComparison -> docs.microsoft.com
3: Ustawienia
Przydatne ustawienia
Set-StrictMode -Version 3
$ErrorActionPreference = "Stop"
- gdy chcemy na początku nie przeoczyć błędów
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
- inaczej UTF16 LE BOM, czyli UCS2 LE BOM - też nieźle.
4: Array
$myArray = @(); $myArray += '...'
- bardzo powolne; za każdym +=
kopiuje całą tablicę
$myArrList = [System.Collections.ArrayList]@(); [void]$myArrList.Add()
- lista dynamiczna; gdy brak [void]
do drukuje liczbę elementów
$Arr.length
szybko dla tablicy, $ArrList.count
powolniejsze, używaj dla kolekcji.
$a=@(11,22,33,44); $a[0,2];
11,33 $a[0,-1]
11,44 $a[($a.Count-1)..0]
wspak $b,$c=$a; $b
11 $c
22,33,44
[string[]]$s3=@('')*3
[string[][]]$s2x4=(,(@('x')*4))*2
$s2x4[1][3]
x
$ArrayDeepCopy = $Array | foreach { $_ } # deep copy trick
to spłaszcza tablicę;
dla wielowymiarowych: $MultiDimShallowCopy = $Array | foreach { , $_ }
$MultiDimDeepCopy = $Array | foreach { , ($_ | foreach{ $_ }) }
$Obj | Export-Clixml -LiteralPath .\serialized.xml
$ObjDeepCopy = Import-Clixml .\serialized.xml
- PowerShell add or remove elements from an Array -> pscustomobject.github.io
- Deep copying arrays and objects -> powershelladmin.com
5: Pliki
$EnDefault = [System.Text.Encoding]::Default # gdy potrzeba ANSI, np. dla txt-CSV
[Console]::OutputEncoding = [System.Text.Encoding]::Unicode
Set-Location -Path $PSScriptRoot # gdy używam ścieżek względem położenia bieżącego skryptu
# System.IO.Stream - szybko, ale mało intuicyjnie:
$fWe = new-object System.IO.StreamReader( (Resolve-Path ('we.txt')), $EnDefault)
# ^-- Reader: koniecznie pełna ścieżka!
try { while (($wiersz = $fWe.ReadLine()) -ne $null) { ... } finally { $fWe.Close() }
$fWy = new-object System.IO.StreamWriter( ('..\Wyniki\' + 'wy1.txt'), $false, $EnDefault)
# ^-- konieczny nawias, gdy "+" ^--no-append
try { ...; $fWy.WriteLine( $kolejnyWiersz ) } finally { $fWy.Close() }
- The many ways to read and write to files -> powershellexplained.com
Lista podfolderów może się przydać do katalogowania dysków z kopiami zapasowymi:
Polecenie PowerShell dla foldera bieżącego '.\'
, np. głównego na wybranym dysku:
Get-ChildItem -Directory '.\' | ForEach{ $_.Name+'\'; $_ | ForEach {'* '+($_.GetDirectories().Name -join '\, ')+"\`n"} }
Analogiczna wersja do wklejenia w pasku eksploratora plików czy menu Total Comander`a:
Powershell -NoExit -c "Get-ChildItem -Directory '.\' | ForEach{ $_.Name+'\'; $_ | ForEach {'* '+($_.GetDirectories().Name -join '\, ')+\"`\`n\"} }"
Fragment przykładowego wyniku:
Users\
* All Users\, Default\, ...
Windows\
* Boot\, Cursors\, debug\, ...
6: Operator @
@()
-array ,@{}
-hash table@
operator rozwinięcia (splat)function fun1 { param([int]$x, [int]$y) $x + $y } fun1 10 11 #-> 21 ( NIE: fun1(10, 11); NIE: fun1 10, 11 ) $a = @(10, 11) fun1 @a #-> 21
- Here string
$c = @" Wiele "wierszy" $a "@
7: Właściwości mutim. plików
Odczyt rozszerzonych własności pliku
$shellFolder = $Shell.NameSpace("$($pwd.Path)\...\").self.GetFolder()
$shellFile = $shellFolder.ParseName('abc.mp4')
$shellFile # m.in. Name ('abc.mp4'), Path, ModifyDate ('2021-04-08 19:11:27'), Size (bajty)
0..400 | where-object {($details=$shellFolder.GetDetailsOf($shellFile,$_))} | ForEach {
" $($_.ToString('000')):$(($shellFolder.GetDetailsOf($null,$_)).PadLeft(40,'.')) : $details"
} #rozmiar np. w MB, czas bez sek.
# albo odczytaj wszystkie, także puste właściwości
0..400 | ForEach {
" $($_.ToString('000')):$(($shellFolder.GetDetailsOf($null,$_)).PadLeft(40,'.')) " +
": $($shellFolder.GetDetailsOf($shellFile,$_))"
}
Odczytywanie tekstów z językowych DLL.MUI, np. z c:\Windows\System32\en-US\propsys.dll.mui
1. Dodaj na końcu rozszerzenie .DLL
; 2. Otwórz w Visual Studio; 3. Zapisz jako .RC
- Getting file metadata with PowerShell -> evotec.pl
8: Odczyt rejestru Windows
Zob. przykłady: WinInst_error_migrate_data
m.in. infProfileList_regWrTm.ps1 (html) (.zip)
Różne odnośniki:
- unicodeSupSub_test.ps1 (html) (.zip) (zob. przy okazji Przydatne znaki unicode)
# Nie będziesz używał!
... | foreach { ...
continue
break
$a[
0 . .-1]