Create Windows shares on remote servers

By Andrei Ungureanu - Last updated: Tuesday, March 20, 2018

Cum in ultimul timp ma invart numai prin probleme legate de file server, permisiuni NTFS si network share-uri, tot invat cum sa fac anumite task-uri in diverse moduri. Iar sa creezi un share pe o masina remote e tricky cateodata. Pe vremuri foloseam PSEXEC si rulam MKDIR si NET SHARE. Dar acum avem pretentii de la Powershell. Problema e ca prin noile comenzi din modulul SMB, tot nu merge. Poti sa fac share-uri local, dar nu remote. Sau poti folosi Invoke-Command si sa rulezi New-SMBShare sau NET SHARE remote.

Dar ce faci daca PS Remoting nu e activat. Si tot la WMI ajungem, dar de data asta via Powershell:

$newShare = Get-WmiObject win32_share -ComputerName numeserver -list
$newShare.Create("c:\path","numeShare",0)

image

Cand creati instanta lui Win32_Share trebuie sa folositi parametrul –List, altfel nu o sa vedeti metoda Create.

Parametrii folositi au fost Path, Share Name si Type. Type se refera la disk, printer etc. In cazul nostru am folosit 0 ce reprezinta Disk Drive.

Ca sa determinati daca taskul a fost efectuat cu succes, ReturnValue trebuie sa fie 0.

Documentatia completa o gasiti aici:

https://msdn.microsoft.com/en-us/library/aa389393(v=vs.85).aspx

Filed in Scripting, Windows Server • Tags: , , ,

Running commands on remote computers from Powershell

By Andrei Ungureanu - Last updated: Monday, March 19, 2018

A cam trecut vremea de cand singura varianta ca sa rulezi ceva pe un sistem remote se facea prin PSEXEC. In ultimii ani am folosit Powershell si PS Remoting pentru astfel de activitati insa as vrea azi sa prezint si cum se face plus o alternativa in caz ca Powershell Remoting nu este activat sau accesati sisteme mai vechi.

Prima data e util sa stiti cum sa testati daca sistemul remote are activat  Powershell Remoting. Prima data puteti  incerca sa verificati daca sistemul remote este online prin Test-NetConnection. Iar apoi o alta verificare partiala se poate face prin comanda Test-WSMan.

image

Daca returneaza eroare (si automat $False) atunci WinRM nu este activat si automat nici PS Remoting nu o sa mearga. Dar daca este activat atunci puteti incerca sa rulati o comanda remote folosind Invoke-Command. Si daca rezultatul va fi $False atunci probabil nu aveti drepturile necesare si colectati mesajul de eroare.

Invoke-Command functioneaza cam asa: Invoke-Command –ComputerName NumeleServerului {scriptblock}. In scriptblock puteti pune efectiv un script; o serie de comenzi despartite prin punct si virgula.

Iar in exemplul de mai jos am luat un caz simplu in care trebuie sa cream doua foldere pe sistemul remote. In exemplul asta trimitem si niste parametri catre comanda MKDIR din acel scriptblock. Vedeti mai jos cum se foloseste –ArgumentList (este un array, ce apoi il accesati din interiorul acoladelor).

image

Suficient pana aici ca sa va faceti o idee. Sunt multe de spus dar nu o sa mai dezvolt. in schimb o sa mai prezint o varianta prin care puteti executa aceasta operatiune si fara Powershell remoting.

Daca va mai aduceti aminte si prin WMI exista o clasa numita Win32_Process ce poate instanta procese remote. Iar cu Invoke-WmiMethod puteti face asta remote:

image

De data asta ArgumentList este diferit si aici punem de fapt procesul sau comanda ce vrem sa ruleze remote. Doar ca de exemplu, pentru ca MKDIR sa ruleze, acesta trebuie sa fie in contextul unui command prompt. Asa ca va trebui sa il rulati cu CMD /C. In cazul de mai sus numele folderului il puteti in locui cu o variabila locala (in primul exemplu cu Invoke-Command nu merge si trebuie sa folositi –ArgumentList).

