Skip to Content

IT nieuczesane.
category

Category: DevOps/Scripting

skrypty, programy, command line i inne

Ku pamięci – usuwanie Forefront Client Security

Taki mały startup script do usuwania FCS-a ze stacji:

Przy czym trzeba pamiętać, żeby odfiltrować/odpiąć polisę, która go wcześniej zainstalowała.

AD Powershell na WS2003/2008 – teraz to już możliwe :)

Jakiś czas temu pisałem o Active Directory Management Gateway Service. Teraz już jest :)

Link do pobrania: http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=008940c6-0296-4597-be3e-1d24c1cf0dda

Usuwanie nie skasowanych profili

Idea profili mandatoryjnych jest piękna. Niestety czasami skubańce nie chcą się kasować :/ Takimi cudeńkami obdarzamy studentów, żeby jak im się coś popsuje wystarczył restart i mają świeży profil. Aby sam mechanizm wspomóc wrzuciłem do GPO taki prościutki skrypcik:

on error resume next
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder("C:Documents and Settings")
Set colFOlders = objFolder.SubFolders
Dim re 
set re = New RegExp
re.Pattern = "(^s[0-9][0-9][0-9][0-9]?[0-9])|(^pd[0-9][0-9][0-9])"
For Each subFolder In colFOlders
 
if re.Test(subFolder.Name) then 
   
subFolder.delete(true)    
 
end if
Next

FTM nie usuwa kolejki

ten stary wpis to jeden z najczęściej przeze mnie wyszukiwanych na w-files. a więc zamieszam nieco uaktualnioną wersję dla powershell’a:

n.

SCCM Console Extensions – WOL nie działa na WS2008

Ostatnio mocno zainteresowałem się rozszerzeniami konsoli SCCMa. Ogólnie polegają one na fajnym wykorzystaniu przestrzeni nazw WMI, którą daje ConfigMgr. Ale żeby nie malować trawy na zielono najpierw zainstalowałem 2 pakiety wtyczek – SCCM Right Click Tools oraz SCCM Console Extensions. Po ich przetestowaniu muszę powiedzieć, że można robić niezłe cuda w MMC przy użyciu hta i vbs ;)

Tyle, że jedna funkcjonalność mi nie działała – Wake On Lan. Wiem, że komputery mają uruchomiony remote wake up i są podłączone do sieci (1 warstwa) mam możliwość directed broadcast (2. warstwa), więc problem musi być z działaniem samej wtyczki. Po kliknięciu tutaj:

image

Mamy śliczny komunikat, że wszystko się udało.

image

grzebiąc w kodzie znajdujemy coś takiego:

errReturn = WshShell.Run(chr(34) & strCurrentPath & "WOL.exe" & chr(34) & " " & strWOLAddress,0)
If errReturn <> 0 Then
   
LogArea.Value = LogArea.Value & "ERROR!" & vbCrLf
   
LogArea.Value = LogArea.Value & " " & Err.Description & vbCrLf
   
LogFile.WriteLine(Date & " " & Time & vbTab & "Send Wakeup: ERROR!" & vbTab & Err.Description)
   
LogArea.scrollTop = LogArea.scrollHeight
Else
   
WolSuccess = 1
   
LogArea.Value = LogArea.Value & "Wakeup sent to " & strMACAddress & vbCrLf
   
LogArea.scrollTop = LogArea.scrollHeight
   
LogFile.WriteLine(Date & " " & Time & vbTab & arrComputers(iList) & ": Wakeup sent to " & strMACAddress)
End If

