Gerência de Pastas Particulares com PowerShell

Uma demanda que sempre tive foi o controle mais efetivo de pastas particulares em ambientes com domínio Microsoft. Desde os idos tempos de Windows NT, os controles utilizados eram os mais diversos, e sempre manuais. No Windows NT, digamos, o caso era ainda pior, pois nem controle sobre a utilização de espaço por pasta – vide quota – existia de forma nativa.

Com o advento do Windows 2003, 2008 e agora 2012, a demanda me persegue mas digamos assim, com ferramentas mais adequadas para automatizar o processo e não depender de ferramentas de terceiros. O PowerShell já está disponível desde a versão 2008 do Windows Server e já ajuda em muito na automatização de processos, mas mesmo com o Windows 2012 a gerência de pastas particulares, pelo menos da forma que entendo ser mais adequada, não possui uma ferramenta que facilite todo o ciclo de vida da pasta particular relacionada ao usuário.

Criei então o pFolder, um script em PowerShell que automatiza a manutenção de pastas pessoais, incluindo a criação do compartilhamento, permissões e quotas. Adicionei também a funcionalidade de archiving das pastas após a exclusão dos usuários – mantendo as pastas/arquivos armazenados por um período determinado.

O script foi todo construído em PowerShell 3.0 utilizando um módulo nativo, um módulo externo mantido pela comunidade e um snappin para facilitar a consulta e alteração de objetos do Active Directory. 

Conteúdo

1 Operação

A inserção de novos usuários e/ou remoção destes, após o funcionamento do script agendado, se baseia apenas na manutenção de membros dos grupos de Quota do Diretório. Da mesma forma, a mudança de quota de um usuário, por exemplo, de 100MB para 500MB, implica apenas na mudança da associação de um grupo de quota para outro. Para execução e manutenção das pastas / grupos / quotas, primeiramente deve-se seguir os passos descritos abaixo:

1.1 Criação dos Grupos de Quota

A existência dos grupos de quota é pré-requisito para a execução do script. Estes grupos DEVEM ser criados seguindo o formato indicado e a localização no diretório, conforme o arquivo de configuração. Abaixo, um exemplo de grupos criados no diretório.

Grupos de Quota
Grupos de Quota

 

 

 

1.2 Criação dos Templates de Quota

Os templates de quota seguem o padrão da nomenclatura utilizada na criação dos grupos. Devem ser criados através do “FileServer Resource Manager”, na opção do menu “Quota Templates”. Abaixo um exemplo de templates criados seguindo o padrão utilizado na criação dos grupos.

Templates de Quota
Templates de Quota

1.3 Criação do Usuário de Serviço

O usuário de serviço deve ser criado como um usuário normal, sem inserí-lo em grupos especiais do domínio (ex: Domain Admins). Estas serão concedidas diretamente no servidor onde será executado o script. Abaixo, de forma detalhada, as permissões necessárias para plena execução do script.

1.3.1 Servidor

No servidor onde o script é executado, o usuário de serviço deve fazer parte do grupo de administradores locais. Na pasta raiz onde ficarão as pastas dos usuários, deve ser adicionado o usuário de serviço com permissão full control e também deve ser habilitada a herança.

1.3.2 Domínio

Deve ser delegada a permissão de ler/modificar os atributos de homeDirectory e homeDrive do usuário. Somente estas permissões devem ser delegadas, sendo assim o usuário de serviço não irá possuir mais acesso que o necessário.

Delegando Permissões
Delegando Permissões

1.4 Agendamento

O agendamento de execução do script deve ser realizado utilizando o Agendador de tarefas do Windows (Task Scheduler), seguindo as configurações como as imagens abaixo. Lembrando que o script powershell deve ser executado em modo elevado, por isso a necessidade do agendamento seguir exatamente as mesmas configurações. Aqui que definimos o usuário de serviço criado anteriormente como responsável pela execução da tarefa agendada.

Usuário de Serviço
Usuário de Serviço
Detalhes do Agendamento
Detalhes do Agendamento

 

 

 

 

 

