I had a project few weeks ago where my client wanted to install Skype for Business 2019 but had installed Lync before and removed the server without doing proper decommissioning which kept dirty records in AD database and had to be removed manually in order to make a new clean installation of Skype for Business 2019
To do so:
There are two days of doing so, One is using ADSIEdit and ADUC to remove Computer Objects and Users related attributes and Security Groups.
I normally would prefer PowerShell but since we can demonstrate both ways for people who like to work with GUI
Starting with GUI
Removing Legacy Lync server from the AD Schema
Prerequisites
Using a domain or enterprise admin
Access to the ADSIEdit.
Goal of removing Legacy Lync server from your AD environment.
Preparing AD schema and domain for a new deployment after you improperly deleted Lync Servers without uninstalling them.
Cleaning Users’ Lync related attributes for the new deployment.
Step#1: Remove permissions
This step removes the original Lync permissions from the active director.
Open Active Directory Users and Computers
Right click on your top level domain being cleaned and select Properties
From the Properties windows, select the Security tab.
Remove all security users titled RTC*
These are usually
– RTCUniversalServerReadOnlyGroup
– RTCUniversalUserReadOnlyGroup
– RTCUniversalUniversalServices
– RTCUniversalUserAdmins
I have got a request from a client asking to find out which server(s) is using which domain admin or a highly privileged account as a service.
To find this I already wrote a powershell script that does this, Search the non standard/(Domain only users) and show the services and name of the servers where those accounts are configured on utilizing Remote powershell to do so and the use of a Domain Admin user.
You can refer to this link to see this article by clicking here
Creating the script process:
The same client wanted to also know which of those accounts did authenticate and wanted to know from which server/Computer did the request originate from and to which DC did it go.
I have started thinking of the process of doing so by again utilizing remote PowerShell to check against certain security events on AD to check which user among the Domain admin members did authenticate.
After sometime and with the help of some forums I managed to get script ready which looks in all Domain Controllers for users that are members of the Domain Admin groups who triggered an event ID 4624 and from which Computer did this request came from.
The Script :
# Get domain admin user list
$DomainAdminList = Get-ADGroupMember -Identity 'Domain Admins'
# Get all Domain Controller names
$DomainControllers = Get-ADDomainController -Filter * | Sort-Object HostName
# EventID
$EventID = '4624'
#
# Get only last 24hrs
$Date = (Get-Date).AddDays(-3)
# Limit log event search for testing as this will take a LONG time on most domains
# For normal running, this will have to be set to zero
$MaxEvent = 100
# Loop through Dcs
$DALogEvents = $DomainControllers | ForEach-Object {
$CurDC = $_.HostName
Write-Host "`nSearching $CurDC logs..."
Get-WinEvent -ComputerName $CurDC -FilterHashtable @{Logname='Security';ID=$EventID;StartTime = $Date} -MaxEvents $MaxEvent |`
Where-Object { $_.Properties[5].Value -in $DomainAdminList.SamAccountName } |`
ForEach-Object {
[pscustomobject]@{SourceIP = $_.Properties[18].Value; SamAccountName = $_.Properties[5].Value;Time = $_.TimeCreated;LogonEventLocation = $CurDC}
}
}
$DALogEvents
How to run:
The Script must be run on DC with a privileged account in order to get the write results, The default time interval is set to 3 days but you can choose to increase that.
You can also change the default group where you want to search for members by changing Domain Admin groups to something else.
In office 365 when you’re working on Exchange 2010,2013, 2016 or 2019 in a hybrid environment things might look easy but in a big enterprises where Internet security is something being taken into account very seriously. It might cause many issues that you don’t expect at all.
One of my clients whom I was doing Exchange Migration for had an issue with the Migration. The error was as follows:
Error occurs after Office 365 Exchange online connects to Exchange on-premises 2010 mailbox server
RPR05DG049-db131′, Mailbox server ‘DB3PR05MB0778.eurprd05.prod.outlook.com’
Version 15.1 (Build 466.0).RequestExpiryTimestamp : 03.04.2116 07:42:38
ObjectState : New
Troubleshooting:
To troubleshoot issues, You need to put so many things into account! The architecture of the infrastructure of where you are doing the project is very important and the need of knowing how things are working matters.
Things that could always come in mind and handy are what you will need to start your troubleshooting:
To troubleshoot the MRs, You need to know what kind of error you’re getting and to see this you can use the following powershell after you connect to Office 365 powershell.
The resultant report will reveal the error and shows you where is the exact culprit.
– Disk Latency
– Firewall Configuration (IPS/IDS)
From Exchange 2016 to 2019 or 2013 to 2016 The transient error might be related to MRSProxy or at least this is the case with me 90% of the time. To resolve this issue you will need to change the MRSProxy values on the target server and depending on the error might also be the Source server too.
SOLUTION:
===========
1. Some instability was detected in communications as well as saturation by the size of the link.
2. The procedure to increase the timeout for the service through the file MRSProxy
The Story (Finding Domain Joined Servers Services users)
If you’re wondering which of your servers are using domain joined account or a non regular account like network service or system. You will need to go through every server’s service console and check that one by one but thanks to PowerShell this job was made like a piece of cake.
Requirement
The requirement to run this script is a domain admin account since the PowerShell will require access to other servers using Remote PowerShell using Invoke command and run a Get-WMIObject script to find out those details. So in short I will write the required things for this to work
1- Logged in to Active Directory (In order for AD PowerShell module to run and find computers).
2- Domain admin account (To run the remote PowerShell on other servers and get service details)
3- Firewall for domain joined computers is open (To allow remote PowerShell to work) or have remote PowerShell enabled via GPO.
The Script will also show you the offline (inaccessible servers) and will state those servers as down as you can see in the screenshot below.
The script will also prompt you for a path to save the output. You can enter something like C:\Services.csv as soon as you type the file path and extension it’ll be opened using Notepad.
#Check servers down and get services from the responsive servers
Windows 10 has arrived finally and with it came lot of new features, and one of my favorite new features is that you can finally install applications through powershell just like Linux OS’s terminal window command (apt-get install).
Although the command is still pretty new and lack many repositories where you can find and install applications from.
There’s already some people who are working on adding sources of applications which you can test initially before Microsoft asks product companies to start making their own repositories so Powershell can trust these sites and applications.
One of the sites that are working on providing Windows 10 with repositories is https://chocolatey.org/ which provides hundreds of softwares that can be installed through PS.
To install Chocolately repository simply do the following
Open powershell as an administrator and paste the following cmdlet
As soon as you have installed chocolately, you will get a new huge list of applications that can be installed with a very simple and short cmdlet as in the below screenshots.
The good things about these cmdlets is it can be used to deploy an app for a huge number of clients by simply running the script through GPO or batch file.
I am going to install VLC and Google drive on my computer using these cmdlet …
Find-Package
Find-package -Name VLC
Install-package
Checking if the app is really installed or not?
——————————————
Find and install google drive package
Downloading
Installing
If an application doesn’t install, how to troubleshoot it?
If for instance you were trying to install a package or app and that doesn’t work or get stuck then you can navigate to the Chocolately directory and delete any package that you tried to install but were suspended for any reason.
c:\Chocolately\lib\
You can simply delete the whole directory or the file that ends with extension .nupkg and try again to install…
In migration, Powershell can be a very crucial tool to achieve success and finalize projects within deadline or even fix issues.
During the time of working with Exchange we had lots of issues with users not able to send an email to their migrated colleagues due to some issues with contacts which was caused by the Legacy Exchange DN not being migrated with the user or lost due to some wrong deletion.
Once users try to send an email to that particular user with the missing Legacy Exchange DN. The receiving Exchange server will result an error and send it to the user as NDR message explaining to them that the error is due to not finding the particular address.
The solution to this particular problem is very simple especially if it’s couple of users however to resolve the address you’ll need to google and understand the language that Exchange server users to match the original used address in the missing user’s attributes.
The below script would work accordingly with whatever situation that faced me and it became very handy to me.
How to use:
1- Copy the script to a notepad and save as convert.ps1 on Desktop
2- Run script and try to type in powershell convert-X500 then hit enter.
3- Copy and paste the address you got from the error message above.
Once you copy and paste hit enter and you’ll get the final result
Note: Make sure you remove the @domain.local in the end
Function Convert-X500{ # Define the Legacy Exchange DN here
Write-Host “”Enter your X500 Address here…”” -ForegroundColor Green -BackgroundColor Black
$X500Source = read-host
# Converts the various strings to the proper syntax
$X500 = $X500Source.Replace(“_”, “/”)
$X500 = $X500.Replace(“+20″, ” “)
$X500 = $X500.Replace(“IMCEAEX-“, “”)
$X500 = $X500.Replace(“+28”, “(“)
$X500 = $X500.Replace(“+29”, “)”)
$X500 = $X500.Replace(“+2E”, “.”)
$X500 = $X500.Replace(“+5F”, “_”)
$X500 = $X500.Replace(“@YourDC.localHere“, “”)
Write-Host X500:$X500
This article presumes that you have setup all the initial steps for the Cross Forest migration to work:
– Configure DNS resolution and trust between two AD forests.
– Create and configure Send connector between Source.com and Target.com
– Create and configure Availability service between Source.com and Target.com
– Configure Source.com as accepted domain in blue.com
– Install and configure ADMT server at the target domain Target.com
– Install and configure Password Encryption Server (PES) on the source domain Source.com
– Configure MRSProxy on Source and Target CAS Servers (Enabling MRSProxy, Increase limits..etc.).
– Configured Public Certificates between both CAS Servers or installed self signed CA certs.
In order for two Cross forest Exchange users to send an E-mail to one another before or during Cross forest migration; Each forest have to have the other forest’s users as external contacts on their Exchange environment to ease the finding of any particular user in that other organization and avoid X500 errors after the migration.
During the migration this process is critical and very important to be up to date in order to not mess users included in distribution groups before, during and after user migration from source to target forests.
For Cross forest user migration, User has to be prepared via Microsoft’s own prepare-moverequest Powershell which is included in the $Exscript directory that prepares the target user’s attributes (Before or after ADMT copy) for the migration using the Powershell script new-moverequest.
However, before that user is migrated and before doing the prepare move request the user must have their user object mail user enabled in order to get all the proper attributes for the move request to work which means the Contact has to either be deleted or lose the SMTP which is goin to be enabled on the mail enabled user.
For this process and in a big environment a tool, 3rd party or a script must be used to hasten the migration of users otherwise it would take ages and would be a very problematic process.
User Creation:
Using ADMT then Prepare-Moverequest script
Starting with the creation of target user using ADMT or by Prepare-MoveRequest Script, If ADMT is used prior to PrepareMoveRequest. The target user will have exchange attributes migrated and mail-user enabled by default but due to some incomplete or incorrect attributes the user will most probably have a corrupted mail user object that needs to be disabled and re-enabled with the proper mail address.
Using Prepare-MoveRequest before ADMT
In the case of using Prepare-Moverequest the user will be created in the target forest properly without any issue but will not have their SIDHistory copied so after creation of the user account ADMT must be used to copy user’s SIDHistory with Exchange attributes excluded.
Note:
– This method has an advantage over using ADMT first, User don’t have to create a new outlook profile in order to use their target mailbox after migration.
– You don’t have to mailenable user.
Mail Enabling User:
The first step for the migration to work is to Mail enable user in the target forest. Assuming you have a user called Tim@source.com the user gets his AD Object copied to the target forest with ADMT and user gets his UPN changed from tim@source.com to tim@target.localautomatically, still user will get his SIDhistory and the Groups he’s in if groups are migrated prior to that however, in some rare cases that I have seen while doing this kind of project the SIDHistory might not get copied and you might not notice that unless you take a very close look at the log that ADMT is generating for you, In the script I am attaching below and prior to preparing the user for migration I added a script to bulk check user list for SIDHistory. The script below will disable mailuser that’s migrated with ADMT and show you their SIDHistory attribute in order to double check before you migrate their mailbox.
$Users = import-csv -path “C:\List\List1.csv”
foreach ($User in $Users)
{
$Identity = $User.Alias
$UIdentity = $User.Sam
$Mail = $User.Proxy
$NProxy = $User.NewProxy
#Before Migration, Show if user has SIDHistory or Not, If not don’t migrate User
Enable-Mailuser –Identity Tim –ExternalAddresstim@domain.com
In this case user will be ready for the prepare moverequest script to work and get his source Exchange attributes to be copied to the target one.
Prepare-MoveRequest for Single mailbox:
The Prepare-Moverequest powershell is pretty easy to use for a single user and all you need is to enter target and Remote credentials in a variable to use it with the command.
Once you use the script it’ll copy the source user and their Exchange attributes including Proxy Addresses, it’ll convert the LegacyExchangeDN into X500 address in the target user’s mailbox object so users in the source forest wont get any cache issue reaching to the migrated user and will set other attributes like Displayname, MailNickName..etc like in the screenshot below.
Once the list is ready and you run the powershell script the target CAS server would connect to the source CAS and start migration as in the following screenshot.
Once users migration is finished, On the source forest user will be converted to MailUser so non-migrated users in the source forest will still be able to send emails to this user however, The Groups on target forest must be manually maintained and updated with users that are being migrated.
– Contacts Issue
In the target forest those two migrated users were already contacts there prior to migrating them and thus Target forest users who have sent those two users email have the LegacyExchangeDN Address of those contacts cached in their Outlook in X500 format which will create an issue if those contacts are deleted without exporting their LegacyExchangeDN and add it to the migrated users’s ProxyAddress Attributes.
Prior to deleting those contacts, From the Target forest I have exported their info to CSV with the following attributes.
Name, Alias, PrimarySMTPAddress and LegacyExchangeDN Attribute using the following powershell script
The PowerShell will export contacts in the following format and in order to import them you’ll need to bulk edit the file using Notepad or Notepad++
In notepad replace “/o= with X500:/o=
and Replace all “ with nothing
After you save the file in the target forest, Only in the condition of migrating Source users to the target forest use the following script to Import those users’ LegacyExchangeDN as X500 to their migrated Mailbox objects.
Sometimes while we do Exchange projects in big environments where there more than 10 or 15 servers we need to quickly get a particular server’s hostname or IP.
I created a simple PowerShell script that does the work for you
#Get all mailbox Exchange Servers IP address remotely
#Import Exchange Management Shell if ran from PowerShell
In an Exchange Crossforest migration the distribution groups can be a very painful operation that would cause loss of time, lots of issues and continues headache if not solved within a timely manner.
The migration can be a long boring process that needs to be as accurate as possible to avoid any issue related to members in the group or/and Group’s Primary SMTP details.
While doing a Crossforest migration I came through through this headache and tried to seek a script that would satisfy my migration’s requirements but only thing I found is the exportPowershell made by Satheshwaran Manoharan.
Export Process:
The script exports all groups and their members from the source forest, but to import there’s no option and I had to write my own script.
To make use of this script first make sure you that you have migrated the Groups with ADMT in the recommended order otherwise the migration would be problematic.
First: Universal Groups
Second: Global Groups
Third: Domain Local Groups
Once groups are migrated to the target forest you can check how they look like through Exchange management shell and whether they have members added or SMTP address set.
After I checked it apparently shows that group is empty and has no Primary SMTP address associated with it.
Import Process:
In order to add members during the migration since this is a Hybrid/Coexistence migration not cutover, It took time to migrate users and therefore I have to add non-migrated users in target forest as External Contacts to the Distribution Groups and add migrated users as Mailbox users.
Then after adding the users I have to setup Primary SMTP address for the groups according to the exported CSV file from the Source Forest.
To Import users, I had to setup a CSV file with the following format:
In this format, the Display name, Alias, RecipientType and PrimarySMTPAddress belong to the User object that’s included in the group meanwhile, The Dgroup is the Distribution group’s Alias and DGSMTP is the Group’s Primary SMTP address.
The following script imports groups members to their relative groups
Since distribution groups are mostly imported without Primary SMTP address through ADMT then we’ll have to also make sure that we fix this for our groups, but what if the destination forest has similar groups or the SMTP is used already ? In order to avoid any mistake when associating the Primary SMTP address I have created a script that would check distribution groups with null value in their primary SMTP Address and copy the SMTP address to these groups avoiding any overwrite or change of the destination Distribution groups.
Write-Host Group $GroupAlias has $GroupSMTP Setup as primary SMTP -ForegroundColor Green -BackgroundColor Black }}
The script will check if the groups has primary SMTP matches the one in the CSV file, if it doesn’t it’ll setup the primary SMTP address for that group with green color like in the below screenshot
You can use this script with the same CSV file that you will use for adding members to the groups too , If groups SMTP exists already you’ll get the following error
Note:
Attached below, You can find the new version of the powershell and the CSV along with it.
This will export a file called “ExportLicenseUsage.csv” to your C root drive. you can open this file with Microsoft Excel and find out all the useful information that you’re looking for.
Hope this helps
Testing Office 365 SMTP relay
In order to test Office 365 SMTP relay you will have to create a user with an Exchange online license. After the email is activated for this user you can test this user for relay with the following powershell.
First connect to Microsoft Online service with this user that you’ll be using for relaying.
$msolcred = Get-Credential
Next edit the following powershell with the user’s e-mail and the recipient’s too
This test is known as Client SMTP submission you can also use a different method for multiple devices where you can configure them all to point to a single server (IIS) in a method known as IIS for relay with Office 365 however, all the methods what involve office 365 (Only) for relay will require a user with Exchange online license assigned to it.
If you have configured Hybrid integration between Exchange 2010/2013 with Office 365 using dirSnyc or Azure active directory sync tool and then stopped the synchronization. The accepted domains and additional domains will be removed from the user’s Attributes on the cloud and in order to add these accepted domains again to all of the Office 365 users..
First we’ll have to connect to Exchange online with the following powershell tool. so Launch Azure powershell as Admin and copy the following line by line.