spis IP

***UPDATED

scenariusz: jest lista nazw komputerów, trzeba rozwiązać adresy IP. warunek konieczny – odpowiednie wpisy w DNS.

dla widoczności oneliner rozbity na kilka linijek:

cat .\lista.txt | 
  %{
     $res=ping $_ -n 1;
     $ip=[regex]::Matches($res,"[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")[0].value;
     echo "$_;$ip"
   } | out-file compip.csv

podstawa to wyrażenie regularne. krótkie wyjaśnienie:

  • adres IPv4 to 3 cyfry, kropka … 3 cyfry. „[0-9]+” oznacza „wystąpienie dowolnej cyfry raz lub więcej”.
  • kropka jest znakiem specjalnym w wyrażeniach regularnych więc musi być wyeskejpowana – „\.”.
  • metoda Matches zwraca tablicę wyników, więc trzeba wybrać pierwszą wartość – stąd pojawia się „[0]” – jako pierwszy element tablicy.
  • no i na końcu wybranie atrybutu 'value’, ponieważ każdy rekord tablicy Matches zawiera kilka atrybutów a tu chodzi konkretnie o wartość.

udpate:

Player uzupełnia, że prawidłowy zapis dla adresu IP powinien wyglądać „[0-9]{1,3}” a nie + bo w końcu może być tylko od jednej do trzech cyfr. w tym przykładzie nie ma to znaczenia, bo ping nie zwróci raczej nieprawidłowego adresu, ale lepiej pisać dobrze (:

Paweł pokazuje, że lepiej niż pinga użyć commandletu ’test-connection’ i się nie bawić w wyrażenia regularne.

eN.

split, tablice, X400 i jeszcze więcej

scenariusz: w atrybucie proxyAddresses w AD użytkownicy mają wpisane nieużywane adresy X4oo, które trzeba było usunąć. prościzna… przynajmniej tak mi się wydawało. sporo ciekawych drobiazgów przy tym wyszło i zadanie, które oceniałem na 15-2o min zajęło mi ze 2h /:

a takież to ciekawostki powychodziły…

najpierw trzeba wyszukać wszystkie obiekty [user/contact], które mają w proxyaddresses X400. szczęśliwie filtry są na tyle sprytne, że radzą sobie z multivalue [zaraz napiszę jak to robią] i nie trzeba się męczyć z jakimiś konwersjami:

get-adobject -f {proxyaddresses -like "*x400*"} -properties proxyaddresses|%{
  <...tu bedzie obsluga...>
}

w 'normalnym’ języq, trzeba by się pomęczyć najpierw wyszuqjąc wszystkie obiekty posiadające wartość proxyaddresses, potem konwertując tablicę do stringa, a potem sprawdzić czy w tym stringu jest wartość x400 – bo w 'normalnym’ języq świat nie jest tak prosty (;

#tak nie trzeba robić, bo PowerShell rządzi!
get-adobject -f {proxyaddresses -like "*"} -properties proxyaddresses|%{
    $pa=$_.proxyaddresses -join ';'
    if( $pa -like "*X400*") {
<...>

proxyaddresses jest tupu 'mulivalue’ czyli jako parametr przyjmuje tablicę stringów i z tejże tablicy trzeba usunąć linijkę, która zawiera wartość 'x4oo’. wartość można łatwo odczytać, ale jak z tej tablicy wywalić ową linijkę?i tutaj czas na wyjaśnienie, jakim cudem filtr zadziałał dla tablicy tak, jakby to był pojedynczy string. spróbuję to zobrazować na trochę prostszym przykładzie:

C:\ :))o- $a=@("abc","cde","efg")
C:\ :))o- $a
abc
cde
efg
C:\ :))o- $a|gm

   TypeName: System.String

Name             MemberType            Definition
----             ----------            ----------
Clone            Method                System.Object Clone(), System.Object ICloneable.Clone()

<...CUT..>

Replace          Method                string Replace(char oldChar, char newChar), string Replace(string ol..

<...CUT...>

na powyższym przykładzie widać, że po zdefiniowaniu tablicy i sprawdzeniu jej typu przy pomocy get-member, PS traktuje ją jak zwykły string…  jeśli jednak sprawdzi się typ zmiennej….

C:\ :))o- $a.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

choć nieco dziwne, to wiele ułatwia. pozostaje jednak nadal pytanie – jak łatwo usunąć element z tablicy stringów? można kombinować z metodami replace i remove, które tu zadziałają jak dla zwykłego stringa, ale dają średnie rezultaty. dużo ciekawszym sposobem jest metoda remove, dla klasy ArrayList.