2 Estrutura

O script possui uma pasta própria para armazenamento dos arquivos, bibliotecas, configuração e arquivos de log, residindo normalmente na raiz do servidor (Ex: c:\pFolder). O script pode ter como pasta base qualquer diretório no servidor, apenas atentando para modificar as configurações necessárias quando utilizar algum caminho diferente do padrão. Segue abaixo a descrição das pastas e correspondente descrição da função de cada arquivo:

pFolder               # Pasta Raiz
   pFolder.ps1        # Script Principal
   pFolder.xml	      # Arquivo de Configuração
   mailTemplate.htm   # Template HTML do Email de Report
   ignored.txt        # Usuários ignorados da pesquisa
   lib                # Bibliotecas externas
      config.ps1      # Funções de configuração
      logging.ps1     # Funções de log
      utils.ps1       # Funções de uso geral
      functions.ps1   # Biblioteca de funções
   log                # Repositório de log
   tmp                # Template de email temporário

2.1 Pastas de log

Os logs são gerados durante cada execução e salvos em arquivos no formato texto, dentro de uma estrutura de pastas divididas por ANO/MÊS/DIA. Os arquivos de log, por sua vez, possuem o formato de nome de arquivo baseado em pFolder_HORAMINUTOSEGUNDO.log. Abaixo, um exemplo da estrutura já criada após alguns dias de execução do script

log                         # Pasta Raiz de Logs / Vide Item 3
  2014                      # Ano 2014
    02                      # Mês 02
      28                    # Dia 28
        pFolder_232517.log  # Arquivo de log
    03                      # Mês 03
      01                    # Dia 01

3 ARCHIVING

Foi implementada nesta versão a retenção das pastas de usuário. Assim, quando um usuário é removido de um grupo de quota, sua pasta de dados não é excluída automaticamente mas sim movida para pasta de Archiving definida no arquivo de configuração (parâmetro archivingDir).

Ao final do processamento das pastas de usuário, uma função específica valida todas as pastas e seu período de retenção individual, de acordo com o valor definido no parâmetro retentionDays. Caso a data de arquivamento da pasta for maior que a data atual menos o parâmetro de retenção, a pasta é excluída de forma recursiva.

4 Report HTML

O relatório de operação é enviado por email e utiliza o formato HTML. Este relatório, diferentemente do log da operação em formato texto, só é enviado quando existe alguma modificação no status de uma pasta existente ou criação de uma nova estrutura.

A criação do relatório se baseia em um modelo em HTML que é copiado no início da execução de forma temporária e sendo modificado à medida em que o script é processado. Dessa forma, existe a possibilidade de customização do relatório apenas modificando o template. Abaixo, a lista de tags disponíveis para customização.

mailTemplate.htm

TAG

EXIBIÇÃO

{ERROR} Mensagem de erro, em qualquer função
{VERSION} Lista versão e nome da aplicação
{REMOVEDUPLICATED} Retorno da Busca e Remoção de usuários duplicados dos grupos de quota
{IGNOREDUSERS} Retorno da listagem de usuários ignorados (txt)
{GETOLDERLOGONS} Retorno da lista de usuários obsoletos
{GETVALIDUSERS} Retorno da lista de usuários válidos
{GETDIRLIST} Retorno da lista de Diretórios Existentes
{FILTERUSERS} Retorno da filtragem de usuários elegíveis
{DIRACTIONS} Retorno da listagem de diretórios e ações correspondentes
{FACTIONS} Lista de pastas, informações e ações executadas
{ARCHIVE} Resultado da validação de retenção nas pastas em arquivo

 

 

 

 

 

 

 

 

 

 

 

 

 

5 ARQUIVO DE CONFIGURAçÃO

O arquivo de configuração do pFolder é localizado na pasta raiz, juntamente com o script principal, em um arquivo no formato XML. O script e consequente arquivo de configuração foram construídos de forma que o mesmo possa ser transportado para outros ambientes/servidores modificando apenas os parâmetros necessários no arquivo de configuração.

