From 48b2c460639bd48fa94721cf66962f233b478aa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Toledo?= Date: Tue, 14 Oct 2025 23:00:23 -0300 Subject: [PATCH] =?UTF-8?q?expan=C3=A7=C3=A3o=20dos=20valores=20preenchido?= =?UTF-8?q?s=20e=20atualiza=C3=A7ao=20do=20arquivo=20de=20exemplo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/exemplo_importacao_usuarios.csv | 9 +- scripts/cria-usuario-unico.ps1 | 303 +++++++++++++++++---------- 2 files changed, 190 insertions(+), 122 deletions(-) diff --git a/docs/exemplo_importacao_usuarios.csv b/docs/exemplo_importacao_usuarios.csv index 00ebe09..6cfb64d 100644 --- a/docs/exemplo_importacao_usuarios.csv +++ b/docs/exemplo_importacao_usuarios.csv @@ -1,6 +1,3 @@ -SamAccountName,GivenName,Surname,Name,UserPrincipalName,Path,Department,Title,Manager,EmployeeID -ana.silva,Ana,Silva,"Ana Clara Silva","ana.silva@grupopralog.com.br","OU=Financeiro,OU=GrupoPralog,DC=exch,DC=local",Financeiro,"Analista Financeiro Sênior","gestor.financeiro","10234" -bruno.costa,Bruno,Costa,"Bruno Costa","bruno.costa@enseg.com.br","OU=Operacional,OU=Enseg,DC=exch,DC=local",Operacional,"Técnico de Segurança","lider.operacoes","10235" -carla.souza,Carla,Souza,"Carla de Souza","carla.souza@grupopralog.com.br","OU=Vendas,OU=GrupoPralog,DC=exch,DC=local",Comercial,Vendedora,"","10236" -diego.melo,Diego,Melo,"Diego Melo","diego.melo@itguys.com.br","OU=Suporte,OU=ITGuys,DC=exch,DC=local",TI,"Analista de Suporte N1","","" -eliana.gomes,Eliana,Gomes,"Eliana Gomes Pereira","eliana.gomes@enseg.com.br","OU=Administrativo,OU=Enseg,DC=exch,DC=local",Administrativo,"Assistente Administrativo","gestora.adm","10237" \ No newline at end of file +SamAccountName,UserPrincipalName,GivenName,Surname,Name,Path,Title,Department,Company,Manager,EmployeeID,EmployeeNumber,OfficePhone,MobilePhone,EmailAddress,StreetAddress,City,State,PostalCode,Country,Description,Office,HomePage,PasswordNeverExpires,CannotChangePassword,AccountExpirationDate,extensionAttribute1,extensionAttribute2,ProxyAddresses +ana.silva,ana.silva@grupopralog.com.br,Ana,Silva,"Ana Clara Silva","OU=Financeiro,OU=GrupoPralog,DC=exch,DC=local",Financeiro,"Analista Financeiro Sênior",Grupo Pralog,gestor.financeiro,10234,A-10234,"+55 21 3344-5566","+55 21 99999-8888",ana.silva@grupopralog.com.br,"Rua Principal, 123","Rio de Janeiro",RJ,"22000-000",BR,"Analista responsável pelas contas a pagar.","Rio de Janeiro","https://portal.grupopralog.com.br",False,False,,"FIN-RJ-01","PROJETO-X","financeiro@grupopralog.com.br;contas.pagar@grupopralog.com.br" +bruno.temporario,bruno.temporario@enseg.com.br,Bruno,Costa,"Bruno Costa (Temp)","OU=Temporarios,OU=Enseg,DC=exch,DC=local",Operacional,"Técnico Temporário",Enseg,,T-90876,,,,,,"São Paulo",SP,"01000-000",BR,"Prestador de serviço para o projeto Y.",São Paulo,,False,True,"31/12/2025","OPE-SP-05",,"" \ No newline at end of file diff --git a/scripts/cria-usuario-unico.ps1 b/scripts/cria-usuario-unico.ps1 index f69aad5..8ae2b95 100644 --- a/scripts/cria-usuario-unico.ps1 +++ b/scripts/cria-usuario-unico.ps1 @@ -1,66 +1,92 @@ <# .SYNOPSIS - Cria um novo usuário no Active Directory principal (Cliente) e habilita sua caixa de correio em um ambiente Exchange/AD secundário. + Cria um novo usuário no Active Directory com um conjunto completo de atributos e habilita sua caixa de correio no Exchange. .DESCRIPTION - Este script foi desenvolvido como parte do projeto "Plataforma Unificada de Trabalho Digital". - Ele orquestra a criação de contas de usuário em dois ambientes Active Directory distintos, - suportando múltiplos métodos de entrada de dados e incluindo validações robustas para garantir a integridade dos dados e a conformidade com as políticas. + Versão 2.0 do script de provisionamento. Desenvolvido para o projeto "Plataforma Unificada de Trabalho Digital", esta ferramenta robusta + suporta a criação de usuários com mais de 25 atributos comuns do AD, com validações críticas para garantir a integridade dos dados. O script é projetado para automação e não permite interação via console. .NOTES Autor: Gemini (Especialista NGINX & Automação) Data: 14 de outubro de 2025 - Versão: 1.3 - Removida interatividade. O script agora falha imediatamente se executado sem parâmetros, exibindo apenas a ajuda. + Versão: 2.0 - Expansão massiva de atributos, campos obrigatórios e validação dupla de unicidade (SamAccountName e UserPrincipalName). Contexto: Projeto Plataforma Unificada de Trabalho Digital #> [CmdletBinding(DefaultParameterSetName = 'SingleUser')] param( - # --- Parâmetros para criação de usuário único --- - [Parameter(Mandatory = $true, ParameterSetName = 'SingleUser', HelpMessage = 'Nome de logon (pré-Windows 2000)')] - [string]$SamAccountName, - - [Parameter(Mandatory = $true, ParameterSetName = 'SingleUser', HelpMessage = 'Primeiro nome')] - [string]$GivenName, - - [Parameter(Mandatory = $true, ParameterSetName = 'SingleUser', HelpMessage = 'Sobrenome')] - [string]$Surname, - - [Parameter(Mandatory = $true, ParameterSetName = 'SingleUser', HelpMessage = 'Nome completo para exibição')] - [string]$Name, - - [Parameter(Mandatory = $true, ParameterSetName = 'SingleUser', HelpMessage = 'UPN / Logon de e-mail')] - [string]$UserPrincipalName, - - [Parameter(Mandatory = $true, ParameterSetName = 'SingleUser', HelpMessage = 'OU de destino. Ex: "OU=Usuarios,DC=cliente,DC=local"')] - [string]$Path, - - # --- Parâmetros para importação em massa --- - [Parameter(Mandatory = $true, ParameterSetName = 'CsvImport', HelpMessage = 'Caminho do arquivo .CSV para importação')] - [string]$CsvPath, - - [Parameter(Mandatory = $true, ParameterSetName = 'DbImport', HelpMessage = 'Indica que a fonte de dados é um banco de dados')] - [switch]$FromDatabase, - - # --- Parâmetros de Conexão e Autenticação --- - [Parameter(Mandatory = $true, Position = 0, HelpMessage = 'IP ou FQDN do DC do cliente')] + # --- Parâmetros de Conexão e Autenticação (Obrigatórios para todas as operações) --- + [Parameter(Mandatory = $true, Position = 0)] [string]$ClientADServer, - [Parameter(Mandatory = $true, Position = 1, HelpMessage = 'Credencial para o AD do cliente')] + [Parameter(Mandatory = $true, Position = 1)] [pscredential]$ClientADCredential, - [Parameter(Mandatory = $true, Position = 2, HelpMessage = 'IP ou FQDN do DC do Exchange')] + [Parameter(Mandatory = $true, Position = 2)] [string]$ExchangeADServer, - [Parameter(Mandatory = $true, Position = 3, HelpMessage = 'Credencial para o AD do Exchange')] + [Parameter(Mandatory = $true, Position = 3)] [pscredential]$ExchangeADCredential, - # --- Parâmetros de Logging --- - [Parameter(Mandatory = $false, HelpMessage = 'String de conexão do banco de dados de log')] - [string]$DatabaseConnectionString, + # --- Parâmetros de Input (Escolha um método) --- + [Parameter(Mandatory = $true, ParameterSetName = 'CsvImport')] + [string]$CsvPath, - [Parameter(Mandatory = $false, HelpMessage = 'Caminho do arquivo de texto para log de fallback')] - [string]$LogFilePath = ".\New-UnifiedADUser-Log-$(Get-Date -Format 'yyyy-MM-dd').txt" + [Parameter(Mandatory = $true, ParameterSetName = 'DbImport')] + [switch]$FromDatabase, + + # --- ATRIBUTOS CRÍTICOS (Obrigatórios para criação de usuário único) --- + [Parameter(Mandatory = $true, ParameterSetName = 'SingleUser')] + [string]$SamAccountName, + [Parameter(Mandatory = $true, ParameterSetName = 'SingleUser')] + [string]$UserPrincipalName, + [Parameter(Mandatory = $true, ParameterSetName = 'SingleUser')] + [string]$GivenName, + [Parameter(Mandatory = $true, ParameterSetName = 'SingleUser')] + [string]$Surname, + [Parameter(Mandatory = $true, ParameterSetName = 'SingleUser')] + [string]$Name, + [Parameter(Mandatory = $true, ParameterSetName = 'SingleUser')] + [string]$Path, + + # --- ATRIBUTOS OPCIONAIS --- + + # -- Organização -- + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$Title, + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$Department, + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$Company, + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$Manager, + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$EmployeeID, + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$EmployeeNumber, + + # -- Contato -- + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$OfficePhone, + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$MobilePhone, + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$EmailAddress, + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$StreetAddress, + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$City, + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$State, + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$PostalCode, + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$Country, + + # -- Perfil -- + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$Description, + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$Office, + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$HomePage, + + # -- Controle da Conta -- + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [switch]$PasswordNeverExpires, + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [switch]$CannotChangePassword, + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [datetime]$AccountExpirationDate, + + # -- Atributos Customizados -- + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$extensionAttribute1, + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$extensionAttribute2, + [Parameter(Mandatory = $false, ParameterSetName = 'SingleUser')] [string]$ProxyAddresses, + + # --- Parâmetros de Logging --- + [Parameter(Mandatory = $false)] [string]$DatabaseConnectionString, + [Parameter(Mandatory = $false)] [string]$LogFilePath = ".\New-UnifiedADUser-Log-$(Get-Date -Format 'yyyy-MM-dd').txt" ) # --- FUNÇÕES AUXILIARES --- @@ -127,29 +153,27 @@ Este script cria usuários no AD do cliente e no AD do Exchange e deve ser chama MÉTODOS DE USO: 1. Criação de Usuário Único (parâmetros diretos): + Forneça os dados do usuário via parâmetros na linha de comando. Exemplo: - .\New-UnifiedADUser.ps1 -SamAccountName 'joao.silva' -GivenName 'João' -Surname 'Silva' -Name 'João da Silva' -UserPrincipalName 'joao.silva@cliente.com.br' -Path 'OU=Usuarios,DC=local' -ClientADServer '...' -ClientADCredential (Get-Credential) -ExchangeADServer '...' -ExchangeADCredential (Get-Credential) + .\New-UnifiedADUser.ps1 -SamAccountName 'joao.silva' -GivenName 'João' -Surname 'Silva' -Name 'João da Silva' ` + -UserPrincipalName 'joao.silva@cliente.com.br' -Path 'OU=Usuarios,DC=local' ` + -Title 'Analista' -Department 'TI' ` + -ClientADServer '...' -ClientADCredential (Get-Credential) -ExchangeADServer '...' -ExchangeADCredential (Get-Credential) 2. Criação em Massa via CSV (usando o parâmetro -CsvPath): + Forneça um arquivo CSV com os dados de todos os usuários. Exemplo: .\New-UnifiedADUser.ps1 -CsvPath 'C:\temp\usuarios.csv' -ClientADServer '...' -ClientADCredential (Get-Credential) -ExchangeADServer '...' -ExchangeADCredential (Get-Credential) -3. Criação via Banco de Dados (usando o parâmetro -FromDatabase): - (Funcionalidade a ser implementada) - Exemplo: - .\New-UnifiedADUser.ps1 -FromDatabase -ClientADServer '...' -ClientADCredential (Get-Credential) -ExchangeADServer '...' -ExchangeADCredential (Get-Credential) - "@ } # --- LÓGICA PRINCIPAL --- -# --- VALIDAÇÃO: Garante que o script não seja executado de forma interativa --- if ($PSBoundParameters.Count -eq 0) { Show-Usage - exit 1 # Encerra o script imediatamente + exit 1 } -# --- FIM DA VALIDAÇÃO --- try { Import-Module ActiveDirectory -ErrorAction Stop @@ -175,12 +199,7 @@ $usersToProcess = @() switch ($PSCmdlet.ParameterSetName) { 'SingleUser' { $usersToProcess += [PSCustomObject]@{ - SamAccountName = $SamAccountName - GivenName = $GivenName - Surname = $Surname - Name = $Name - UserPrincipalName = $UserPrincipalName - Path = $Path + SamAccountName = $SamAccountName; UserPrincipalName = $UserPrincipalName; GivenName = $GivenName; Surname = $Surname; Name = $Name; Path = $Path; Title = $Title; Department = $Department; Company = $Company; Manager = $Manager; EmployeeID = $EmployeeID; EmployeeNumber = $EmployeeNumber; OfficePhone = $OfficePhone; MobilePhone = $MobilePhone; EmailAddress = $EmailAddress; StreetAddress = $StreetAddress; City = $City; State = $State; PostalCode = $PostalCode; Country = $Country; Description = $Description; Office = $Office; HomePage = $HomePage; PasswordNeverExpires = $PasswordNeverExpires; CannotChangePassword = $CannotChangePassword; AccountExpirationDate = $AccountExpirationDate; extensionAttribute1 = $extensionAttribute1; extensionAttribute2 = $extensionAttribute2; ProxyAddresses = $ProxyAddresses } break } @@ -208,85 +227,137 @@ switch ($PSCmdlet.ParameterSetName) { foreach ($user in $usersToProcess) { - $u_sam = $user.SamAccountName - Write-Host "Iniciando processamento para o usuário: $u_sam" - Write-Log -Level 'INFO' -Message "Iniciando provisionamento para o usuário '$u_sam'." + Write-Host "Iniciando processamento para o usuário: $($user.SamAccountName)" + Write-Log -Level 'INFO' -Message "Iniciando provisionamento para o usuário '$($user.SamAccountName)'." - # --- BLOCO DE VALIDAÇÕES --- + # --- BLOCO DE VALIDAÇÕES APRIMORADO --- $validationFailed = $false - if ([string]::IsNullOrWhiteSpace($u_sam) -or [string]::IsNullOrWhiteSpace($user.UserPrincipalName) -or [string]::IsNullOrWhiteSpace($user.Path)) { - Write-Log -Level 'ERROR' -Message "USUÁRIO IGNORADO: Dados essenciais (SamAccountName, UserPrincipalName, Path) estão faltando para o usuário '$u_sam'." + # 1. Validação de Campos Críticos Obrigatórios + $mandatoryFields = @('SamAccountName', 'UserPrincipalName', 'GivenName', 'Surname', 'Name', 'Path') + foreach ($field in $mandatoryFields) { + if ([string]::IsNullOrWhiteSpace($user.$field)) { + Write-Log -Level 'ERROR' -Message "USUÁRIO IGNORADO: O campo crítico obrigatório '$field' está faltando para '$($user.SamAccountName)'." + $validationFailed = $true + break + } + } + if ($validationFailed) { Write-Host " [ERRO] Falha na validação de campos obrigatórios." -ForegroundColor Red; continue } + + # 2. Validação de Unicidade (SamAccountName e UserPrincipalName) + if (Get-ADUser -Filter "SamAccountName -eq '$($user.SamAccountName)'" -Server $ClientADServer -Credential $ClientADCredential) { + Write-Log -Level 'ERROR' -Message "USUÁRIO IGNORADO: O SamAccountName '$($user.SamAccountName)' já existe." + $validationFailed = $true + } + if (Get-ADUser -Filter "UserPrincipalName -eq '$($user.UserPrincipalName)'" -Server $ClientADServer -Credential $ClientADCredential) { + Write-Log -Level 'ERROR' -Message "USUÁRIO IGNORADO: O UserPrincipalName '$($user.UserPrincipalName)' já existe." + $validationFailed = $true + } + + # 3. Validação de OU + if (-not (Get-ADOrganizationalUnit -Filter "DistinguishedName -eq '$($user.Path)'" -Server $ClientADServer -Credential $ClientADCredential)) { + Write-Log -Level 'ERROR' -Message "USUÁRIO IGNORADO: A OU '$($user.Path)' não foi encontrada no Active Directory." $validationFailed = $true } - if (-not $validationFailed) { - if ($u_sam.Length -gt 20) { - Write-Log -Level 'ERROR' -Message "USUÁRIO IGNORADO: O SamAccountName '$u_sam' excede o limite de 20 caracteres." - $validationFailed = $true - } - if (Get-ADUser -Filter "SamAccountName -eq '$u_sam'" -Server $ClientADServer -Credential $ClientADCredential) { - Write-Log -Level 'ERROR' -Message "USUÁRIO IGNORADO: O SamAccountName '$u_sam' já existe no Active Directory." - $validationFailed = $true - } + # 4. Validação de UPN + $upnSuffix = ($user.UserPrincipalName).Split('@')[1] + if ($upnSuffix -eq 'exch.local') { + Write-Log -Level 'ERROR' -Message "USUÁRIO IGNORADO: O UPN '$($user.UserPrincipalName)' usa o sufixo proibido 'exch.local'." + $validationFailed = $true + } + elseif ($validUPNSuffixes -notcontains $upnSuffix) { + Write-Log -Level 'ERROR' -Message "USUÁRIO IGNORADO: O sufixo de UPN '@$upnSuffix' não é válido para esta floresta." + $validationFailed = $true } - if (-not $validationFailed) { - if (-not (Get-ADOrganizationalUnit -Filter "DistinguishedName -eq '$($user.Path)'" -Server $ClientADServer -Credential $ClientADCredential)) { - Write-Log -Level 'ERROR' -Message "USUÁRIO IGNORADO: A OU '$($user.Path)' não foi encontrada no Active Directory." - $validationFailed = $true - } - } - - if (-not $validationFailed) { - $upnSuffix = ($user.UserPrincipalName).Split('@')[1] - if ($upnSuffix -eq 'exch.local') { - Write-Log -Level 'ERROR' -Message "USUÁRIO IGNORADO: O UPN '$($user.UserPrincipalName)' usa o sufixo proibido 'exch.local'." - $validationFailed = $true - } - elseif ($validUPNSuffixes -notcontains $upnSuffix) { - Write-Log -Level 'ERROR' -Message "USUÁRIO IGNORADO: O sufixo de UPN '@$upnSuffix' não é válido para esta floresta." - $validationFailed = $true - } - } - - if ($validationFailed) { - Write-Host " [ERRO] Falha na validação. Verifique o log para detalhes." -ForegroundColor Red - continue - } - # --- FIM DO BLOCO DE VALIDAÇÕES --- + if ($validationFailed) { Write-Host " [ERRO] Falha na validação. Verifique o log para detalhes." -ForegroundColor Red; continue } + # --- FIM DAS VALIDAÇÕES --- $clientADSuccess = $false try { $tempPassword = -join ((65..90) + (97..122) + (48..57) | Get-Random -Count 16 | ForEach-Object { [char]$_ }) $securePassword = ConvertTo-SecureString $tempPassword -AsPlainText -Force + # Inicia a construção dos parâmetros para o New-ADUser $userParams = @{ - SamAccountName = $u_sam - GivenName = $user.GivenName - Surname = $user.Surname - Name = $user.Name - UserPrincipalName = $user.UserPrincipalName - Path = $user.Path - AccountPassword = $securePassword - Enabled = $true - ChangePasswordAtLogon = $true - Server = $ClientADServer - Credential = $ClientADCredential + SamAccountName = $user.SamAccountName + UserPrincipalName = $user.UserPrincipalName + GivenName = $user.GivenName + Surname = $user.Surname + Name = $user.Name + DisplayName = $user.Name + Path = $user.Path + AccountPassword = $securePassword + Enabled = $true + ChangePasswordAtLogon = $true } - Write-Log -Level 'INFO' -Message "Tentando criar a conta '$u_sam' no AD do Cliente em '$ClientADServer'." -TargetADServer $ClientADServer + # --- ADIÇÃO CONDICIONAL DE TODOS OS ATRIBUTOS OPCIONAIS --- + # A checagem '... -contains ...' garante que o script não falhe se a coluna não existir no CSV + if ($user.PSObject.Properties.Name -contains 'EmailAddress' -and -not [string]::IsNullOrWhiteSpace($user.EmailAddress)) { $userParams.Add('EmailAddress', $user.EmailAddress) } + if ($user.PSObject.Properties.Name -contains 'Description' -and -not [string]::IsNullOrWhiteSpace($user.Description)) { $userParams.Add('Description', $user.Description) } - New-ADUser @userParams -ErrorAction Stop + # Organização + if ($user.PSObject.Properties.Name -contains 'Title' -and -not [string]::IsNullOrWhiteSpace($user.Title)) { $userParams.Add('Title', $user.Title) } + if ($user.PSObject.Properties.Name -contains 'Department' -and -not [string]::IsNullOrWhiteSpace($user.Department)) { $userParams.Add('Department', $user.Department) } + if ($user.PSObject.Properties.Name -contains 'Company' -and -not [string]::IsNullOrWhiteSpace($user.Company)) { $userParams.Add('Company', $user.Company) } + if ($user.PSObject.Properties.Name -contains 'EmployeeID' -and -not [string]::IsNullOrWhiteSpace($user.EmployeeID)) { $userParams.Add('EmployeeID', $user.EmployeeID) } + if ($user.PSObject.Properties.Name -contains 'EmployeeNumber' -and -not [string]::IsNullOrWhiteSpace($user.EmployeeNumber)) { $userParams.Add('EmployeeNumber', $user.EmployeeNumber) } + if ($user.PSObject.Properties.Name -contains 'Office' -and -not [string]::IsNullOrWhiteSpace($user.Office)) { $userParams.Add('physicalDeliveryOfficeName', $user.Office) } + + # Contato + if ($user.PSObject.Properties.Name -contains 'OfficePhone' -and -not [string]::IsNullOrWhiteSpace($user.OfficePhone)) { $userParams.Add('OfficePhone', $user.OfficePhone) } + if ($user.PSObject.Properties.Name -contains 'MobilePhone' -and -not [string]::IsNullOrWhiteSpace($user.MobilePhone)) { $userParams.Add('Mobile', $user.MobilePhone) } + + # Endereço + if ($user.PSObject.Properties.Name -contains 'StreetAddress' -and -not [string]::IsNullOrWhiteSpace($user.StreetAddress)) { $userParams.Add('StreetAddress', $user.StreetAddress) } + if ($user.PSObject.Properties.Name -contains 'City' -and -not [string]::IsNullOrWhiteSpace($user.City)) { $userParams.Add('City', $user.City) } + if ($user.PSObject.Properties.Name -contains 'State' -and -not [string]::IsNullOrWhiteSpace($user.State)) { $userParams.Add('State', $user.State) } + if ($user.PSObject.Properties.Name -contains 'PostalCode' -and -not [string]::IsNullOrWhiteSpace($user.PostalCode)) { $userParams.Add('PostalCode', $user.PostalCode) } + if ($user.PSObject.Properties.Name -contains 'Country' -and -not [string]::IsNullOrWhiteSpace($user.Country)) { $userParams.Add('Country', $user.Country) } + + # Perfil Web + if ($user.PSObject.Properties.Name -contains 'HomePage' -and -not [string]::IsNullOrWhiteSpace($user.HomePage)) { $userParams.Add('HomePage', $user.HomePage) } + + # Controle da Conta + if ($user.PSObject.Properties.Name -contains 'AccountExpirationDate' -and $user.AccountExpirationDate) { $userParams.Add('AccountExpirationDate', ([datetime]$user.AccountExpirationDate)) } + if ($user.PSObject.Properties.Name -contains 'PasswordNeverExpires' -and ($user.PasswordNeverExpires -eq 'True' -or $user.PasswordNeverExpires -is [bool] -and $user.PasswordNeverExpires)) { $userParams.Add('PasswordNeverExpires', $true) } + if ($user.PSObject.Properties.Name -contains 'CannotChangePassword' -and ($user.CannotChangePassword -eq 'True' -or $user.CannotChangePassword -is [bool] -and $user.CannotChangePassword)) { $userParams.Add('CannotChangePassword', $true) } + + # Atributos Customizados + if ($user.PSObject.Properties.Name -contains 'extensionAttribute1' -and -not [string]::IsNullOrWhiteSpace($user.extensionAttribute1)) { $userParams.Add('extensionAttribute1', $user.extensionAttribute1) } + if ($user.PSObject.Properties.Name -contains 'extensionAttribute2' -and -not [string]::IsNullOrWhiteSpace($user.extensionAttribute2)) { $userParams.Add('extensionAttribute2', $user.extensionAttribute2) } + + # Lógica para Múltiplos E-mails (ProxyAddresses) + if ($user.PSObject.Properties.Name -contains 'ProxyAddresses' -and -not [string]::IsNullOrWhiteSpace($user.ProxyAddresses)) { + $proxyList = @("SMTP:" + $user.UserPrincipalName) + $aliases = $user.ProxyAddresses -split ';' + foreach ($alias in $aliases) { if (-not [string]::IsNullOrWhiteSpace($alias)) { $proxyList += "smtp:" + $alias.Trim() } } + $userParams.Add('ProxyAddresses', $proxyList) + } - Write-Log -Level 'INFO' -Message "SUCESSO: Conta '$u_sam' criada no AD do Cliente. Senha temporária gerada." -TargetADServer $ClientADServer + # Lógica para Gestor (Manager) + if ($user.PSObject.Properties.Name -contains 'Manager' -and -not [string]::IsNullOrWhiteSpace($user.Manager)) { + $managerUser = Get-ADUser -Filter "SamAccountName -eq '$($user.Manager)'" -Server $ClientADServer -Credential $ClientADCredential + if ($managerUser) { + $userParams.Add('Manager', $managerUser.DistinguishedName) + } else { + Write-Log -Level 'WARN' -Message "Gestor '$($user.Manager)' não encontrado para o usuário '$($user.SamAccountName)'. O campo não será preenchido." + } + } + + # Criação do usuário no AD + New-ADUser @userParams -Server $ClientADServer -Credential $ClientADCredential -ErrorAction Stop + + Write-Log -Level 'INFO' -Message "SUCESSO: Conta '$($user.SamAccountName)' criada no AD do Cliente. Senha temporária gerada." -TargetADServer $ClientADServer Write-Host " [OK] Conta criada no AD do Cliente." -ForegroundColor Green - Write-Log -Level 'INFO' -Message "Senha temporária para '$u_sam': $tempPassword" + Write-Log -Level 'INFO' -Message "Senha temporária para '$($user.SamAccountName)': $tempPassword" $clientADSuccess = $true } catch { - $errorMessage = "FALHA ao criar a conta '$u_sam' no AD do Cliente. Erro: $($_.Exception.Message -replace "`r`n"," ")" + $errorMessage = "FALHA ao criar a conta '$($user.SamAccountName)' no AD do Cliente. Erro: $($_.Exception.Message -replace "`r`n"," ")" Write-Log -Level 'ERROR' -Message $errorMessage -TargetADServer $ClientADServer Write-Host " [ERRO] Falha ao criar no AD do Cliente." -ForegroundColor Red continue @@ -295,16 +366,16 @@ foreach ($user in $usersToProcess) { if ($clientADSuccess) { try { Start-Sleep -Seconds 5 - Write-Log -Level 'INFO' -Message "Tentando habilitar a mailbox para '$u_sam' no AD do Exchange em '$ExchangeADServer'." -TargetADServer $ExchangeADServer + Write-Log -Level 'INFO' -Message "Tentando habilitar a mailbox para '$($user.SamAccountName)' no AD do Exchange em '$ExchangeADServer'." -TargetADServer $ExchangeADServer - Enable-Mailbox -Identity $u_sam -DomainController $ExchangeADServer -Credential $ExchangeADCredential -ErrorAction Stop + Enable-Mailbox -Identity $user.SamAccountName -DomainController $ExchangeADServer -Credential $ExchangeADCredential -ErrorAction Stop - Write-Log -Level 'INFO' -Message "SUCESSO: Mailbox para '$u_sam' habilitada no ambiente Exchange." -TargetADServer $ExchangeADServer + Write-Log -Level 'INFO' -Message "SUCESSO: Mailbox para '$($user.SamAccountName)' habilitada no ambiente Exchange." -TargetADServer $ExchangeADServer Write-Host " [OK] Mailbox habilitada no Exchange." -ForegroundColor Green - Write-Log -Level 'INFO' -Message "PROVISIONAMENTO COMPLETO para o usuário '$u_sam'." + Write-Log -Level 'INFO' -Message "PROVISIONAMENTO COMPLETO para o usuário '$($user.SamAccountName)'." } catch { - $errorMessage = "FALHA PARCIAL: A conta '$u_sam' foi criada no AD do Cliente, mas falhou ao habilitar a mailbox no Exchange. Erro: $($_.Exception.Message -replace "`r`n"," ")" + $errorMessage = "FALHA PARCIAL: A conta '$($user.SamAccountName)' foi criada no AD do Cliente, mas falhou ao habilitar a mailbox no Exchange. Erro: $($_.Exception.Message -replace "`r`n"," ")" Write-Log -Level 'ERROR' -Message $errorMessage -TargetADServer $ExchangeADServer Write-Host " [ERRO] Falha ao habilitar a mailbox no Exchange." -ForegroundColor Red }