get-adobject -f {proxyaddresses -like "*x400*"} -properties proxyaddresses|%{
    $newpa=[System.Collections.ArrayList]$_.proxyaddresses
    foreach($p in $_.proxyaddresses) {
        if($p -like '*x400*') {$newpa.remove($p)}
    }
    set-adobject $_ -Replace @{proxyaddresses=[array]$newpa}
}

na koniec jeszcze jedna ciekawostka. zanim wpadłem na konwersję do ArrayList, kombinowałem z przepisaniem zmiennej do drugiej tablicy i próbowałem wycinać z niej wartości na różne sposoby.  tak trafiłem na kolejną 'ciekawostkę’ – w cudzysłowiu, bo de facto taki sposób działania jest normalny dla środowisk obiektowych: powiązanie zmiennej z atrybutem obiektu jest robione przez referencję a nie jest ona kopiowana. taki jakiś niedziałający kod:

get-adobject -f {proxyaddresses -like "*x400*"} -properties proxyaddresses|%{
    $newpa=$_.proxyaddresses
        foreach($p in $_.proxyaddresses) {
            if($p -like '*x400*') {$newpa.remove($p)}
        }
        set-adobject $_ -Replace @{proxyaddresses=$newpa}
}

podczas działania dostawałem taki błąd:

An error occurred while enumerating through a collection: Collection was modified; enumeration operation may not execute..At D:\ISCG\scriptz\cleanX400.ps1:11 char:16
     +         foreach <<<< ($p in $_.proxyaddresses) {
+ CategoryInfo          : InvalidOperation: (System.Collecti…numeratorSimple:ArrayListEnumeratorSimple) [], RuntimeException
+ FullyQualifiedErrorId : BadEnumeration

kolekcja została zmodyfikowana… i faktycznie – kiedy sprawdziłem modyfikacje na $newpa, wyświetlenie $_.proxyaddresses je odzwierciedlało. wniosek – z obiektami nie ma żartów, trzeba uważać (;

na koniec jeszcze jedna metoda usuwania konkretnej linii a tablicy stringów, która jednak mi się nie przydała, ponieważ trzeba znać index. załóżmy, że chcę usunąć 4tą wartość:

$a=@('abc','def',1,5,8,'fgt',43)
$a=$a[0..2+4..($a.Length-1)]

reasumując – atrybuty zostały poprawione, a te 2h nie poszły na marne – rozumiem bardziej ^^

eN.

 

MTS RIP

w skrócie – nie będzie. na tą chwilę komunikat jest dość enigmatyczny:

„Chcemy rozbudować naszą współpracę ze specjalistami IT i uczynić ją możliwie wartościową. Nasza nowa inicjatywa ma być skupiona nie tylko na dostarczaniu wiedzy, ale też budowaniu realnych kompetencji”

brzmi to trochę jak „…ze względu na oszczędności…” … ale z opinią należy poczekać do czasu propozycji owej nowej inicjatywy. szkoda. MTS był świetnym eventem…

eN.

przerwane dziedziczenie

***updated

migracja gównianej macierzy publikowanej via SMB. ADMT nie obsługuje dysqw sieciowych. jak sprawdzić na których katalogach zerwane jest dziedziczenie? może jakiś tool z netu? może jakiś super-skomplikowany kod? a może po prostu szybki test w PS ^^

wyszukaj wszystkie obiekty potomne, wybierz katalogi, wybierz te, które mają wyłączone dziedziczenie:

#dla PS2.o "? {$_.PSIsConstainter}"
Get-ChildItem <drive:> -recurse |? PSIsContainer |? {(Get-Acl $_.FullName).AreAccessRulesProtected}

jakoś tak z przyzwyczajenia używam filtra, który pokazuje tylko katalogi „? PSIsContainer”… przewija się na wszystkich stronach i we wszystkich przykładach… a przecież get-childItem ma parametr -Directory /:

gci <drive:> -r -directory|?{(get-acl $_.FullName).AreAccessRulesProtected}

 

eN.

wyniki koqrsu

na ostatnim spotkaniu WGUiSW został ogłoszony konqrs. do wygrania był 12to letni chivas. najwyraźniej nikt nie gustuje w takich trunkach, ponieważ zgłoszeń nie było q: jedni twierdzili, że bardzo chcieli ale jakoś czasu zabrakło.. inni, że było za trudne.

nie wnikając w powody – nagroda zostaje na następny konqrs. w okolicach listopada ruszy w ramach WGUiSW nowy cykl dotyczący PowerShell ale w innej formule – nie będą to krótkie prezentacje a… LABORATORIA. tym razem zapraszamy na zajęcia praktyczne ze swoim lapkiem, gdzie będziecie mogli wraz ze mną wykonywać zadania, zadawać pytania, tworzyć wariacje. na koniec będzie nowy konqrs – i tym razem liczę na to, że znajdą się chętni na nagrodę.

eN.