GENERAL SETTINGS

PARÂMETRO VALORES DESCRIÇÃO
runMode RUN, TEST Especifica o modo de operação. No modo “TEST”, o script retorna em modo console uma tabela com os usuários/pastas elegíveis e ações relacionadas. No modo “RUN”, ele executa as funções em modo normal.
fileServer HOSTNAME Nome do Servidor onde está sendo executado o script
errorMode STOP, CONTINUE Modo de tratamento de erros do PowerShell. Não modificar
Modules Módulos carregados pelo script. Não modificar
Snapin Snappin carregado pelo script. Não modificar
homeFolder C:\pFolder Caminho para pasta Raiz do Script
homeDrive U: Unidade para mapeamento da unidade pelo Usuário
baseDir E: Caminho para pasta Raiz das Pastas de Usuário
archivingDir _ARCHIVING Nome da pasta onde serão armazenadas as pastas até o período definido pelo parâmetro retentionDays
retentionDays 90 Período de retenção para as pastas, após este período as mesmas são excluídas automaticamente

DIRECTORY SETTINGS

PARÂMETRO VALORES DESCRIÇÃO
domain DOMÍNIO Domínio netbios
baseOU contoso.local/Structure Caminho do AD para pesquisa dos Usuários elegíveis
groupBaseName GG_FSQUOTA_SERVERNAME_ Base do nome dos grupos de Quota. Será utilizado para construir a pesquisa dos grupos bem como inserção nas políticas de quota.
groupBaseOU contoso.local/Service/Groups Caminho do AD para pesquisa pelos grupos de quota

LIMIT SETTINGS

PARÂMETRO VALORES DESCRIÇÃO
dirOwner GNET\Domain Admins Proprietário com permissão de Full Control das pastas de usuários. O mesmo será adicionado à ACL após o script tomar a propriedade da pasta.
lastLogonDays 90 A pesquisa por usuários elegíveis leva em consideração o registro referente aos dias sem efetuar logon no domínio. Caso seja maior que o número informado neste parâmetro, o usuário é filtrado e mesmo fazendo parte dos grupos de quota, não é incluído na lista de elegíveis.
ignoredUsersPre scv, adm Hash com lista de iniciais a serem descartadas no filtro de usuários elegíveis. No caso, usuários que iniciam por “svc” ou “adm” ( ex: usuários de serviço e administrativos )  são excluídos da lista de usuários elegíveis.
ignoredUsersFile Ignored.txt Arquivo contendo lista de usuários a serem excluídos do filtro de elegíveis, mesmo pertencentes aos grupos de quota.

LOG SETTINGS

PARÂMETRO VALORES DESCRIÇÃO
evSource pFolder Fonte do EventViewer – criada automaticamente pelo sistema casa não exista – para inclusão de eventos. Apenas eventos de execução e erro são registrados no EventViewer local.
logPath log Nome da pasta base para criação e escrita dos arquivos de log
logFileName pFolder Utilizado para criação dos arquivos de log, sendo adicionado o formato _HORAMINUTOSEGUNDO.log ao nome do arquivo.

EMAIL SETTINGS

PARÂMETRO VALORES DESCRIÇÃO
server correio.contoso.local Nome do servidor de Email para envio dos logs.
user svc_pfolder Usuário para envio / autenticação
password Senha do usuário para envio / autenticação
from svc_pfolder@contoso.local Endereço de email do remetente
to Endereço de destino
subject pFolder – LOG Título do email que será enviado com o arquivo de log
mailTemplate mailTemplate.htm Template HTML para o email de Report

6 CMDLETS / FUNÇÕES

O pFolder utiliza-se tanto de cmdlets e funções nativas como objetos externos para criar as funções e sumarizar os dados em uma tabela, contendo como resultado a pasta/usuário, quota e ação a ser executada. Abaixo, uma breve descrição das funções internas:

functions.ps1