Mai greu va fi sa colectati erorile in caz ca ceva nu merge. ReturnValue va fi 0 chiar si daca MKDIR va esua. Asta pentru ca win32_process a reusit sa porneasca CMD.EXE dar mai departe nu are vizibilitate daca a si mers comanda.

Sper sa va fie utila infomatia de mai sus.

Filed in Scripting, Windows Client, Windows Server • Tags: , ,

Getting a list of network mapped drives based on the network path

By Andrei Ungureanu - Last updated: Saturday, March 17, 2018

In exemplul de astazi o sa iau ca task listarea maparilor in retea catre un anumit server. Operatiunea asta ne poate ajuta sa identificam la nivelul unui client, daca are mapari facute catre un anumit file server.

Optiunile ar fi sa folosim WMI si clasa WIN32_LogicalDisk sau direct Get-PSDrive. Daca rulam Get-PSDrive obtinem ceva de genul:

image

Si as vrea sa filtrez si sa mi se returneze doar drive-ul X: care mapeaza catre un anumit file server. Iar asta o facem folosind comanda: gwmi win32_logicaldisk |? {$_providername –match “server”}.

image

Sau daca folosim Get-PSDrive va trebui sa filtram dupa DisplayRoot, chiar daca proprietatea afisata se numeste doar Root:

Get-PSDrive |? {$displayroot –match “server”}

image

In cazul migrarii unui file server putem folosi tehnica asta pentru a identifica unde se foloseste vechiul nume si eventual il putem modifica.

Filed in Scripting, Windows Client, Windows Server • Tags: ,

NTFS: the case when Deny permissions don’t apply

By Andrei Ungureanu - Last updated: Sunday, March 11, 2018

Cand setezi Deny de fiecare data esti intampinat cu urmatorul avertisment. Si e bine ca apare, ca de multe ori poti sa iti tai singur accesul.

image

Dar exista si un caz cand Deny nu este chiar atat de puternic. Cand Deny este mostenit de la un obiect parinte, si adaugam dreptul explicit de Allow pe obiectul in cauza, atunci dreptul setat explicit castiga (chiar daca prin combinarea drepturilor avem un Deny).

Iar documentatia spune fix la fel:

https://technet.microsoft.com/en-us/library/cc783530(v=ws.10).aspx

Filed in Windows Client, Windows Server • Tags:

And another way on how to identify and list network mapped drives in Powershell

By Andrei Ungureanu - Last updated: Saturday, March 10, 2018

Pe tema asta am mai scris de nu stiu cate ori dar de fiecare data mai gasesc cate ceva nou. Incercasem sa evit pana acum sa folosesc Get-WmiObject dar se pare ca e o varianta mai buna decat Get-PSDrive.

Si iata de ce. Cu Get-WmiObject –Class Win32_logicaldisk mai obtii o proprietate numita DriveType si in functie de asta poti filtra dupa mapari in retea:

Get-WmiObject -Class Win32_logicaldisk -Filter "DriveType = ‘4’"

image

PS: DriveType 3 e pentru disk local iar 2 pentru removable.

Filed in Windows Client, Windows Server • Tags: ,

Searching Active Directory from Powershell without using the AD module

By Andrei Ungureanu - Last updated: Saturday, March 10, 2018

Cu modulul Active Directory poti cauta foarte usor obiecte si genera tot felul de rapoarte. Dar sunt suficiente cazuri cand nu vrei sa le folosesti. Cateodata se intampla sa te lovesti de o limitare a comenzilor sau AD Web services, performanta, sau bug-uri. Sau pur si simplu o sa rulezi scriptul pe o masina ce nu are modulul AD instalat. Si atunci e bine sa stii ca mai exista si alte variante.

Una dintre ele este ADSI si este foarte simplu de folosit. Iata un exemplu mai jos:

$search = [adsisearcher]"(&(ObjectCategory=Person)(ObjectClass=User)(cn=test*))"
$users = $search.FindAll()
Write-Host "Found $($users.Count) objects"
If ($users.count -gt 0)
{
    foreach($user in $users)
    {
        $user.Properties[‘SamAccountName’]
    }
}

Iata si rezultatul rularii acestei portiuni de cod:

image

PS: Se poate si prin DirectorySearcher .Net Class.

Filed in Active Directory, Scripting • Tags: , ,

Access Based Enumeration (ABE) and Windows 10

By Andrei Ungureanu - Last updated: Sunday, March 4, 2018

In postul precedent am scris despre ceva legat de permisiuni si am mentionat si Access Based Enumeration (ABE). ABE este o functionalitate a Windows-ului ce face ca un server ce share-uieste foldere/fisiere sa arate clientului doar resursele la care acesta are acces.

Si cum in articolul precedent am mentionat cazul in care nu este dat dreptul “Read Permissions”, ABE o sa impiedice listarea folderelor/fisierelor pe care clientul nu are acest drept.

Din Windows Server, poti activa/dezactiva ABE simplu din Server Manager si proprietati pe share.

image

In schimb daca ai Windows 10 si il folosesti sa dai share la resurse in retea, eu personal nu am gasit de unde poti face lucrul asta din interfata. Asa ca trecem la Powershell si modulul SMBShare.

Cu Get-SmbShare putem afla detalii despre un share (chiar si unul default gen C$).

image

Dar parca nu e suficient. Asa ca incercam sa includem toate proprietatile folosind FL *.

image

Iar aici ne intereseaza proprietatea FolderEnumerationMode. Cand e pe AccessBased inseamna ca ABE este activat. Cand e pe Unrestricted e dezactivat.

Ca sa dezactivam ABE folosim Set-SmbShare -FolderEnumerationMode Unrestricted:

image

Este nevoie sa rulati comanda dintr-un shell cu drepturi elevate sau cu UAC dezactivat (nerecomandat).

PS: comenzile astea pot fi folosite la fel si pe Windows Server.

Filed in Windows Client, Windows Server • Tags: , , ,

Granting list folder contents only in Windows/NTFS

By Andrei Ungureanu - Last updated: Sunday, March 4, 2018

Sa setezi in Windows permisiuni ca cineva sa poata vedea lista fisierelor dar sa nu poata accesa continutul e destul de tricky. Unii ar spune chiar ca nu se poate. Dar se poate. In felul asta poti da permisiunea de list folder contents si apoi drepturi depline de read pe un anumit fisier. E de preferat totusi sa ocoliti scenariile astea si sa setati permisiunile la nivel de folder.

Drepturile necesare le vedeti in imaginea de mai jos:

image

Important este sa nu dati dreptul “Read permissions”. Prin acest drept se controleaza accesul la ACL si daca nu il ai nu poti deschide fisierul dar il poti vedea.  Avantajul este ca se aplica si pe foldere si pe fisiere. Pe cand combinatia ListFolder/ReadData e diferita: Read Data se aplica pe fisiere iar List Folder pe foldere. Deci daca activezi List Folder automat dai drept de read pe fisiere. Solutia e sa controlezi prin Read Permissions. Sau bineinteles sa te duci sa faci modificari la nivel de fisier.

Cu drepturile astea date am facut un test pe un user (ce este chiar admin pe masina locala) si care are doar drepturile din imaginea de mai sus. Pot sa listez fisierele din folder, dar cand incerc sa deschis un fisier iata ce se intampla:

image

Testul meu a fost unul local. Daca incercati sa faceti acest lucru pe un share cu ABE activat (Access Based Enumeration) nu o sa vedeti deloc fisierele/folderele pentru care nu aveti Read Permission. Asa ca varianta ar fi sa dezactivati ABE.

image

Filed in Windows Client, Windows Server • Tags:

Adding–WhatIf and–Confirm to your Powershell scripts

By Andrei Ungureanu - Last updated: Wednesday, February 28, 2018

