When you post code, sample data, console output or error messages please format it as code using the preformatted text button ( </> ). Simply place your cursor on an empty line, click the button and paste your code.
I don’t think your code is functional as its copied/pasted above. for example when piping you are using $. (missing the underscore). Same thing with a lot of the parts of the custom object.
I’m not familiar with ‘extension_3949a35e7317477db4e45dd98d717482_msDS_PhoneticCompanyName’ but It looks like you are running Get-AzureADUserExtension twice, once to get the ‘createdDateTime’ property and once to get the value of that extension. Why not run it once and just access the properties (reference them in the hashtable you are returning)?
You should only need to run it once $ADUserExtension = Get-AzureADUserextension -ObjectId $_.ObjectId and then that variable should have it for use in your hashtable, you just need to access the properties like you are already doing That would eliminate a call for every single guest user you are looping through, in theory nearly doubling the speed of that section.
Lastly, How many guest users are you looping through in this state? Have you determined how many and how long it takes to loop through each user? Sometimes I’ll add some things to keep track of loops or i’ll turn a subset of 10 users or even 50 users to get a feel for how long it’s taking. You can do that by wrapping a command in Measure-Command