Widać, że to nic innego niż wywołanie wol.exe z katalogu z rozszerzeniami. Sprawdzamy co się dzieje z tym programikiem. Po wpisaniu w CMD – "c:Program FilesSCCMConsoleExtensionsWOL.exe" 00219B7B80CD też działa… ale ale – brakuje adresu IP i maski do kierunkowego bradcastu. Patrzymy wol.exe /? można podać tylko IP :/ niedobrze. sieci z nie klasowymi maskami odpadają. po chwili szperan
ia w bingu znalazłem narzędzie wolcmd.exe. Usage: wolcmd [mac address] [ipaddress] [subnet mask] [port number]. No i pięknie teraz tylko wrzucić je do odpowiedniego katalogu i podmienić kawałęk skryptu na coś takiego:

strNetmask = inputbox("Provide netmask")
For Each instance in colMACAddress
   
strMACAddress = instance.MACAddress
   
strWOLAddress = (Replace(instance.MACAddress,":",""))
   
strIPAddress = instance.IPAddress
   
LogArea.Value = LogArea.Value & arrComputers(iList) & ": "
   
LogArea.scrollTop = LogArea.scrollHeight
   
errReturn = WshShell.Run(chr(34) & strCurrentPath & "wolcmd.exe" & chr(34) & " " & strWOLAddress & " " & strIPAddress & " " & strNetmask & " 7",0)
    
   
If errReturn <> 0 Then
       
LogArea.Value = LogArea.Value & "ERROR!" & vbCrLf
       
LogArea.Value = LogArea.Value & " " & Err.Description & vbCrLf
       
LogFile.WriteLine(Date & " " & Time & vbTab & "Send Wakeup: ERROR!" & vbTab & Err.Description)
       
LogArea.scrollTop = LogArea.scrollHeight
   
Else
       
WolSuccess = 1
       
LogArea.Value = LogArea.Value & "Wakeup sent to " & strMACAddress & "" & strIPAddress & vbCrLf< font color="#808080">
        LogArea.scrollTop = LogArea.scrollHeight
       
LogFile.WriteLine(Date & " " & Time & vbTab & arrComputers(iList) & ": Wakeup sent to " & strMACAddress)
   
End If
Next

No i wtedy działa :) Jeszcze jedna uwaga – w czasie szukania pól do skryptów niezastąpione jest narzędzie WMI CIM Studio. tylko należy pamiętać, żeby wybrać do przeglądania namespace \Srv1rootSMSsite_LAB gdzie Srv1 to nazwa serwera SCCM, a LAB to trzyliterowy kod site’u. Najciekawsze klasy są w gałęzi – SMS_GroupSMS_G_System_Current*

Powershell portable

Powstaje przenośna wersja PS :D na razie w fazie closed beta. nie ukrywam, że fajnie by było mieć możliwość korzystania z PowłokiMocy w śrowisku WinPE lub BartPE :) Więcej szczegółów tutaj: http://karlprosser.com/coder/2009/07/21/shelltools-portable-powershell-description-survey-and-private-beta/

Visual Studio Unattended

Przyszły wakacje, a więc czas odświeżania oprogramowania w salach laboratoryjnych w PJWSTK. Oczywiście wszystko powinno być nienadzorowane itd. Przez lata instalacje WinXP leżące na RIS było modyfikowane wielokrotnie – Peki, który jest autorem systemu teraz by go już nie poznał ;)

Dobra – zadnie polega na nienadzorowanej instalacji MSSQL2008 (tylko narzędzia klienckie) i Visual Studio 2008. Pierwszą rzeczą jest ustalenie kolejności instalacji. Gdyby zaczynać on VS, to trzeba by zrobić tak:

  • .NET 3.5 + Windows Installer 4.5 (wymaganie SQL2008)
  • restart
  • VS2008
  • restart
  • SP1 do VS2008
  • restart
  • SQL2008
  • restart

No i jakoś dużo tych restartów :/ gdyby zrobić odwrotnie? Zazwyczaj staram się instalować oprogramowanie według kolejności w jakiej wychodzi na świat, ale tutaj zrobię na odwrót :)

  • .NET 3.5 + Windows Installer 4.5
  • restart
  • SQL2008
  • restart
  • VS2008
  • teoretycznie restart, ale już nie wymagany :)