Recent am avut de facut un script ce modifica informatii din Active Directory, si printre mecanismele de protectie am adaugat si WhatIf. Dar intr-un mod primitiv. Am pus o gramada de If/Else si am rulat comenzile din interiorul scriptului cu WhatIf.

Dupa ce am terminat scriptul am aflat si eu ca puteam implementa WhatIf si Confirm la nivel de script sau functie doar printr-o simpla delcaratie.

Simpla adaugare la inceputul scriptului a urmatoarelor:

[CmdletBinding(SupportsShouldProcess)]

Param()

Va implementa suportul pentru WhatIf si Confirm.

Ruland scriptul cu parametrul –WhatIf va face ca fiecare comanda din script ce implementeaza WhatIf sa ruleze in acest mod. Fara a mai pune o gramada de If/Else si alt cod redundant.

Ceva mai detaliat gasiti si aici: https://blogs.technet.microsoft.com/poshchap/2014/10/24/scripting-tips-and-tricks-cmdletbinding/

Iar daca vreti sa verificati in interiorul scriptului daca s-a folosit parametrul WhatIf puteti verifica variabila $WhatIfPreference. Un exemplu mai jos:

If ($WhatIfPreference)
{
    Write-Host "Script is running in WhatIf mode." -ForegroundColor yellow -BackgroundColor Black
}

Filed in Scripting • Tags: ,

Basic version control for your enterprise powershell scripts

By Andrei Ungureanu - Last updated: Sunday, February 25, 2018

In lumea celor ce scriu cod in mod profesional, version control e ceva uzual si pentru care exista solutii. In schimb pentru cei care nu scriem cod zi de zi sunt momente cand e dificil sa gestionam versiunile scripturilor.

Scenariul e de genul: am scris un script care in spate executa cateva actiuni si care a ajuns sa fie distribuit mai multor sysadmini din organizatie. Scriptul ajunge sa fie stocat pe un share, cateodata chiar distribuit pe email si in final ajunge pe desktop-ul unui sysadmin sau poate si pe un server de unde il ruleaza.

Intre timp cel ce l-a scris a mai adaugat cate ceva la script sau poate a corectat un bug. Cum putem sa facem in asa fel ca cel ce ruleaza scriptul sa fie informat ca exista o versiune mai recenta si sa o downloadeze dintr-un repository central?

Sincer nu e nimic nou sau complex in toata chestia asta, ci doar mai mult un sfat despre cum ai putea sa implementezi o solutie basic la aceasta problema.

Asa ca in opinia mea cea mai simpla varianta ar fi ca scriptul sa verifice o locatie accesibila de peste tot din companie. Se poate face si web based, dar cum discutam de ceva foarte simplu si in contextul unui sysadmin care part time mai face si cate un script cel mai simplu ar fi ca versiunea curenta sa fie stocata ca si valoare numerica intr-un fisier text stocat intr-un share.

Folosim Get-Content ca sa citim continutul fisierului text. In cel mai simplu scenariu, fisierul va contine doar o valoare numerica. Putem sa complicam lucrurile si sa tinem mai multe valori in acest fisier si pe baza lor sa luam decizii, dar va las pe voi sa va imaginati scenarii.

$currentversion = Get-Content \\Server\Share\appcurrentversion.txt

In script va exista si o variabila $ScriptVersion ce va tine versiunea scriptului. Dupa ce citim $currentversion din retea, trebuie doar sa comparam valorile cu ceva de genul:

$scriptversion -le $currentversion

Luand exemplul de mai sus, daca valoarea stocata in script $scriptversion e mai mica decat cea din retea $currentversion putem lua anumite decizii, gen sa terminam executia scriptului sau sa il lasam sa continue dar sa informam uitilizatorul ca exista o versiune mai noua si sa ii spunem de unde sa o ia.

Logica asta o putem pune foarte usor intr-o functie pe care mai apoi sa o portam la toate scripturile ce vor fi distribuite in companie.

Filed in Scripting • Tags: ,