SyncMultipleGroups2One.ps1
<#PSScriptInfo
.VERSION 1.0 .GUID 99891081-c8f5-487d-8b83-434611b36043 .AUTHOR Vikas Sukhija .COMPANYNAME TechWizard.cloud .COPYRIGHT Vikas Sukhija .TAGS .LICENSEURI .PROJECTURI https://techwizard.cloud/2021/02/07/sync-multiple-groups-to-single-group/ .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES https://techwizard.cloud/2021/02/07/sync-multiple-groups-to-single-group/ .PRIVATEDATA #> <# .DESCRIPTION Sync Multiple Groups to Single Group #> param ( [string[]]$groups = $(Read-Host "Enter Groups as Source seprated by Coma"), [string]$Desgroup = $(Read-Host "Enter the Destination Group"), [string]$smtpserver = $(Read-Host "Enter SMTP Server"), [string]$from = $(Read-Host "Enter From Address"), [string]$erroremail = $(Read-Host "Enter Address for Report and Errors"), $countofchanges = $(Read-Host "Enter Count of changes"), $logrecyclelimit = $(Read-Host "Enter Number of Days for log Recycling") ) ######################Load Functions############################################ function New-FolderCreation { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$foldername ) $logpath = (Get-Location).path + "\" + "$foldername" $testlogpath = Test-Path -Path $logpath if($testlogpath -eq $false) { #Start-ProgressBar -Title "Creating $foldername folder" -Timer 10 $null = New-Item -Path (Get-Location).path -Name $foldername -Type directory } } function Write-Log { [CmdletBinding()] param ( [Parameter(Mandatory = $true,ParameterSetName = 'Create')] [array]$Name, [Parameter(Mandatory = $true,ParameterSetName = 'Create')] [string]$Ext, [Parameter(Mandatory = $true,ParameterSetName = 'Create')] [string]$folder, [Parameter(ParameterSetName = 'Create',Position = 0)][switch]$Create, [Parameter(Mandatory = $true,ParameterSetName = 'Message')] [String]$message, [Parameter(Mandatory = $true,ParameterSetName = 'Message')] [String]$path, [Parameter(Mandatory = $false,ParameterSetName = 'Message')] [ValidateSet('Information','Warning','Error')] [string]$Severity = 'Information', [Parameter(ParameterSetName = 'Message',Position = 0)][Switch]$MSG ) switch ($PsCmdlet.ParameterSetName) { "Create" { $log = @() $date1 = Get-Date -Format d $date1 = $date1.ToString().Replace("/", "-") $time = Get-Date -Format t $time = $time.ToString().Replace(":", "-") $time = $time.ToString().Replace(" ", "") New-FolderCreation -foldername $folder foreach ($n in $Name) {$log += (Get-Location).Path + "\" + $folder + "\" + $n + "_" + $date1 + "_" + $time + "_.$Ext"} return $log } "Message" { $date = Get-Date $concatmessage = "|$date" + "| |" + $message +"| |" + "$Severity|" switch($Severity){ "Information"{Write-Host -Object $concatmessage -ForegroundColor Green} "Warning"{Write-Host -Object $concatmessage -ForegroundColor Yellow} "Error"{Write-Host -Object $concatmessage -ForegroundColor Red} } Add-Content -Path $path -Value $concatmessage } } } #Function Write-Log Function Get-ADGroupMembersRecursive{ Param( [Parameter(Mandatory = $true,ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [String[]]$Groups, [ValidateNotNullOrEmpty()] [String[]]$Properties ) Begin{ $Results = @() [String[]]$defaultproperties = "distinguishedName","name","objectClass","objectGUID","SamAccountName","SID" $Properties+=$defaultproperties $Properties = $Properties | Sort-Object -Unique } Process{ ForEach($adobj in $Groups){ $getgroupdn = (Get-ADGroup -identity $adobj).DistinguishedName $findallgroups = Get-ADGroup -identity $getgroupdn -Properties members| Select-Object -ExpandProperty members | get-adobject | Where-Object{$_.objectClass -eq "Group"} |Select DistinguishedName $Results+=$getgroupdn ForEach($Object in $findallgroups){ Get-ADGroupMembersRecursive $Object.DistinguishedName -Properties $Properties } } } End{ $Results = $Results | Select-Object -Unique $collgroupmembers=@() foreach($item in $Results){ $arrgroupmembers =@() $arrgroupmembers = Get-ADGroup -id $item -Properties members | Select-Object -ExpandProperty members |get-adobject | Where-Object{$_.objectClass -eq "user"} | Get-ADUser -properties $Properties | Select-Object $Properties $collgroupmembers+=$arrgroupmembers } $collgroupmembers } } #Get-ADGroupMembersRecursive function Set-Recyclelogs { [CmdletBinding( SupportsShouldProcess = $true, ConfirmImpact = 'High')] param ( [Parameter(Mandatory = $true,ParameterSetName = 'Local')] [string]$foldername, [Parameter(Mandatory = $true,ParameterSetName = 'Local')] [Parameter(Mandatory = $true,ParameterSetName = 'Path')] [Parameter(Mandatory = $true,ParameterSetName = 'Remote')] [int]$limit, [Parameter(ParameterSetName = 'Local',Position = 0)][switch]$local, [Parameter(Mandatory = $true,ParameterSetName = 'Remote')] [string]$ComputerName, [Parameter(Mandatory = $true,ParameterSetName = 'Remote')] [string]$DriveName, [Parameter(Mandatory = $true,ParameterSetName = 'Remote')] [string]$folderpath, [Parameter(ParameterSetName = 'Remote',Position = 0)][switch]$Remote, [Parameter(Mandatory = $true,ParameterSetName = 'Path')] [ValidateScript({ if(-Not ($_ | Test-Path) ){throw "File or folder does not exist"} return $true })] [string]$folderlocation, [Parameter(ParameterSetName = 'Path',Position = 0)][switch]$Path ) switch ($PsCmdlet.ParameterSetName) { "Local" { $path1 = (Get-Location).path + "\" + "$foldername" if ($PsCmdlet.ShouldProcess($path1 , "Delete")) { Write-Host "Path Recycle - $path1 Limit - $limit" -ForegroundColor Green $limit1 = (Get-Date).AddDays(-"$limit") #for report recycling $getitems = Get-ChildItem -Path $path1 -recurse -file | Where-Object {$_.CreationTime -lt $limit1} ForEach($item in $getitems){ Write-Verbose -Message "Deleting item $($item.FullName)" Remove-Item $item.FullName -Force } } } "Remote" { $path1 = "\\" + $ComputerName + "\" + $DriveName + "$" + "\" + $folderpath if ($PsCmdlet.ShouldProcess($path1 , "Delete")) { Write-Host "Recycle Path - $path1 Limit - $limit" -ForegroundColor Green $limit1 = (Get-Date).AddDays(-"$limit") #for report recycling $getitems = Get-ChildItem -Path $path1 -recurse -file | Where-Object {$_.CreationTime -lt $limit1} ForEach($item in $getitems){ Write-Verbose -Message "Deleting item $($item.FullName)" Remove-Item $item.FullName -Force } } } "Path" { $path1 = $folderlocation if ($PsCmdlet.ShouldProcess($path1 , "Delete")) { Write-Host "Path Recycle - $path1 Limit - $limit" -ForegroundColor Green $limit1 = (Get-Date).AddDays(-"$limit") #for report recycling $getitems = Get-ChildItem -Path $path1 -recurse -file | Where-Object {$_.CreationTime -lt $limit1} ForEach($item in $getitems){ Write-Verbose -Message "Deleting item $($item.FullName)" Remove-Item $item.FullName -Force } } } } }# Set-Recycle logs #####################Finished Loading Functions################################## ####################Load variables and log####################################### $log = Write-Log -Name "GroupSync-Log" -folder "logs" -Ext "log" ########################Start Script################ Write-Log -Message "Start script" -path $log try { Import-Module ActiveDirectory Write-Log -Message "loaded.... AD Module" -path $log } catch { $exception = $_.Exception Write-Log -Message "Error loading AD Module" -path $log -Severity Error Write-Log -Message $exception -path $log -Severity error Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Error has occured loading AD Module - SyncmultipleGroupsWithOne" -Body $($_.Exception.Message) exit; } try{ $groups = $groups -split "," $collgroup=@() Write-Log -Message "Start fetching group membership information $groups" -path $log $collgroup1 = Get-ADGroupMembersRecursive -groups $groups | Select-Object -ExpandProperty samaccountname $collgroup = $collgroup1 | select -Unique Write-Log -Message "Start fetching group membership information $Desgroup" -path $log $collgroup3 = Get-ADGroup -id $Desgroup -Properties member | Select-Object -ExpandProperty member | Get-ADUser | Select-Object -ExpandProperty samaccountname #destination group Write-Log -Message "Finished fetching group membership" -path $log } catch{ $exception = $_.Exception Write-Log -Message "Error fetching group membership information" -path $log -Severity Error Write-Log -Message $exception -path $log -Severity error Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Error has occured fetching group membership information - SyncmultipleGroupsWithOne" -Body $($_.Exception.Message) exit; } try{ Write-Log -Message "Start comparing $groups with $Desgroup" -path $log $changes = Compare-Object -ReferenceObject $collgroup -DifferenceObject $collgroup3 | Select-Object -Property inputobject, @{ n = 'State' e = {If ($_.SideIndicator -eq "=>"){"Removal" } Else { "Addition" }} } if($Changes){ $removal = $Changes | Where-Object -FilterScript {$_.State -eq "Removal"} | Select -ExpandProperty inputobject $Addition = $Changes | Where-Object -FilterScript {$_.State -eq "Addition"} | Select -ExpandProperty inputobject if($Addition){ $addcount = $Addition.count Write-Log -Message "Adding members to $Desgroup count $addcount" -path $log if($addcount -le $countofchanges){ $Addition | ForEach-Object{ $amem = $_ Write-Log -Message "ADD $amem to $Desgroup" -path $log ADD-ADGroupMember -identity $Desgroup -Members $amem -Confirm:$false } }else{ Write-Log -Message "ADD count $addcount is more than $countofchanges" -path $log -Severity Error Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Error has occured ADD count $addcount is more than $countofchanges - SyncmultipleGroupsWithOne" -Body "Error has occured ADD count $addcount is more than $countofchanges - SyncmultipleGroupsWithOne" } } if($removal){ $remcount = $removal.count Write-Log -Message "Removing members from $Desgroup count $remcount" -path $log if($remcount -le $countofchanges){ $removal | ForEach-Object{ $rmem = $_ Write-Log -Message "Remove $rmem from $Desgroup" -path $log Remove-ADGroupMember -identity $Desgroup -Members $rmem -Confirm:$false } }else{ Write-Log -Message "Remove count $remcount is more than $countofchanges" -path $log -Severity Error Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Error has occured Remove count $remcount is more than $countofchanges - SyncmultipleGroupsWithOne" -Body "Error has occured Remove count $remcount is more than $countofchanges - SyncmultipleGroupsWithOne" } } } } catch{ $exception = $_.Exception Write-Log -Message "Error comparing $Desgroup with$groups" -path $log -Severity Error Write-Log -Message $exception -path $log -Severity error Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Error has occured comparing $Desgroup - SyncmultipleGroupsWithOne" -Body $($_.Exception.Message) } ########################Recycle reports & logs############## Write-Log -Message "Recycle Logs" -path $log -Severity Information Set-Recyclelogs -foldername "logs" -limit $logrecyclelimit -Confirm:$false Write-Log -Message "Script Finished" -path $log Send-MailMessage -SmtpServer $smtpserver -From $from -To $erroremail -Subject "Log - SyncmultipleGroupsWithOne" -Body "Log - SyncmultipleGroupsWithOne" -Attachments $log ############################################################################## |