none
Script powershell per creazione directory di rete RRS feed

  • Domanda

  • Buonasera

    Ho creato uno script in powershell per creare automaticamente delle cartelle utente su un file server

    Se l'utente esiste nell'active directory mi crea 3 cartelle sotto la share di dominio \\azienda.locale\Utenti\

    Utenti

    Ogni cartella è ha differenti accessi
    -
    \\azienda.locale\Utenti\utente\Pubblica   (lettura per tutti / scrittura per il proprietario)
    -
    \\azienda.locale\Utenti\utente\Privata     (lettura e scrittura solo per il proprietario)
    - \\azienda.locale\Utenti\utente\Scambio   (lettura e scrittura proprietario | solo scrittura per tutti) Ha la funzione come della cassetta delle lettere. Si deposita ma non si legge servirà per evitare lo scambio dei documenti per email.....

    Il problema è che non riesco a settare correttamente i permessi per la cartella di scambio

    Se non metto fullcontrol ma solo $colRights = [System.Security.AccessControl.FileSystemRights]"ReadAndExecute, Traverse" 

    L'utente non riesce ad aprire i file che sono copiati perchè rimangano i permessi del precedente proprietario.

    Se metto fullcontrol l'utente riesce ad aprire i documenti correttamente ma riesce anche a cancellare la directory scambio e vorrei impedire questo.

    Ecco la parte di codice incriminata

    .... 

        $AclS = Get-Acl $DIRUSERNAME
     
        #setto permessi parente scambio/drop
        $Acl=$AclS
        $colRights = [System.Security.AccessControl.FileSystemRights]"Write"
        $InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
        $PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
        $objType =[System.Security.AccessControl.AccessControlType]::Allow
        $Ar = New-Object  system.security.accesscontrol.filesystemaccessrule("Everyone",$colRights,$InheritanceFlag,$PropagationFlag,$objType)
        $Acl.SetAccessRule($Ar)
        Set-Acl $DIRUSERNAME_DROP $Acl
               
        $Acl=$AclS
        $colRights = [System.Security.AccessControl.FileSystemRights]"FullControl"    
        $PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
        $objType =[System.Security.AccessControl.AccessControlType]::Allow
        $Ar = New-Object  system.security.accesscontrol.filesystemaccessrule($nome,$colRights,"ContainerInherit, ObjectInherit",$PropagationFlag,$objType)
        $Acl.SetAccessRule($Ar)
        Set-Acl $DIRUSERNAME_DROP $Acl
    ....   
       
           
    Spero di essere stato chiaro e che mi potete dare una mano

     

    grazie

    Marco 


    martedì 6 dicembre 2011 14:14