FUNÇÃO VERSÃO DESCRIÇÃO
ignoredUsers 1.0 Carrega arquivo de texto – $ignoredUsersFile – com lista de usuários e retorna um array com o conteúdo
getOlderLogons 1.1 Pesquisa no AD – $baseOU – por usuários com último registro de logon no domínio maior que $lastLogonDays e retorna um array com o atributo samAccountName
getValidUsers 1.0 Pesquisa no AD – $baseOU – por usuários válidos (enabled=TRUE) e que pertençam a um grupo específico ( $gBaseName ), retornando um array de hashes com o atributo samAccountName e groupName
getDirList 1.0 Retorna lista de diretórios existentes na base ( $baseDir ) de pastas de usuários.
filterUsers 1.0 Filtra lista de usuários de arrays correspondentes, recebendo como entrada o resultado de ignoredUsers, getOlderLogons, getValidUsers e o parâmetro ignoredUsersPre. Retorna array de hashes com usuários elegíveis, categorizados por pasta e quota correspondente.
dirActions 1.0 Adiciona, baseado no resultado do filtro de usuários elegíveis e pastas existentes, uma coluna a cada registro com a ação correspondente.

CREATE – Usuário está em um grupo de quota mas não possui nenhuma pasta correspondente.

CHANGE-QUOTA – Usuário está em um grupo de quota diferente do anterior ao qual foi aplicada a quota.

NONE – Nenhuma ação pois não houve alteração referente a pasta, usuário ou grupo de quota.

DUPLICATE – O usuário está em mais de um grupo de quota, sendo assim nenhuma ação é executada

REMOVE – Usuário possui uma pasta correspondente mas não está presente em nenhum dos grupos de quota

qAction 1.0 Funções relacionadas a criação, remoção e manutenção da quota. Retorna TRUE ou FALSE após a execução, que pode ser:

GET – Valida a quota aplicada ao compartilhamento e retorna resultado

CHANGE – Modifica quota para outro template

CREATE – Define quota no compartilhamento para o template

fActions 1.0 Funções relacionadas às pastas, chamando funções externas ou executando a ação necessária.

CREATE-QUOTA – Define a quota, chamando a função qAction com o parâmetro CREATE

CHANGE-QUOTA – Modifica a quota, chamando a função qAction com o parâmetro CHANGE

CREATE-FOLDER – Cria a pasta dentro da base de usuários

REMOVE-FOLDER – Remove a pasta do usuário de forma recursiva

REMOVE-SHARE – Remove o compartilhamento da pasta via chamada WMI

CREATE-SHARE – Cria o compartilhamento ( $folderName + $ ) e define ACL’s de acesso ao mesmo com os parâmetros $dirOwner e $folderName (usuário) como proprietários.

CREATE-ACL – Com funções externas, define o proprietário da pasta para $dirOwner e modifica as ACL’s para:

$dirOwner : FULL CONTROL

$folderName (usuário): MODIFY

$runas (svc_pfolder): FULL CONTROL

SET-HOMEDIRECTORY – Define o parâmetro homeDirectory e homeDrive do usuário no AD para $homeDrive e caminho do compartilhamento

REMOVE-HOMEDIRECTORY – Remove homeDirectory e homeDrive do usuário no AD e define para localpath.

removeDuplicatedUsers 1.0 Realiza uma busca em todos grupos de quota, criando um array com o nome do grupo e quota relacionada. À partir do array, efetua-se um comparativo entre os membros de cada grupo em busca de usuários duplicados – presentes em mais de um grupo -, caracterizando-de como resultado “DUPLICATE” em dirActions. Caso encontre resultados em mais de um grupo, remove o membro do grupo com a quota menor.

 

config.ps1

FUNÇÃO VERSÃO DESCRIÇÃO
readConfig 1.0 Carrega o arquivo XML e cria um array a partir destes dados, retornando-os para uma variável global “appSettings”.

 

logging.ps1