Jest krócej i to sporo :) Dzielimy to na 3 skrypty vbs. stage1.vbs, stage2.vbs i stage3.vbs 
Pierwszy wygląda tak:

Dim WshShell   
Set WshShell = WScript.CreateObject("WScript.Shell")   
WshShell.run "C:scriptsfrmwrkdotnetfx35.exe /qb /norestart",1,true ‚.NET 3.5   
Wait "msiexec.exe","Administrator"   
Wait "setup.exe","Administrator"   
WshShell.run "C:scriptsfrmwrkdotnetfx35SP1.exe /qb /norestart",1,true ‚.NET 3.5 SP1   
Wait "msiexec.exe","Administrator"   
Wait "setup.exe","Administrator"   
‚Windows Installer 4.5   
WshShell.run "C:scriptsWindowsInstallerWindowsXP-KB942288-v3-x86.exe /passive /norestart /overwriteoem /nobackup",1,true   
Wait "msiexec.exe","Administrator"   
Wait "setup.exe","Administrator"   
‚autologin do stage 2   
WshShell.run "c:Windowsregedit.exe /s c:scriptsstage2.reg",1,true   
WshShell.run "c:scriptsshutdown.exe -r -t 30 -f",1,false   

Sub Wait (processName, userName)    
 
On Error Resume Next    
 
Dim objProcess   
 
Dim wmi   
 
Dim isRunning   
 
Dim strUser   
 
Dim return   
 
isRunning = True   
 
set wmi=GetObject("winmgmts:")   
     
 
Do While isRunning   
   
isRunning = False   
   
for Each objProcess in wmi.ExecQuery("select * from Win32_Process")   
       
strUser = ""   
      &#16
0;
return = objProcess.GetOwner(strUser)   
       
If return = 0 Then   
           
if UCase(objProcess.name) = UCase(processName) And UCase(strUser) = UCase(userName) then   
               
isRunning = True   
           
End if           
       
End If   
   
Next   
   
wscript.sleep 1000   
 
Loop   
wscript.sleep 10000   
     
End Sub  

Dla Ciekawskich: Plik stage2.reg wygląda tak:

Windows Registry Editor Version 5.00 

[HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionWinlogon]  
"DefaultDomainName"
="PJWSTK"  
"DefaultUserName"
="Administrator"  
"DefaultPassword"
="StandardoweHasloAdmina"  
"AutoAdminLogon"
="3"  
"ForceAutoLogon"
="1"  

[HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionRun]  
"afterreboot"
="c:\scripts\stage2.vbs"

Jedziemy dalej. Żeby zrobić nienadzorowaną instalację SQL 2008 trzeba przygotować response file. Jako, że informatycy są z natury ludźmi leniwymi pozwoliłem, żeby setup MSSQL zrobił go za mnie :) Po wyklikaniu jakie składniki chcemy mieć na komputerze (w procesie zwykłej instalacji – więcej szczegółów tutaj). Jak już mamy plik odpowiedzi, to jedziemy.

stage2.vbs:

Dim WshShell  
Set WshShell = WScript.CreateObject("WScript.Shell")  
‚naprawiamy MSDTC – czasami przez zepsuty log instalacja potrafi sie wywalać. polega to na zatrzymaniu usługi MSDTC, wywołaniu msdtc -resetlog i ponownym uruchomieniu MSDTC  
WshShell.run "c:scriptsfixmsdtc.cmd",0,true  
‚zatrzymanie usługi Automatic Updates – nie chcemy, żeby jakiś inny setup chodził w tle i nam coś popsuł :)  
WshShell.run "c:scriptsupdatesstop.cmd",1,true  
WshShell.run "P:DbMicrosoftMsSQL2008devsetup.exe /q /CONFIGURATIONFILE=P:DbMicrosoftMsSQL2008devConfigurationFile.ini",0,true  
Wait "setup.exe","Administrator"  
‚znów MSDTC – same kłopoty z tą usługą :/  
WshShell.run "c:scriptsfixmsdtc.cmd",0,true  
‚autologin do stage 3  
WshShell.run "c:Windowsregedit.exe /s c:scriptsstage3.reg",1,true  
WshShell.run "c:scriptsshutdown.exe -r -t 30 -f"< font color="#000000">,1,false  

