Megosztási engedélyek

A megosztások engedélyeinek beállítása sem egyszerű feladat, hasonlóan a többi objektuméhoz. Ráadásul itt WMI objektumok metódusainak hívásával tudunk engedélyeket állítani, ami tovább bonyolítja a helyzetet. Úgyhogy példaként ne is nulláról kezdjük egy megosztás engedélyeinek beállítását, hanem legyen az a feladta, hogy egy távoli kiszolgálón levő meglevő megosztásokat másoljuk át a helyi gépre. Ez jól jöhet akkor például, ha egy régi kiszolgálóról át szeretnénk migrálni az adatokat egy újra. Ráadásul nem csak a megosztási szintű jogosultságokat szeretnénk lemásolni, hanem az NTFS szintű jogokat is. Nézzük az ezt megvalósító függvényt, aztán egy kis magyarázatot:

function copy-share ($remote){

 

$wc = New-Object -TypeName WMIClass -ArgumentList Win32_Share

 

Get-WmiObject -Class Win32_ShareToDirectory -ComputerName $remote | %{ 

    $share = if($_.share -match '"(.+)"'){$matches[1] -replace "\\\\","\"} 

    $dir = if($_.sharedelement -match '"(.+)"'){$matches[1] -replace "\\\\","\"} 

    New-Object -TypeName PSObject -Property @{share = $share; dir = $dir} 

} | ?{$_.share -notmatch '\$$'} | %{ 

    if(!(test-path $_.dir)){ 

        New-Item -Path (Split-Path $_.dir -Parent) -Name (Split-Path $_.dir -Leaf) -ItemType directory > $null 

    } 

    $shpath = $_.dir -replace "^(\w):", "\\$remote\`$1`$" 

    get-acl -Path $shpath | set-acl $_.dir 

    $wc.Create($_.dir,$_.share,0) > $null 

    $sharesec = ([WMI] "\\$remote\root\cimv2:Win32_LogicalShareSecuritySetting.Name='$share'").GetSecurityDescriptor().descriptor 

    ([WMI] "\\localhost\root\cimv2:Win32_LogicalShareSecuritySetting.Name='$share'").setSecurityDescriptor($sharesec) > $null 

    Get-ChildItem -Path "\\$remote\$share" -Force | Copy-Item -Destination $dir -Recurse 

    Get-ChildItem -Path "\\$remote\$share" -Recurse -Force | get-acl | %{ 

        set-acl -Path ($_.path -replace "\\\\$remote\\","\\localhost\") -AclObject $_ 

    } 

}

}

A függvény fejléce után létrehozom a $wc változóba a korábban már látott WMIClass objektumomat. Utána elkezdem listázni a távoli gép Win32_ShareToDirectory objektumait. Ez azért jó nekünk, mert ebben a Share és SharedElement tulajdonságokban a megosztások és a hozzájuk tartozó helyi elérési utak is elérhetők. Nézzük mit is ad ez a WMI osztály:

[1] PS C:\> Get-WmiObject -Class Win32_ShareToDirectory

 

 

__GENUS          : 2

__CLASS          : Win32_ShareToDirectory

__SUPERCLASS     :

__DYNASTY        : Win32_ShareToDirectory

__RELPATH        : Win32_ShareToDirectory.Share="\\\\SOOST-PC\\root\\cimv2:Win

                   32_Share.Name=\"ADMIN$\"",SharedElement="\\\\SOOST-PC\\root

                   \\CIMV2:Win32_Directory.Name=\"c:\\\\windows\""

__PROPERTY_COUNT : 2

__DERIVATION     : {}

__SERVER         : SOOST-PC

__NAMESPACE      : root\cimv2

__PATH           : \\SOOST-PC\root\cimv2:Win32_ShareToDirectory.Share="\\\\SOO

                   ST-PC\\root\\cimv2:Win32_Share.Name=\"ADMIN$\"",SharedEleme

                   nt="\\\\SOOST-PC\\root\\CIMV2:Win32_Directory.Name=\"c:\\\\

                   windows\""

Share            : \\SOOST-PC\root\cimv2:Win32_Share.Name="ADMIN$"

SharedElement    : \\SOOST-PC\root\CIMV2:Win32_Directory.Name="c:\\windows"

A Share és SharedElement tényleg jó lesz nekünk. Némi kis regex-szel és egyedi objektum létrehozásával, valamint a $-ra végződő admin megosztások kiszűrésével egész jó kis áttekintést kapunk:

[2] PS C:\> $remote = "."

[3] PS C:\> Get-WmiObject -Class Win32_ShareToDirectory -ComputerName $remote |

 %{

>>     $share = if($_.share -match '"(.+)"'){$matches[1] -replace "\\\\","\"}

 

>>     $dir = if($_.sharedelement -match '"(.+)"'){$matches[1] -replace "\\\\",

"\"}

>>     New-Object -TypeName PSObject -Property @{share = $share; dir = $dir}

>> } | ?{$_.share -notmatch '\$$'}

>> 

 

share                                   dir

-----                                   ---

download                                c:\download

e14                                     c:\_munka\e14

powershell                              c:\_munka\powershell

Users                                   c:\users

_munka                                  c:\_munka

A függvény következő soraiban sok újdonság nincsen, ellenőrzöm, és ha nincsen, akkor létrehozom a helyi gépen a szükséges mappákat, lemásolom a jogosultságokat, majd megosztom ezeket. Ezután jön a fejezetünk fő motívuma, a megosztásszintű jogosultságok lekérdezése:

[16] PS C:\> ([WMI] "\\SOOST-PC\root\cimv2:Win32_LogicalShareSecuritySetting.Na

me='_munka'").getsecuritydescriptor().descriptor

 

 

__GENUS          : 2

__CLASS          : Win32_SecurityDescriptor

__SUPERCLASS     : __SecurityDescriptor

__DYNASTY        : __SecurityRelatedClass

__RELPATH        :

__PROPERTY_COUNT : 6

__DERIVATION     : {__SecurityDescriptor, __SecurityRelatedClass}

__SERVER         :

__NAMESPACE      :

__PATH           :

ControlFlags     : 32772

DACL             : {System.Management.ManagementBaseObject}

Group            :

Owner            :

SACL             :

TIME_CREATED     :

A nehézséget itt az jelenti, hogy például a ControlFlags egy szám, amit így elég nehéz értelmezni. De ha jobban beljebb megyünk a DACL irányába, akkor sem túl olvasmányos a tartalma:

[17] PS C:\> ([WMI] "\\SOOST-PC\root\cimv2:Win32_LogicalShareSecuritySetting.Na

me='_munka'").getsecuritydescriptor().descriptor.dacl

 

 

__GENUS                 : 2

__CLASS                 : Win32_ACE

__SUPERCLASS            : __ACE

__DYNASTY               : __SecurityRelatedClass

__RELPATH               :

__PROPERTY_COUNT        : 7

__DERIVATION            : {__ACE, __SecurityRelatedClass}

__SERVER                :

__NAMESPACE             :

__PATH                  :

AccessMask              : 2032127

AceFlags                : 0

AceType                 : 0

GuidInheritedObjectType :

GuidObjectType          :

TIME_CREATED            :

Trustee                 : System.Management.ManagementBaseObject

Még tovább is lehet ásni a Trustee tulajdonság irányába:

[19] PS C:\> ([WMI] "\\SOOST-PC\root\cimv2:Win32_LogicalShareSecuritySetting.Na

me='_munka'").getsecuritydescriptor().descriptor.dacl[0].trustee

 

 

__GENUS          : 2

__CLASS          : Win32_Trustee

__SUPERCLASS     : __Trustee

__DYNASTY        : __SecurityRelatedClass

__RELPATH        :

__PROPERTY_COUNT : 6

__DERIVATION     : {__Trustee, __SecurityRelatedClass}

__SERVER         :

__NAMESPACE      :

__PATH           :

Domain           :

Name             : Everyone

SID              : {1, 1, 0, 0...}

SidLength        : 12

SIDString        : S-1-1-0

TIME_CREATED     :

Szóval nem túl egyszerű, ezért nem akartam én új jogosultságot definiálni, hanem csak a meglevőt másolni. Azaz először eltárolom a teljes biztonsági leírót a $sharesec változóba, majd a  SetSecurityDescriptor metódussal az újonnan létrehozott megosztásra ráteszem, azaz átmásolom. Ezután már csak a mappa tartalmát kell átmásolni és az alacsonyabb szinteken esetlegesen eltérő jogosultságokat átmásolni. És készen is vagyunk.

Valószínű valamilyen migráló eszköz, vagy akár a RoboCopy mindezt egyszerűbben megoldaná, de ezeknél nincs a kezünkben a testre szabás lehetősége, így egy saját megoldás mindig nagyobb szabadságot ad nekünk, nem beszélve a sikerélményről!



Word To HTML Converter