Risposte

  • Ciao Marco,

    ho ragionato sul problema e come dicevo nel post precedente è solo un problema di utilizzare i permessi corretti per ottenere il risultato voluto.

    Solitamente per la gestione delle ACL negli script utilizzo varie applicazioni (cacls, icacls, subInACL, xcacls, setacl ...) ma visto che powershell può gestirle nativamente, ho pensato di  usare SDDL  "Security Descriptor Definition Language" per settare le Acl giuste sulle directories create.

    Lo script in allegato è equivalente al tuo, con il vantaggio di poter utilizzare SDDL per il settaggio delle ACL.

    ACL per DropFolder  "D:PAI(A;OICIIO;FA;;;CO)(A;OICI;0x100116;;;AU)(A;OICI;FA;;;SY)"

     

     

    <#
     
     By Gastone Canali
     http://www.armadillo.it
     
    #>
    # All user whose name starting with g
    $UserName="g*"
    # User profiles home
    $HomesPath = "k:\UserProfileHomes"
    # Folders created inside "home folder"
    $dirs=@("pubblic","private","drop")
    
    function change-sddl($dir,$user,$protosddl) {
       $tmpdir=$dir+"\"+[System.IO.Path]::GetRandomFileName()
       mkdir $tmpdir |Out-Null
       $acl = Get-Acl $tmpdir
       rmdir $tmpdir|Out-Null
       $sid=(ConvertTo-Sid  $User).value
       $newsddl = $protosddl+"(A;OICI;FA;;;$sid)"
       $acl.SetSecurityDescriptorSddlForm($newsddl)
       Set-Acl $dir  $acl
    }
    function ConvertTo-Sid ($NtAccount) {
        (new-object system.security.principal.NtAccount($NTaccount)).translate([system.security.principal.securityidentifier])
    }
    function IsAdministrator {   
        $identity  = [System.Security.Principal.WindowsIdentity]::GetCurrent()
        $principal = New-Object System.Security.Principal.WindowsPrincipal( $identity )
    	$principal.IsInRole( [System.Security.Principal.WindowsBuiltInRole]::Administrator )
    }
    # owner an NT Authority\System  full control, Authenticated Users only write permission 
    #  Authenticated Users can drop files inside but not read ...
    $drop_sddl    = "D:PAI(A;OICIIO;FA;;;CO)(A;OICI;0x100116;;;AU)(A;OICI;FA;;;SY)"
    # owner an NT Authority\System  full control
    #
    $private_sddl = "D:PAI(A;OICIIO;FA;;;CO)(A;OICI;FA;;;SY)"
    # owner an NT Authority\System  full control, Authenticated Users Readonly
    #
    $pubblic_sddl = "D:PAI(A;OICI;0x1200a9;;;AU)(A;OICI;FA;;;SY)"
    
    Clear-Host
    if (!(IsAdministrator)) {
    @"
     ========================================================================
     Errore: diritti insufficienti
     Riavviare lo script con un utente che abbia i diritti di amministrazione
     ========================================================================
    "@
    exit
    }
    
    $strFilter = "(&(objectCategory=User)(userPrincipalName=$UserName))"
    $objDomain = New-Object System.DirectoryServices.DirectoryEntry
    $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
    $objSearcher.SearchRoot = $objDomain
    $objSearcher.SearchScope = "Subtree" 
    $objSearcher.PageSize = 1000 
    $objSearcher.Filter = $strFilter
    $Results = $objSearcher.FindAll()
    foreach ($upn in $Results) {
            $u = [string] $upn.GetDirectoryEntry().UserPrincipalName
            echo "working on $u ..."
            $usr, $dom =  $u.Split("@")
    		#([string]$u).Split("@")[0]
            $HomeUsr=$homesPath+"\"+$usr
            if (-not (Test-Path   $HomeUsr)) { md $HomeUsr|Out-Null}
            $(foreach ($D in $dirs) { if (-not (Test-Path ("$HomeUsr\"+"$D"))) { md ("$HomeUsr\"+"$D")|Out-Null}})   
            change-sddl -dir "$homeUsr\$pri"  -protosddl "$private_sddl" -user "$u"
            change-sddl -dir "$homeUsr\$Dro"  -protosddl "$drop_sddl"    -user "$u"
            change-sddl -dir "$homeUsr\$Pub"  -protosddl "$pubblic_sddl" -user "$u"
        }
    

     

    Ciao Gas

    Gastone Canali - http://www.armadillo.it

     

     SDDL http://blogs.dirteam.com/blogs/jorge/archive/2008/03/26/parsing-sddl-strings.aspx

     

     


    lunedì 12 dicembre 2011 15:44
    Moderatore

Tutte le risposte

  • Allego lo script usato per la creazione delle 3 cartelle

     

    Param([Parameter(Mandatory=$true)]$UserName)

    Clear-Host;

    $PATH = "\\azienda.locale\share\utenti"

    #Nome delle directory
    $PUB="pubblica"
    $PRIV="privata"
    $DROP="scambio"
    $DOMINIO="@azienda.locale"

    #MAIN
    Write-Host "=============================================";
    Write-Host "ATTENZIONE";
    Write-Host "Questo script genera le directory per l'utente";
    Write-Host "Deve girare con profili di administrator";
    Write-Host "=============================================";

    #imposto filtro di ricerca su Active Directory
    $strFilter = "(&(objectCategory=User)(userPrincipalName=$UserName"+$DOMINIO+"))"

    Write-Host $strFilter;

    #Pesco la lista utneti appartenenti al gruppo
    $objDomain = New-Object System.DirectoryServices.DirectoryEntry
    $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
    $objSearcher.SearchRoot = $objDomain
    $objSearcher.PageSize = 1000
    $objSearcher.Filter = $strFilter
    $objSearcher.SearchScope = "Subtree"

    #recordset dei risultati
    $objresult=$objSearcher.FindOne()

    #Controlla se l'utente esiste nel dominio
    if ($objresult -eq $null)
     {
     Clear-Host;
     Write-Host "*********************************";
     Write-Host "Nome: $UserName";
     Write-Host "*********************************";
     Write-Host "NON è PRESENTE NEL DOMINIO $DOMINIO";
     Write-Host "*********************************";
     Write-Host "Filtro applicato  = "$strFilter;
     exit;
     }

        $user= $objresult.GetDirectoryEntry()       
       
        #Prendo il nome di dominio compreso il dominio username@domain
        $nome = [string] $user.UserPrincipalName
        Write-Host $nome;
       
        #Prendo solo lo username separandolo appena trovo @
        $directory = $nome.Split("@")
        $username = $directory[0]
           
        $DIRUSERNAME=$PATH+"\"+$username
        $DIRUSERNAME_PUB=$PATH+"\"+$username+"\"+$PUB
        $DIRUSERNAME_PRIV=$PATH+"\"+$username+"\"+$PRIV
        $DIRUSERNAME_DROP=$PATH+"\"+$username+"\"+$DROP   
           
        [Io.Directory]::CreateDirectory($DIRUSERNAME)
        [Io.Directory]::CreateDirectory($DIRUSERNAME_PUB)
        [Io.Directory]::CreateDirectory($DIRUSERNAME_PRIV)
        [Io.Directory]::CreateDirectory($DIRUSERNAME_DROP)

        $AclS = Get-Acl $DIRUSERNAME
           
        #setto permessi parente directory
        $Acl=$AclS
        $colRights = [System.Security.AccessControl.FileSystemRights]"Read, Traverse"
        $InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
        $PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
        $objType =[System.Security.AccessControl.AccessControlType]::Allow
        $Ar = New-Object  system.security.accesscontrol.filesystemaccessrule("Everyone",$colRights,$InheritanceFlag,$PropagationFlag,$objType)
        $Acl.SetAccessRule($Ar)
        Set-Acl $DIRUSERNAME $Acl
       
        #setto permessi parente scambio/drop
        $Acl=$AclS
        $colRights = [System.Security.AccessControl.FileSystemRights]"Write"
        $InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
        $PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
        $objType =[System.Security.AccessControl.AccessControlType]::Allow
        $Ar = New-Object  system.security.accesscontrol.filesystemaccessrule("Everyone",$colRights,$InheritanceFlag,$PropagationFlag,$objType)
        $Acl.SetAccessRule($Ar)
        Set-Acl $DIRUSERNAME_DROP $Acl
               
        $Acl=$AclS
        $colRights = [System.Security.AccessControl.FileSystemRights]"FullControl"
        #$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::ContainerInherit
        $PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
        $objType =[System.Security.AccessControl.AccessControlType]::Allow
        $Ar = New-Object  system.security.accesscontrol.filesystemaccessrule($nome,$colRights,"ContainerInherit, ObjectInherit",$PropagationFlag,$objType)
        $Acl.SetAccessRule($Ar)
        Set-Acl $DIRUSERNAME_DROP $Acl
           
        #setto permessi pubblica
        $Acl=$AclS
        $colRights = [System.Security.AccessControl.FileSystemRights]"ReadAndExecute, Traverse"
        $InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
        $PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
        $objType =[System.Security.AccessControl.AccessControlType]::Allow
        $Ar = New-Object  system.security.accesscontrol.filesystemaccessrule("Everyone",$colRights,$InheritanceFlag,$PropagationFlag,$objType)
        $Acl.SetAccessRule($Ar)
        Set-Acl $DIRUSERNAME_PUB $Acl
       
        $colRights = [System.Security.AccessControl.FileSystemRights]"Write"
        $InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
        $PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
        $objType =[System.Security.AccessControl.AccessControlType]::Allow
        $Ar = New-Object  system.security.accesscontrol.filesystemaccessrule($nome,$colRights,$InheritanceFlag,$PropagationFlag,$objType)
        $Acl.SetAccessRule($Ar)
        Set-Acl $DIRUSERNAME_PUB $Acl
       
        #setto permessi privata       
        $Acl=$AclS
        $colRights = [System.Security.AccessControl.FileSystemRights]"ReadAndExecute, Write"
        $InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
        $PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
        $objType =[System.Security.AccessControl.AccessControlType]::Allow
        $Ar = New-Object  system.security.accesscontrol.filesystemaccessrule($nome,$colRights,$InheritanceFlag,$PropagationFlag,$objType)
        $Acl.SetAccessRule($Ar)
        Set-Acl $DIRUSERNAME_PRIV $Acl
       
        $Acl=$AclS
        $colRights = [System.Security.AccessControl.FileSystemRights]"Read, Traverse"
        $InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
        $PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
        $objType =[System.Security.AccessControl.AccessControlType]::Allow
        $Ar = New-Object  system.security.accesscontrol.filesystemaccessrule("Everyone",$colRights,$InheritanceFlag,$PropagationFlag,$objType)
        $Acl.RemoveAccessRule($Ar)
        Set-Acl $DIRUSERNAME_PRIV $Acl

    martedì 6 dicembre 2011 14:24
  • e se sostituisci il "Fullcontrol" col solo "Write" ?
    Edoardo Benussi
    Microsoft MVP - Management Infrastructure
    edo[at]mvps[dot]org
    mercoledì 7 dicembre 2011 11:00
    Moderatore
  •  Edoardo e Fabrizio non riesco a capire perchè avete "proposto come risposta" il post sopra? A me sembra lo script completo, senza alcuna modifica risolutiva, infatti, la parte relativa al folder di drop è esattamente uguale al post che ha aperto questo tread.

    Marco, per il problema della share di drop bisognerebbe riuscire con lo script PS a dare i permessi interrompendo l'ereditarietà e applicare permessi speciali   a "Solo sottocartelle e file".

     In questi giorni provo a giocare con i permessi per vedere se si riesce fare questo "drop" e poi replicare il tutto in Powershell.

    Complimenti per l'idea che mi piace molto! Ti copio, la voglio far funzionare per tutti i miei utenti...  (sabato ri-posto su questo 3d con qualcosa)

    Ciao Gas

    Gastone Canali - http://www.armadillo.it

     


    giovedì 8 dicembre 2011 23:45
    Moderatore
  •  Edoardo e Fabrizio non riesco a capire perchè avete "proposto come risposta" il post sopra? A me sembra lo script completo, senza alcuna modifica risolutiva, infatti, la parte relativa al folder di drop è esattamente uguale al post che ha aperto questo tread.


    non hai interpretato bene quello che è accaduto, la marcatura di risposta io l'ho rimossa ed ho fatto una proposta all'op proprio perchè il codice riportato integralmente è esattamente uguale a quello riportato in estratto nel primo post.

    ciao.


    Edoardo Benussi
    Microsoft MVP - Management Infrastructure
    edo[at]mvps[dot]org
    venerdì 9 dicembre 2011 07:30
    Moderatore
  • Grazie a tutti per l'aiuto.

    Gastone Canali copia pure quello che vuoi... l'importante è che poi condividi con tutti le eventuali migliorie allo script :-D

    Oggi proverò a fare quanto suggerito.


     


    venerdì 9 dicembre 2011 08:35
  • Scusa Edoardo, ma non avevo guardato bene!

    Ciao Gas

    Gastone Canali - http://www.armadillo.it

     

    lunedì 12 dicembre 2011 14:15
    Moderatore
  • Ciao Marco,

    ho ragionato sul problema e come dicevo nel post precedente è solo un problema di utilizzare i permessi corretti per ottenere il risultato voluto.

    Solitamente per la gestione delle ACL negli script utilizzo varie applicazioni (cacls, icacls, subInACL, xcacls, setacl ...) ma visto che powershell può gestirle nativamente, ho pensato di  usare SDDL  "Security Descriptor Definition Language" per settare le Acl giuste sulle directories create.

    Lo script in allegato è equivalente al tuo, con il vantaggio di poter utilizzare SDDL per il settaggio delle ACL.

    ACL per DropFolder  "D:PAI(A;OICIIO;FA;;;CO)(A;OICI;0x100116;;;AU)(A;OICI;FA;;;SY)"

     

     

    <#
     
     By Gastone Canali
     http://www.armadillo.it
     
    #>
    # All user whose name starting with g
    $UserName="g*"
    # User profiles home
    $HomesPath = "k:\UserProfileHomes"
    # Folders created inside "home folder"
    $dirs=@("pubblic","private","drop")
    
    function change-sddl($dir,$user,$protosddl) {
       $tmpdir=$dir+"\"+[System.IO.Path]::GetRandomFileName()
       mkdir $tmpdir |Out-Null
       $acl = Get-Acl $tmpdir
       rmdir $tmpdir|Out-Null
       $sid=(ConvertTo-Sid  $User).value
       $newsddl = $protosddl+"(A;OICI;FA;;;$sid)"
       $acl.SetSecurityDescriptorSddlForm($newsddl)
       Set-Acl $dir  $acl
    }
    function ConvertTo-Sid ($NtAccount) {
        (new-object system.security.principal.NtAccount($NTaccount)).translate([system.security.principal.securityidentifier])
    }
    function IsAdministrator {   
        $identity  = [System.Security.Principal.WindowsIdentity]::GetCurrent()
        $principal = New-Object System.Security.Principal.WindowsPrincipal( $identity )
    	$principal.IsInRole( [System.Security.Principal.WindowsBuiltInRole]::Administrator )
    }
    # owner an NT Authority\System  full control, Authenticated Users only write permission 
    #  Authenticated Users can drop files inside but not read ...
    $drop_sddl    = "D:PAI(A;OICIIO;FA;;;CO)(A;OICI;0x100116;;;AU)(A;OICI;FA;;;SY)"
    # owner an NT Authority\System  full control
    #
    $private_sddl = "D:PAI(A;OICIIO;FA;;;CO)(A;OICI;FA;;;SY)"
    # owner an NT Authority\System  full control, Authenticated Users Readonly
    #
    $pubblic_sddl = "D:PAI(A;OICI;0x1200a9;;;AU)(A;OICI;FA;;;SY)"
    
    Clear-Host
    if (!(IsAdministrator)) {
    @"
     ========================================================================
     Errore: diritti insufficienti
     Riavviare lo script con un utente che abbia i diritti di amministrazione
     ========================================================================
    "@
    exit
    }
    
    $strFilter = "(&(objectCategory=User)(userPrincipalName=$UserName))"
    $objDomain = New-Object System.DirectoryServices.DirectoryEntry
    $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
    $objSearcher.SearchRoot = $objDomain
    $objSearcher.SearchScope = "Subtree" 
    $objSearcher.PageSize = 1000 
    $objSearcher.Filter = $strFilter
    $Results = $objSearcher.FindAll()
    foreach ($upn in $Results) {
            $u = [string] $upn.GetDirectoryEntry().UserPrincipalName
            echo "working on $u ..."
            $usr, $dom =  $u.Split("@")
    		#([string]$u).Split("@")[0]
            $HomeUsr=$homesPath+"\"+$usr
            if (-not (Test-Path   $HomeUsr)) { md $HomeUsr|Out-Null}
            $(foreach ($D in $dirs) { if (-not (Test-Path ("$HomeUsr\"+"$D"))) { md ("$HomeUsr\"+"$D")|Out-Null}})   
            change-sddl -dir "$homeUsr\$pri"  -protosddl "$private_sddl" -user "$u"
            change-sddl -dir "$homeUsr\$Dro"  -protosddl "$drop_sddl"    -user "$u"
            change-sddl -dir "$homeUsr\$Pub"  -protosddl "$pubblic_sddl" -user "$u"
        }
    

     

    Ciao Gas

    Gastone Canali - http://www.armadillo.it

     

     SDDL http://blogs.dirteam.com/blogs/jorge/archive/2008/03/26/parsing-sddl-strings.aspx

     

     


    lunedì 12 dicembre 2011 15:44
    Moderatore
  • Grazie per aver condiviso questo script.... vengo dal mondo linux...  mi scontro da poco con microsoft...

    SDDL  "Security Descriptor Definition Language" ??? Non so cosa sia.... ora me lo studio per bene.

    Grazie Gastone

    Ciao

    Marco

    • Contrassegnato come risposta Marco Curradi lunedì 12 dicembre 2011 16:10
    • Contrassegno come risposta annullato Marco Curradi lunedì 12 dicembre 2011 16:11
    lunedì 12 dicembre 2011 16:09
  • Grazie anche da parte mia ;-)

    ciao.


    Edoardo Benussi
    Microsoft MVP - Management Infrastructure
    edo[at]mvps[dot]org
    lunedì 12 dicembre 2011 16:17
    Moderatore
  • Come ti dicevo l'idea del DropFolder mi piace, ma la implementerei su una share dedicata, normalmente, la home (intesa come profilo di rete) non è utilizzata in una configurazione di base, ma può diventare parte integrante della tua infrasruttura informatica.

    Ti consiglio prima di iniziare a far modifiche sul profilo di dare un occhiata a

    "Folder redirection"  (che ti ricorderà l'automount delle home unix/linux )

    http://technet.microsoft.com/it-it/library/cc737434(WS.10).aspx

     

    Ciao Gas

    Gastone Canali - http://www.armadillo.it

     

     

     

     

    lunedì 12 dicembre 2011 18:10
    Moderatore