Sub Wait (processName, userName)   
 
On Error Resume Next   
 
Dim objProcess  
 
Dim wmi  
 
Dim isRunning  
 
Dim strUser  
 
Dim return  
 
isRunning = True  
 
set wmi=GetObject("winmgmts:")  
    
 
Do While isRunning  
   
isRunning = False  
   
for Each objProcess in wmi.ExecQuery("select * from Win32_Process")  
       
strUser = ""  
       
return = objProcess.GetOwner(strUser)  
       
If return = 0 Then  
           
if UCase(objProcess.name) = UCase(processName) And UCase(strUser) = UCase(userName) then  
               
isRunning = True  
           
End if          
       
End If  
   
Next  
   
wscript.sleep 1000  
 
Loop  
 
wscript.sleep 10000    
End Sub 

No już prawie koniec – jeszcze tylko Visual Studio. I tu zaczynają się schody. Teoretycznie robię to według tej instrukcji http://www.msfn.org/board/index.php?showtopic=117875, ale coś się nie udawało. Troszkę poczytać i wiem, że mój system to WinXP SP3. Ta aktualizacja zawiera już w sobie Windows Installera 3.5, więc trzeba odpowiednie wpisy usunąć z pliczku ini (więcej informacji tutaj). Ale to niestety jeszcze nie wszystko. Próba ciche instalacji się kończy po paru minutach. Wystarczy spojrzeć do Event Viewer-a, żeby zobaczyć, że Windows Installer próbuje zainstalować .NET 3.5. Jako, że już mamy nowszą wersję, to  setup zwraca błąd i sie kończy. Więc znów trzeba grzebać się w pliczku. Usuwamy wpisy dotyczące net framework z [PreInstallOrder], [InstallOrder] i [PostInstallOrder] oraz zmieniamy InstallActionInteger komponentu na 1. Teraz bangladesz :) dzięki temu mamy taki pliczek stage3.vbs:

Dim WshShell  
Set WshShell = WScript.CreateObject("WScript.Shell")  
WshShell.run "P:InstalkiMICROSOFTDevelopervisual_studio_2008Setupsetup.exe /UnattendFile P:InstalkiMICROSOFTDevelopervisual_studio_20082008v3.ini",0,true  
Wait "setup.exe","Administrator"  
WshShell.run "cmd /c""echo y|gpupdate /force """,1,true  
WshShell.run "c:winntshutdown.exe -r -t 30",1,false  

Sub Wait (processName, userName)   
 
On Error Resume Next   
 
Dim objProcess  
 
Dim wmi  
 
Dim isRunning  
 
Dim strUser  
 
Dim return  
 
isRunning = True  
 
set wmi=GetObject("winmgmts:")  
    
 
Do While isRunning  
   
isRunning = False  
   
for Each objProcess in wmi.ExecQuery("select * from Win32_Process")  
       
strUser = ""  
       
return = objProcess.GetOwner(strUser)  
       
If return = 0 Then  
           
if UCase(objProcess.name) = UCase(processName) And UCase(strUser) = UCase(userName) then  
               
isRunning = True  
           
End if          
       
End If  
   
Next  
   
wscript.sleep 1000  
 
Loop  
 
wscript.sleep 10000    
End Sub

To by było na tyle :) Działa aż miło :D

skrypt mapujący dyski sieciowe

