martedì 27 agosto 2019

Trovare files e cartelle che hanno uno specifico permesso ACL NTFS (o non hanno)

Buongiorno a tutti e benvenuti ad un altro post.

In questo articolo vi voglio spiegare com'è possibile, da un elenco di cartelle e o di file, recuperare quelli che hanno oppure non hanno uno specifico permesso per uno specifico utente.

In sostanza, oggi mi sono trovato a dover testare alcune cartelle, per una anomalia sulle ACLs, tuttavia non sapevo QUALI avevano impostato il mio utente nelle ACLs direttamente e quali invece avevano il gruppo.

Ecco come ho fatto:

  • Ho "fatto DIR" con powershell (Get-ChildItem) e ho quindi ciclato su tutte le cartelle, ottenendo le loro ACLs.
  • Per ogni cartella ho semplicemente verificato che il mio nome utente non fosse presente nelle ACLs, testando la proprietà AccessToString (con un ulteriore LOOP sulla proprietà Access, che è una collection di oggetti*, invece, avrei potuto controllare puntualmente anche il tipo di permesso etc...)
  • Quindi, se il permesso non c'era, ho stampato a schermo il nome della cartella.

* collection di oggetti AuthorizationRuleCollection




Bando alle ciance: ecco lo script:


$FolderPath = Get-ChildItem -Directory -Path "E:\Personali"
$FolderPath|foreach{
    $acls=Get-Acl $_.FullName
    if($acls.AccessToString -notlike "*DOMINIO\nomeutente*"){
        write-host ("la cartella "+$_.FullName+" non ha nomeutente nelle ACLs")
    }
}

come vedete in questo caso ho filtrato SOLO le Directory (con il parametro -Directory)





La versione + "approfondita"

Con quest'altra versione, è possibile verificare per tutti i files e le cartelle, anche il TIPO di permesso ed altre cose. Più precisamente, riporto un esempio di una proprietà Access.

FileSystemRights  : FullControl
AccessControlType : Allow
IdentityReference : BUILTIN\Administrators
IsInherited       : True
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : InheritOnly

e ecco lo script:


$FolderPath = Get-ChildItem -Directory -Path "E:\Personali"
$FolderPath|foreach{
    $acls=Get-Acl $_.FullName
    $printThis=$true
    foreach($e in $acls.Access){
    if($e.AccessControlType -eq "Allow" -and $e.IdentityReference -eq "DASITALIA\DiegoCA"){
            $printThis=$false;
    }
    }
    if($printThis){
        write-host ("la cartella "+$_.FullName+" non ha DiegoCA nelle ACLs")
    }
}

Ricorsione (Recursive, Recurse)
Se volete usare questi script in tutte le sottocartelle / sottodirectory, dovrete semplicemente abilitare la ricorsione sul primo comando!

$FolderPath = Get-ChildItem -Directory -Path "E:\Personali" -Recurse

Et-Voilà!


Spero di avervi stuzzicato la fantasia, anche oggi.

Happy Scripting a tutti!

martedì 16 luglio 2019

Uno script per esportare l'ultimo mese della cassetta postale in archivio .PST, con Powershell - direttamente dal server Exchange con Management Shell


Buongiorno a tutti e  benvenuti ad un altro articolo del mio blog.
Oggi, riagganciandomi all’articolo precedente di Giugno, sul metodo di esportare una cassetta postale dal server con new-mailboxexportrequest, voglio fornirvi uno script bello e pronto per schedulare l’archiviazione del mese precedente alla data di esecuzione.
Ovviamente, poi, potete modificarlo per ampliare o restringere il periodo, accettare le date di inizio e di fine dai parametri…. …e chi più ne ha, più ne metta.

Bando alle ciance, dunque: ecco lo script, prontissimo per essere messo in un ps1 e lanciato a piacimento, serialmente...



Param(
    [parameter(Mandatory=$true, HelpMessage="indirizzo principale della mailbox da archiviare")]
    [string]$address,
    [parameter(Mandatory=$true, HelpMessage="indica il percorso DI RETE dove salvare il PST (verrà appesa una sottocartella con l'anno)")]
    [string]$baseP
)
import-module activeDirectory
if ( (Get-PSSnapin -Name Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction SilentlyContinue) -eq $null ){
    add-pssnapin Microsoft.Exchange.Management.PowerShell.E2010
}

# check di esistenza mailbox
if (-not ($mb=Get-mailbox $address -ErrorAction silentlycontinue)) {
write-host "la casella specificata non esiste"
exit
}

$a=get-date
# ottengo il primo giorno del mese precedente
$b=get-date(""+($a.AddMonths(-1)).Month+"/"+$a.Year)
$nomeMese=$b.Month | %{(Get-Culture).DateTimeFormat.GetMonthName($_)}
# ottengo il primo giorno del mese corrente
$c=get-date(""+$a.Month+"/"+$a.Year)

