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!