###################################################################################################################################################### # Script Title: .\O365UPNCheckV4.ps1 # Script Version: Version 4.0 February 7, 2012 # Script Author: Rick Bergman & Ray Zabilla, Microsoft Corporation # # Script Purpose: Uses an import file to retrive the users current DN & UPN from AD, then checks to users metadata to see when their UPN was updated # and on which Server it was updated on. Next it will grab all Event ID 642 from the list of DC's. # # Script Paramaters: .\O365UPNCheckV4.ps1 'Full' - will run the event log gathering step # .\O365UPNCheckV4.ps1 with no command line parameters, will log only UPN update information and NOT gather the Security event logs # # Result: Script generates the following files: # Output.csv - which then deleted when the script completes # BadUPN_.csv - List of UPN that have changed # O365UPNCheck_.csv - General Log # EventID642__.log \ Both are created for each DC that is scanned. # EventID642___Timing.log / Timing how long has it taken for the log # # Email: An Email notification will be sent to DL_UPN_Changes@Contoso.com DL including the BadUPNs from the 1600 user list # ###################################################################################################################################################### #-----------------Configurations-------------------- Param($RunType) $IFN = ".\1600ToFix.csv" $IFile = Import-Csv $IFN $DT = Get-Date -format "yyyymmddHHmmss" $LogFile = ".\O365UPNCheck_" + $DT + ".log" $CompFile = ".\Output.csv" $BadUPN = ".\BadUPN_" + $DT + ".log" $SrvArray = @() $DC = (Get-ADDomainController).HostName $GC = $DC + ":3268" $SB = "DC=Contoso,DC=com" $Domain = "Contoso.com" #---------------End Configurations------------------------- # Creates and Open the General Log Add-Content -Path $LogFile -Value "------------------------------------------------" -ErrorAction Stop Add-Content -Path $LogFile -Value "O365UPNCheck.ps1 Version 1.0 (January 31,2012)" Add-Content -Path $LogFile -Value $("Started: " + (Get-Date).ToString()) Add-Content -Path $LogFile -Value "Input file: $FN" Add-Content -Path $LogFile -Value "Log file: $LogFile" Add-Content -Path $LogFile -Value "------------------------------------------------" -ErrorAction Stop Add-Content -Path $LogFile -Value " " # Check for AD Module, if not there add it, otherwise continue If ( (Get-Module -Name ActiveDirectory -ErrorAction SilentlyContinue) -eq $null ) { Import-Module ActiveDirectory } # Check for existence of of the Output file, delete if it exists because the assumption is that it is old If (Test-Path $CompFile) { Remove-Item $CompFile } # Updating the Script Run Log Add-Content -Path $LogFile -Value "------------------------------------------------" -ErrorAction Stop Add-Content -Path $LogFile -Value "Started Processing Input File & Checking AD Information" Add-Content -Path $LogFile -Value "------------------------------------------------" -ErrorAction Stop Add-Content -Path $LogFile -Value " " # Use the Input File to create a comparison file by querying AD Add-Content -Path $CompFile -Value "SamAccountName;UserPrincipalName;DistinguishedName" # loop through each record in the input file and get the SamAccountName, UPN and DistinguishedName and write to the log files ForEach ($Obj in $IFile) { $SAM = $Obj.sAMAccountName $OUser = Get-ADUser -Filter {sAMAccountName -eq $SAM} -Server $GC -SearchBase $SB If ($OUser) { Add-Content -Path $CompFile -Value $($OUser.SamAccountName + ";" + $OUser.UserPrincipalName + ";" + $OUser.DistinguishedName) Add-Content -Path $LogFile -Value $("SUCCES - User Found in AD - " + $OUser.SamAccountName) } Else { Add-Content -Path $LogFile -Value $("ERROR - User NOT Found in AD - " + $OUser.SamAccountName) } } # Updating the Script Run Log Add-Content -Path $LogFile -Value "------------------------------------------------" -ErrorAction Stop Add-Content -Path $LogFile -Value "Started Processing Changed UPN's and Finding EventID 642" Add-Content -Path $LogFile -Value $("Created an UPN Error Log - " + $BadUPN) Add-Content -Path $LogFile -Value "------------------------------------------------" -ErrorAction Stop Add-Content -Path $LogFile -Value " " # Use the Comparsion file to compare user account UPN to see if it has any "." $CFile = Import-Csv $CompFIle -Delimiter ";" # Create the Incorrect UPN Log file and write the header Add-Content -Path $BadUPN -Value "SamAccountName,UserPrincipalName,DistinguishedName,OriginatingServer,LastOriginatingChangeTime" # Loop through all users to get their Replication Meta Data Information ForEach ($Acct in $CFile) { # Split the UPN value at the "@" $SPLT = $Acct.UserPrincipalName -split "@" $Name = $SPLT[0] # Check to see if the first part of the UPN contains a "." Example John.Doe, if not then get the AD Meta Data If (-not ($Name.Contains("."))) { # Get the Replication Meta Data $ObjectDN = $Acct.DistinguishedName $Property = "userprincipalname" $context = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$domain) $oDC = [System.DirectoryServices.ActiveDirectory.DomainController]::findOne($context) $meta = $oDC.GetReplicationMetadata($objectDN) $OrgSvr = $meta.userprincipalname.OriginatingServer $LastChg = $meta.userprincipalname.LastOriginatingChangeTime # Write to the Bad UPN Log Add-Content -Path $BadUPN -Value $($Acct.SamAccountName +","+ $Acct.UserPrincipalName +","""+ $ObjectDN +""","+ $OrgSvr +","+ $LastChg) Add-Content -Path $LogFile -Value $("ERROR - User's UPN was incorrect " + $Acct.SamAccountName) # Filter out duplicate Server names If ($OrgSvr -ne $null) { If (-not ($SrvArray -Contains ($OrgSvr))) { $SrvArray += $OrgSvr } } } Else { # Log the Good Users Add-Content -Path $LogFile -Value $("SUCCESS - User's UPN was correct - " + $Acct.SamAccountName) } } # Check input param for full run or not If ($RunType -eq "Full") { # Updating the Script Run Log Add-Content -Path $LogFile -Value "------------------------------------------------" -ErrorAction Stop Add-Content -Path $LogFile -Value "Started Finding EventID 642 from a lists of DCs" Add-Content -Path $LogFile -Value "------------------------------------------------" -ErrorAction Stop Add-Content -Path $LogFile -Value " " # Connect to the Servers in list and dump the security event logs for Event ID 642 ForEach ($Srv in $SrvArray) { Start-Job -Name "DmpEvt$Srv" -ArgumentList $Srv -ScriptBlock { Param ($comp) $DT = Get-Date -format "yyyymmddHHmmss" $CompName = ($comp.SPlit("."))[0] $File = "D:\Work\EventID642_" + $compName + "_" + $DT + ".Log" $Timing = "D:\Work\EventID642_" + $compName + "_" + $DT + "_Timing" + ".Log" $stime = Get-Date Add-Content -path $Timing -Value " ------------- Started processing log file processing at $stime" GWMI Win32_ntlogevent -Filter "logfile='Security' AND EventCode=642" -ComputerName $Comp | Out-File -FilePath $File # Get-EventLog Security -Computer $compName -newest 100 | Out-File -FilePath $File $etime = Get-date Add-Content -path $Timing -Value " ------------- End Log file processing at $etime" } } } Else { Add-Content -Path $LogFile -Value "------------------------------------------------" -ErrorAction Stop Add-Content -Path $LogFile -Value "The Option was choosen to skip scanning the event logs for Event ID 642" Add-Content -Path $LogFile -Value "------------------------------------------------" -ErrorAction Stop Add-Content -Path $LogFile -Value " " } If (Test-Path $CompFile) { Remove-Item $CompFile } Add-Content -Path $Logfile -Value " " Add-Content -Path $LogFile -Value "------------------------------------------------" -ErrorAction Stop Add-Content -Path $Logfile -Value "Sending Email Notification that the script has run" Add-Content -Path $LogFile -Value "------------------------------------------------" -ErrorAction Stop $EmailFrom = "Test@Contoso.com" $EmailTo = "DL_UPN_Changes@Contoso.com" $EmailSubject = "O365UPNCheckV4.PS1 Script has completed" $EmailBody = "Attached is the output from the Office 365 UPN Check Script" $Attach = Get-ChildItem $BadUPN $SMTPSvr = "Mail1.Contoso.com" Send-MailMessage -From $EmailFrom -To $EmailTo -Subject $EmailSubject -Body $EmailBody -Attachments $Attach -SMTPServer $SMTPSvr Add-Content -Path $Logfile -Value " " Add-Content -Path $LogFile -Value "------------------------------------------------" -ErrorAction Stop Add-Content -Path $Logfile -Value $("Completed: " + (Get-Date).ToString()) Add-Content -Path $LogFile -Value "------------------------------------------------" -ErrorAction Stop