if (-not(test-path -PathType Container ($baseP+"\"+$b.Year))){
    New-Item -ItemType Directory -Force -Path ($baseP+"\"+$b.Year)
}
$path = $baseP+"\"+$b.Year+"\"+($mb.Name+"_"+$nomeMese+"-"+$b.Year)+".pst"

new-mailboxExportRequest $mb -FilePath $path -ContentFilter {(received -gt $b) -and (received -lt $c)} -Name ($mb.Name+"--"+$nomeMese+$b.Year)


martedì 9 luglio 2019

Exchange Powershell (EMS) - aggiungere più utenti ad un gruppo di distribuzione con una riga sola di comando.

Buongiorno a tutti,
 oggi dovevo aggiungere più utenti e rimuoverne altri da un distribution group di Exchange.
Come sapete cerco di fare tutto dalla shell powershell di management (Exchange Management Shell), ma stavolta è stato "tricky".

Ho trovato una soluzione elegante e quindi scrivo questo mini-post....

Pronti? via.

Per aggiungere più membri contemporaneamente ad un gruppo di distribuzione con PowerShell

"utente1", "utente2", "utente3" | Add-DistributionGroupMember nomeDG@dominio.it -BypassSecurityGroupManagerCheck

con questo trick one-liner (come si dice "nel gergo di noi scriptomani") possiamo evitare la sintassi con il ciclo foreach, le graffe etc...
Elegante, no?




Per rimuovere più membri contemporaneamente da un gruppo di distribuzione con PowerShell

"utente1", "utente2", "utente3" | Remove-DistributionGroupMember nomeDG@dominio.it -BypassSecurityGroupManagerCheck

... in sostanza la stessa cosa.


Beh, che dire: vi ho promesso un articolo "mini", no?
Spero di aver facilitato la vita a qualche sysadmin e stuzzicato la vostra fantasia.

Happy Scripting a tutti!

martedì 25 giugno 2019

Esportare una cassetta postale in PST (archiviare) con POWERSHELL, direttamente dal server Exchange con Powershell EMS


EDIT: Se volete uno script pronto per archiviare una cassetta postale, che accetta parametri etc...
... sto lavorando a un nuovo POST.
Iscrivetevi come follower al BLOG (o con il vostro lettore di notizie RSS): verrete avvisati quando pubblicherò l'articolo! :-)

A volte ci si trova nella necessità di creare delle esportazioni di cassetta postale in file che possano essere esaminati o aperti in momenti successivi.
É il caso, ad esempio, di quando si hanno lavoratori remoti (smart-working o personale con funsioni principalmente esterne) e una connessione “limitata”.
Il problema che si pone in quel caso è che archiviare un PST su un file server (perché possa essere sottoposto a backup e non sia a rischio di rottura del disco fisso del PC) risulta un’operazione che satura tutta la larghezza di banda… Questo perché il client deve tenere aperto il file e, non so perché in dettaglio, manda dati avanti e indietro come un pazzo…
La soluzione quick & dirty sarebbe di creare il file PST in locale e poi spostarlo sul server… tuttavia anche questa ha parecchie limitazioni, così ovvie che non le scrivo qui.

Quindi, cosa fare per essere sicuri di archiviare automaticamente le mail in una cassetta postale con powershell (Exchange Management Console) in Microsoft Exchange Server 2010 SP3 (ma anche nelle versioni successive)?

Ecco i comandi che ci possono essere utili:
  • New-MailboxExportRequest (iniziare la richiesta di esportazione)
  • Get-MailboxExportRequest (ottenere le richieste di esportazione in corso, e anche terminate)
  • Get-MailboxExportRequestStatistics (ottenere le satistiche circa l’avanzamento della richiesta)
  • Remove-MailboxExportRequest (rimuove la request dalla coda, utile soprattutto per far pulizia).



Premesse

Caricare la snap-in di exchange (ovvio)

Tutti questi comandi vanno lanciati da una powershell con la snap-in di Microsoft Exchange, quindi, se avete una powershell normale, lanciate:
if ( (Get-PSSnapin -Name Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction SilentlyContinue) -eq $null ){
    add-pssnapin Microsoft.Exchange.Management.PowerShell.E2010
}

E avrete la snap-in amministrativa caricata.

Non si può salvare in un percorso LOCALE del server

 deve essere una share di rete (anche se potete usare tranquillamente \\NOMESERVER\C$)
(o almeno IO non posso, dato che ho un DAG – un cluster di exchange – ma suppongo sia così per tutti).

Accesso share di destinazione

La share di rete deve permettere l’accesso in scrittura agli account COMPUTER dei server Exchange nella vostra organizzazione.
Quindi, autorizzate, altrimenti riceverete un bel “Access Denied”


FINE DELLE PREMESSE




Esportazione di tutta la cassetta postale

Ve la faccio breve: ecco come fare se si vuole esportare TUTTO il contenuto della cassetta postale.

New-MailboxExportRequest cassetta.postale@dominio.it -FilePath "\\server\share\...\archivioCassettaPostale.pst"

E tutto verrà salvato.


Le opzioni di New-MailboxExportRequest

Ecco qui le opzioni da get-help del comando.
New-MailboxExportRequest
   [-Mailbox]
   -FilePath
   [-AcceptLargeDataLoss]
   [-AssociatedMessagesCopyOption ]
   [-BadItemLimit ]
   [-BatchName ]
   [-CompletedRequestAgeLimit ]
   [-Confirm]
   [-ConflictResolutionOption ]
   [-ContentFilter ]
   [-ContentFilterLanguage ]
   [-DomainController ]
   [-ExcludeDumpster]
   [-ExcludeFolders ]
   [-IncludeFolders ]
   [-InternalFlags ]
   [-IsArchive]
   [-LargeItemLimit ]
   [-MRSServer ]
   [-Name ]
   [-Priority ]
   [-RemoteCredential ]
   [-RemoteHostName ]
   [-SkipMerging ]
   [-SourceRootFolder ]
   [-Suspend]
   [-SuspendComment ]
   [-TargetRootFolder ]
   [-WhatIf]
   [-WorkloadType ]
   []

Focalizziamoci per ora solo su:
-BadItemLimit
-ContentFilter
-ContentFilterLanguage

BadItemLimit: consentire l’errore su N items e proseguire

Con questa opzione possiamo specificare quanti errori “tollerare” prima che il job fallisca. In base alle necessità si può variare il numero, tuttavia ho riscontrato che i job lanciati con il default falliscono un po’ troppo spesso. Quindi, se vogliamo tollerare un po’ di perdita, per consentirci di lanciare il comando unattended, sarà bene aumentare un po’…

ContentFilter: un filtro per selezionare i messaggi da esportare

… e qui abbiamo a disposizione un intero arsenale di opzioni, pari quasi alle proprietà dei singoli messaggi….
Prendiamo ad esempio questo filtro
{(body -like "*company*") -and (body -like "*profit*") -and (Received -lt "01/01/2018")}
Ci consente di esportare solo i messaggi che contengono le parole company e profit nel corpo del messaggio e che sono ricevuti prima del primo Gennaio 2018.

ContentFilterLanguage : possiamo specificare la localizzazione (culture) del filtro

A che mi serve, direte voi?
Perché se usate filtri con il nome delle cartelle o con il nome di determinati altri parametri che sono soggetti a localizzazione (quindi hanno un nome diverso se la cassetta postale è impostata per la localizzazione in Italiano, rispetto che in inglese, ad esempio), dovrete specificare il che “culture” è il filtro che usate…

se avete bisogno di altre opzioni ecco il link ufficiale (non cambia da Exchange 2010 al 2019):

Esportazione di una cassetta postale con Filtro.

Ecco un classico filtro che potete applicare per un job di archiviazione ricorsivo. Usiamo le date con le operazioni, per identificare un intervallo ed esportare solo le mail inviate o ricevute entro quell’intervallo.
$a = get-date

New-MailboxExportRequest cassetta.postale@dominio.it -FilePath "\\server\share\...\archivioCassettaPostale.pst" -ContentFilter {(received -lt (get-date).AddDays(-60).AddHours(-1*$a.Hour).AddMinutes(-1*$a.Minute)) -and (received -gt (get-date).AddDays(-90).AddHours(-1*$a.Hour).AddMinutes(-1*$a.Minute) )}

Come vedete, memorizzo prima la data attuale in $a, quindi vado a togliere le ore e i minuti dalla data, per riportarla a mezzanotte del giorno selezionato.
Qui selezioniamo tutti i messaggi inviati o ricevuti tra i 60 e i 90 giorni prima dalla data attuale, con
received -lt (less than) e received -gt (greater than)



Alcuni Trucchetti

ottenere il primo ed ultimo giorno del mese corrente (o di una data in mezzo al mese), con Powershell

Primo giorno del mese in powershell

$a.AddDays(-1*($a.Day-1))
#se invece il mese è definito (SO già che è MARZO):
get-date("03/2019")

Ultimo giorno del mese in powershell

(Get-date(($a.Month+1).ToString()+/+$a.Year.ToString())).AddDays(-1)


Questi esempi assumono $a = una data ottenuta con get-date

Fare Pulizia delle mailboxExportRequest

Come vedete nello screenshot più in basso, le richieste, anche quando vengono completate, rimangono in “storico”. Questo per consentire a chi dovesse lanciarne molte di visualizzarne i risultati.
Ecco quindi come fare pulizia, una volta che sono tutte terminate, in un modo o nell’altro:
get-MailboxExportRequest | Remove-MailboxExportRequest


ed ecco il risultato




Bene, spero di aver stuzzicato anche oggi la vostra voglia di scriptare... vi mando il solito augurio:

HAPPY SCRIPTING A TUTTI!