prosty problem: należy spisać co userzy mają podmapowane oraz jakie mają drukarki sieciowe.
sposób 1: podchodzi i spisywać [BUEEEE!]
sposób 2: napisać skrypt. nie jest to trudne i szybko można znaleźć gotowca w netcie ale jeden drobny problem – zarówno ‘net use’ jak obiekt ‘wscript.network’ nie wyświetlają dysqw, do których nie podano haseł. tymczasem na liście w exploratorze normalnie je widać. po kliknięciu na dysk pojawia się prośba o hasło i dopiero user może skorzystać z dysq. aby wylistować takie jeszcze-niezmapowane dyski wystarczy odczytać je z klucza HKCUNetwork:


const HKCU=&H80000001
Set WshNetwork = WScript.CreateObject("WScript.Network")
computername=WshNetwork.ComputerName
set fso=createObject("Scripting.FileSystemObject")
set f=fso.CreateTextFile(computername&".log")
f.writeline wshnetwork.username
f.writeLine "DYSKI SIECIOWE:"
'enum by network
' Set AllDrives = WshNetwork.EnumNetworkDrives()
' If AllDrives.Count = 0 Then f.writeLine "No Network Disk Mapped "
' For i = 0 To AllDrives.Count - 1 Step 2
' f.writeLine AllDrives.item(i)&" "&AllDrives.item(i+1)
' Next
'enum by registry
set oReg=getObject("winmgmts:!\.rootDefault:StdRegProv")
oReg.enumKey HKCU,"Network",subKeys
for each skey in subKeys
oReg.getStringValue HKCU,"Network"&skey,"RemotePath",val
f.writeLine skey&": "&val
next
f.writeLine vbcrlf&"DRUKARKI SIECIOWE:"
Set objPrinter = wshNetwork.EnumPrinterConnections()
' Extra section to troubleshoot
If objPrinter.Count = 0 Then f.writeline "No Printers Mapped "
' Here is the where the script reads the array
For intDrive = 0 To (objPrinter.Count -1) Step 2
intNetLetter = IntNetLetter +1
f.writeLine objPrinter.Item(intDrive) & " = " & objPrinter.Item(intDrive +1) & " Printer : " & intDrive
Next
f.writeLine "done."

n.

AD Powershell na WS2003/2008 (bez R2)

Tomek Onyszko wygrzebał nowe KB opisujące instalację The Active Directory Management Gateway Service – czyli po ludzku  Active Directory Web Services z R2 :) teraz będzie wreszcie można korzystać z kapitalnego PS dla AD bez potrzeby upgrade kontrolera :D W poniedziałek wrzucam na środowisko testowe ;)

Link do KB: http://support.microsoft.com/?scid=969041

regexp – wyrażenia regularne na prostym przykładzie

odkąd poświęciłem kilka godzin na przegryzienie się przez regexpy zakochałem się w tym wynalzq. możliwość matematycznej reprezentacji zapisu słownego – taki revers języków formalnych – to potężna rzecz.

teraz też się przydało. zadanko: jak z sieczki generowanej przez net view wyciągnąć dyski i literki tak, żeby łatwo było potem je obrabiać?

set re = new RegExp
re.pattern="^([a-zA-Z]:) (\\(?:[a-zA-Z0-9.]+\?)+)"
re.ignoreCase=true

to najważniejsza część całego rozwiązania – regexp definiujący zapis typu “X: \serverjakassciezka a potem cokolwiek”. to “cokolwiek” to dopisywaliśmy jako komentarz do pliq, bo nie przywidywaliśmy, że będzie potrzeba późniejszej modyfikacji/sczytywania. geniusz regexpa polega m.in. na tym, że kiedy coś znajdzie, łatwo to wyciągnąć. wyjaśnienie:

^([a-zA-Z]:)[spacja](\\(?:[a-zA-Z0-9.]+\?)+) – każdy znak ma znaczenie:

  • ^ [dash] – oznacza początek linii. jeśli komentarze dawalibyśmy również na początq – wystarczy usunąć
  • () [nawiasy okrągłe]- oznaczają, że to co będzie pasowało do wyrażenia, zostanie zwrócone jako zmienna, z którą można coś później zrobić. w tym przykładzie będzie to literka dysku z dwukropkiem, która będzie przechowywana – dzięki temu mogę to potem wypisać ją lub przerobić jak chcę [np. zamienić na inną]
  • [] [nawiasy kwadratowe] – oznaczają że chodzi o znak z określonego zakresu. tutaj zakresem jest…
  • a-zA-Z – czyli dowolna litera mała lub duża z zakresu a-z
  • : [dwukropek]– po prostu znak. w sumie całe wyrażenie oznacza dowolny ciąg typu “a:”, “M:” itepe
  • [spacja] – podobnie jak w przypadq dwukropka – wszystko co nie jest poprzedzone znakiem specjalnym jest po prostu tym, czym jest – znakiem. a więc spacja to spacja – ta “[spacja]” z przykaładu
  • () – znów nawias, który oznacza, że będzie zwrócona kolejna zmienna [aka $2] – jak się z nich korzysta będzie później
  • \\ [4 backslashe] – backslash to znak specjalny, który eliminuje specjalność znaków specjalnych (; jeśli np. “+” jest znakiem specjalnym ale chodzi nam o znak a nie o jego funkcję, to trzeba poprzedzić go backslashem “+” – i nie będzie interpretowany. znakiem specjalnym jest również backslash, a więc 4 bcks oznacza ciąg “\”
  • (?:) [pytajnik i dwukropek w nawiasach okrągłych] – potem są znów nawiasy, ale tym razem od razu po nawiasie jest pytajnik i dwukropek. zmiennych zwracanych z regexpa może być 9. przy skomplikowanych dopasowaniach może się okazać, że po prostu chcemy coś zgrupować [np,. po to, żeby powiedzieć, że dany ciąg ma wystąpić X razy] ale nie interesuje nas wynik -  nie będzie przydatny do późniejszej obróbki [ma wyłącznie charakter dopasowania]. wtedy dodaje się “?:” oznaczające “nie zapamiętuj tego dopasowania”
  • [a-zA-Z0-9.]+ – część w nawiasie oznacza dowolny znak z zakresu a-z lub A-Z lub 0-9 lub kropkę. plusik na końcu oznacza od 1 do więcej powtórzeń a więc przykładami dopasowania byłyby “aaa”, “10.20.30”, “asd.kjs.d00.00”
  • \? [2backslashe pytajnik] – jak widać z wcześniejszego przykładu, tak i tutaj znak sterujący jest na końcu – tak to jakoś właśnie w regexpach jest. pytajnik oznacza zero lub jedno wystąpienie tego, co stoi przed nim. a przed nim są 2 backslashe, co oznacza ciąg “” który może być albo nie. a to dla tego że w ścieżce dysq jest: “\server12share” – co odpowiada regexpowi, który można by przeczytać “dwa slashe, potem jedno lub więcej wystąpień ciągu składającego się ze ze znaków alfabetu, cyfr lub kropek, po którym jest lub nie pojedyńczy slash”. no tak jest – jedno wystąpienie “server12” i drugie “share”.

teraz jak to wykorzystać w kodzie:

      set file=fso.OpenTextFile(file) 
      fileBody=split(file.ReadAll,VBCrLf)
      for each line in fileBody
        if re.test(line) then 
         set matches = re.execute(line)
'          for each match in matches
'            wscript.echo match.value
'          next
' same-same but different (: 
          wscript.echo matches(0).submatches(0)&" "&matches(0).submatches(1)
        end if
      next 

zmienna ‘file’ to gdzieś tam zdefiniowana nazwa pliq – nieważne. generalnie otwierany jest plik, powstały przy pomocy ‚net view >> somefile.log’, wczytywany do tablicy, w której kolejny wiersz to linia pliq. no i teraz zaczyna się wykorzystanie wyrażeń regularnych.

  • re.test(line) zwraca true/false – czyli czy znalazł dopasowanie czy nie. a więc jeśli linia zaczyna się ciągiem typu “x: \servershare” to o to chodziło. jak nie – olej.
  • set matches = re.execute(line) – sam test niewiele daje. dla tego tworzony jest obiekt, do którego przypisywany jest wynik [kolekcja] z faktycznego ‘uruchomienia’ wyrażenia – trochę to redundantne bo niby sam test to już zrobił, ale trochę konieczne – to takie zabezpieczenie w stylu ochroną przed dzieleniem przez zero. można nie robić testu i po prostu wykonać execute i zobaczyć co zwraca matches.count – czyli ile jest trafień. do wyboru, do koloru
  • potem jest kilka wykomentowanych linijek, a to dla tego, że dalsza część kodu robi to samo, tylko bardziej uniwersalnie. ale zostawiłem, ponieważ to dwa sposoby wyświetlenia wyników – pierwszy ogólny:
  • for each match in matches – jak pisałem, zwracana jest kolekcja, a więc ‘dla każdego dopasowania w kolekcji’
  • wscript.echo match.value –  match.value to wartość dopasowania – całego – i dla tego ciężko coś z tym zrobić później.
  • wscript.echo matches(0).submatches(0)&" "&matches(0).submatches(1) – w tym konkretnym przypadq wynik na ekranie będzie dokładnie taki sam, ale możliwości są zupełnie inne. wyjaśnia się też tajemnica ‘zapamiętywanych zmiennych’ – które wyszuqje się za pomocą nawiasów (). w przykładzie w nawiasach były dwa dopasowania – litera dysku z dwukropkiem oraz sama ścieżka. i dokładnie to jest wypisywane – matches(0), ponieważ to pierwszy element kolekcji [i w tym przypadq jedyny – dokładnie ten, który był w powyżej wypisany jako całość] – a potem występuje ‘submatches(X)’ – co jest adekwatne do $1, $2 etc – oznacza numer ‘zapamiętaj zmiennej’ liczony od zera. a więc submatches(0) to np. ‘M:’ a submatches(1) to np. “\servershare” dzięki temu można je wykorzystać w dowolnym momencie – choćby zamienić ich kolejność, wykonać operację na jednym z nich [np. uppercase]

regexpy mają wiele fajnych zastosowań – wszędzie tam, gdzie trzebaby w kodzie zrobić pierdylion if’ów, case’ów i innych wynalazków – które średnio się nadają do operacji na niezbyt przewidywalnych stringach. dzięki wyrażeniom regularnym można zdefiniować to w lu
dzkim języq.. chociaż wygląda totalnie nieludzko i mało podobnie do języka (; przykładem zastosowania są zasady normalizacji numerów telefonów – czy ktoś wpisze +48 czy 22 czy +4822 czy tylko numer telefonu, a może potem jest jakiś numer wewnętrzny? a jak firma jest w kilq lokalizacjach to prefixy będą inne, a czy numer telefonu ktoś wpisał jako 345-67-89 czy może 3456789 a może ze spacjami?… i tak dalej. a na wyjściu musi zawsze być znormalizowany numer telefonu dla danej lokalizacji. zapisuje się to bardzo prostymi wyrażeniami regularnymi w stylu “^((00|+)48)?(d{3}.?d{2}.?d{2})(d{4})?” q: pisząc to mam na myśli OCS, i tak na prawdę to wygląda tam dużo prościej.

reasumując – niewiarygodnie wygodne narzędzie, które może nie przydaje się na co dzień ale kiedy jest dla niego zastosowanie, robienie tego innymi metodami jest strzałem w kolana.

linki

ps. czemu nie w powerShell? bo siedzę tam, gdzie się teren jeszcze renderuje, i musiałem skleić coś na szybko. ale uh… trzeba będzie usiąść i do poweshella

n.