FUNÇÃO VERSÃO DESCRIÇÃO
Log-Start 1.1 Cria arquivo de log utilizando o parâmetro $logPath + $logFileName + HORAMINUTOSEGUNDO.log
Log-Write 1.1 Adiciona linha ao arquivo de log com parâmetros $logPath e texto a ser inserido
Log-Error 1.1 Adiciona linha ao arquivo de log, informando erro retornado pelo parâmetro $1 do powershell e $logPath
Log-Finish 1.2 Adiciona informações finais ao arquivo de log e finaliza arquivo
Log-Email 1.0 Envia por email o conteúdo do log, recebendo como parâmetro as informações do arquivo de configuração. ( $server, $user, $password, $from, $to e $subject )

 

utils.ps1

FUNÇÃO VERSÃO DESCRIÇÃO
errorPostProcess 1.1 Realiza o tratamento do erro enviado por outras funções, com saída para console em modos RUN e TEST, EventViewer e Log
eventLog 1.0 Escreve uma mensagem no EventViewer local com o $source criado anteriormente.
convertTemplateToMB 1.1 Recebe o nome do grupo de quota e retorna somente o valor de quota correspondente
getModule 1.0 Valida se módulo está carregado e caso não esteja, carrega o mesmo e retorna TRUE ou FALSE.
cArray 1.0 Compara valores dentro de dois arrays com hashes, caso encontre o valor retorna TRUE
convertDateString 1.0 Converte uma string em um objeto Powershell DateTime
replaceFileString Efetua a troca de strings dentro de arquivos utilizando expressões regulares
getHtmlMessage 1.0 Return result with html formatted to replace in htmlTemplate

7 SEQUENCIA DE EXECUÇÃO

PASSO FUNÇÃO RELACIONADA DESCRIÇÃO
1 Importa Bibliotecas externas
2 Cria base de registro do EventViewer, caso não exista
3 Cria estrutura de diretórios do Log, caso não exista
4 Define modo de tratamento de erros
5 getModule Carrega módulos
6 removeDuplicatedUsers Busca e remove usuários duplicados dos grupos de quota
7 ignoredUsers Cria lista com arquivo de usuários ignorados
8 getOlderLogons Cria lista com lista de usuários inativos
9 getValidUsers Cria lista de usuários válidos
10 getDirList Cria lista de diretórios existentes
11 filterUsers Cria lista filtrada de usuários
12 dirActions Cria lista de diretórios, quotas e ações relacionadas
13 fActions Executa cada ação definida na lista de pastas
14 archiving Valida, de acordo com a retenção, a exclusão de pastas antigas
15 eventLog / Log-Email Finaliza arquivo de log e encaminha o mesmo por email

8 Erros Conhecidos

8.1 Erro Modificando Atributos

Um erro verificado durante os testes de execução foi a dificuldade reportada ao modificar o atributo homeDirectory e homeDrive do usuário.

“Error: An error has occurred [Access is denied.].”

Este erro se deve ao fato do usuário não estar com a herança definida, sendo assim, não recebeu a acl do usuário de serviço quando esta foi delegada. Para solucionar este problema, validar o usuário que o log reportou o problema e definir a herança no objeto do usuário no AD, dentro da aba “Security => Advanced”, conforme imagem abaixo.

Herança de Atributos
Herança de Atributos

REFERÊNCIAS

PowerShell Code Repository http://poshcode.org

PowerGui http://www.powergui.org/

The Windows PowerShell Toolbox http://technet.microsoft.com/en-us/scriptcenter/ee861518.aspx

Microsoft Technet http://technet.microsoft.com/

Peter Morrissey’s http://petermorrissey.blogspot.com.br/

Explore PowerShell http://explorepowershell.com/

Technically Speaking http://chrisfederico.wordpress.com

WeepingApps http://weepingapps.wordpress.com/

Stackoverflow http://stackoverflow.com/

IanNotes http://iannotes.wordpress.com/

Spiceworks http://spiceworks.com/

Powershell and Beyond http://dmitrysotnikov.wordpress.com/

SS64 http://ss64.com/

Código Fonte