En Dag i Stockholm Del Två

So, today started off with breakfast in the hotel, which is where the Kalles Caviar photo that finished the last post originated from.

After breakfast, it was a quick shower, realising that I had left almost all of my toiletries at the hotel in Linköping (womp-womp).

First was to go to the Riksdag area, again. The Riksdag, itself, takes up almost half of the island called Helgeandsholmen and the area of the city is called Gamla Stan (literally, the old town).

This is also where the Stockholms Medeltidsmuseum (literally, Stockholm’s Mideival Times Museum) is located.

It’s a museum and it’s free, so of course I went through it! 😊

After that, it was time to get up close and personal with the Riksdag. Apparently, you need to have pre-booked tours; so, guess what I want to do the next go around?

Then, some more walking because why not?

Then, I stumbled upon another church, S:t Jacobs Kyrka. I think that the church is in the Norrmalm area of the city. Yes, it was a bit of a walk.

Just behind S:t Jacobs Kyrka is Kungsträdgården (literally, king’s tree garden), a fairly large park that also hosts an fairly large ice skating arena in winter.

After that, it was time to grab a bite to eat and I figured that it was time to see what all of the fuss about Max was.

Turns out that they’re pretty environmentally conscious and friendly, so I can see what all of the fuss was about.

The fries were worth passing on but the grilled halloumi nacho burger and the cloud berry shake were worth it.

After that, it was to the hotel to pick up my bag and head to Arlanda via the Arlanda Express. A train that goes 180km/h? Yes, please.

Hopped on the plane back to Dublin.

Back in Dublin, the passport control line was brutal. To give you an idea, the plane landed around 19:00. I didn’t get out of passport control until around 20:00.

Fun-filled facts: You have to have your GNIB card and cannot use your phone when talking to GARDAÍ. Either could be a €3000 fine. Not that I forgot my card or used my phone but I overheard the threats (?), so just trying to help you out. The More You Know™️

Now, I’m back in Dublin and I have to go right back to Sweden, soon, so expect a new post before the month is through. 😊

Until then, dear reader, as Mork used say, “Nanu nanu!”

En Dag i Stockholm.

So, a day in Stockholm was between yesterday and today. Well, if you want to hyper literal with it, it was less than a full day but who’s counting ticks, yeah?

Anyway, I got a room with a view at Radisson Blu Waterfront (in the Norrmalm area of Stockholm …or is it really Kungsholmen?). When they say, “with a view”, they aren’t lying.

That church-like tower off to the right is the Stadshuset (literally, house of the city), also known to us in English as city hall. You can tour the Stadshuset and I highly suggest you do so, if you ever get the chance. I, myself, have been twice and it’s a rather lovely building.

Any visit to Stockholm isn’t complete without a visit to Riksdagen.

The Riksdag is where the magic of the Swedish government happens (not to be outdone by knugen, to be sure) and, currently, they’re trying to form a coalition to form a complete government. There’s rumours that Annie Lööf will become the new stasminister, which I hope turn out to be true.

Next up was S:ta Clara kyrka. Unlike the many castles of Europe, I cannot seem to get tired of going into churches. Perhaps, there’s something to them or the fact the overall exposure time to churches is far less because their footprint is much smaller. Who knows…

S:ta Clara kyrka was nice but it was being used at the time that I had popped-in, so I snapped a photo or two and ducked out of there.

I then headed over to Drottninggatan (literally, Queen Street), hoping to go to Dressman before it got too late in the day.

I had duplicitous reasons for going to Dressman. The first was that I was looking for the cashier that had flirted with me in Swedish years before (I know, I know…) and the second was that I was running out of muscle shirts (always layer in cold environments).

After navigating the whole affair, mostly in Swedish, I was off to snag something to eat.

Drottninghof. I can not recommend it enough. Almost every time that I’ve been in Stockholm and had the time to afford a visit to this restaurant, I’ve always gone without fail.

This time, my meal consisted of toast skagen (literally, shrimp toast), regnbågsfilé (literally, rainbow fillet), and the dessert of the day.

After that, it was a bit more walking around before going back to the hotel to sleep and catching my flight today.

Did I mention the view of the hotel room? I’m not trying to show off, more like I’m trying to convince you to treat yourself, if ever you should go.

Finally, if you’ve ever been to Sweden, you’re all too familiar with the Kalles phenomenon. If you haven’t, let me explain: Kalles is a brand of caviar and the caviar, itself, is packaged and sold in tubes. When people talk about it, it’s almost always followed by the word caviar, Kalles Caviar. It’s a thing here, kind of like snus, but the only difference is that I’ve seen people use snus.

So, that’s all there is from a very brief time in Stockholm. I’ll probably tour the city a bit more before my flight today but won’t get a chance to update the blog until late tonight or tomorrow. Better to just assume this is the end of it, at the moment.

Until next time, dear reader, as the Vulcans say, “Live long and prosper.”

En Promenad runt Linköping

So, for Saturday and Sunday, I stuck mainly around the Linköping (pronounced: len-show-ping) area. It’s a decent walk about in autumn (yes, I’m trying to drop “fall” from my vocabulary for any seasonal references) and walking is good for you, or so I hear.

First up was the Trädgårdsföringen park (not to be confused with the park of the same name in Göteborg). I’ve taken plenty of photos of the park in the past. So, to save you from that mundane banality of seeing a panel of photos of it, again, here’s only a few. 🙂

After that, it was necessary to visit Linköpings Domkyrka (pronounced: dum-sheeyir-kah, said very quickly). It’s a beauty of a church and the acoustics of it are astounding, to the say the least.

After the domkyrka, it was a bit more of walking around town, killing time before bed.

The reason why it needed to be an early night for me is because I was off to Stockholm on the morrow. There won’t be anything on Stockholm in the next post.

Until then, dear reader, have a good one and – in the immortal words of Bill S. Preston, Esq. and Ted Theodore Logan, “Be excellent to each other!”

En Dag i Göteborg

I took an early morning bus (Nettbuss, a.k.a. bus4you) from Linköping to Göteborg. Early morning, for context, is only 7am local time (CEST) but that meant I had to interrupt my beauty sleep to catch it and those of you who know me know that I could use as much of that as plausibly possible.

The bus itself was pretty comfortable. If I could give you a comparative, it was like the AirCoach (in Dublin) meets the double-decker bus.

The views were pretty amazing, I have to say, but – then again – maybe I’m preferential to the Swedish countryside.

The bus took about 4 hours to get to Göteborg and it wasn’t too bad of a trip; albeit, the nicotine cravings started kicking in when we got out to lake country…

The bus takes you right to Göteborg Central Station, which is super convenient, as the tram lines run right outside the front doors (veritably). The inside of the station is pretty amazeballs and it’s something worth seeing, I think, if you ever get the chance.

After a quick lunch meeting, it was time to be off walking around the town. The pictures don’t do the city justice, to be sure, but they’re all I have to show you this city’s majesty.

After a brief walk about, it was time to do one of my favourite things: Visit a museum. In this case, it was Göteborgs Stadsmuseum. It cost a few quid (60SEK, which is about €6) and is cheap enough that it’s worthwhile. After all, there are three floors to the museum, itself.

Pictures of a museum? Of course there’s pictures!

And, then? No “and then”! And, then…? Well, and, then, it was time for more walking about the city.

Whilst walking about, I found my next favourite thing: A park. Nordic parks, in my opinion (I’m very opinionated, aren’t I?), are the best in the world. The principle reason, for me, is because most parks are open to the public 24×7, because the public pays for them and the public, in turn, gets to use them any time that they want.

This park, specifically, was called “Trädgårdsföreningen” and is located in the centre of Göteborg. It has everything you’d expect at a large-sized park, even a botanical garden (that’s also free).

After the park (but still, technically, within it), I grabbed a bit of Earl Gray and had a piece of blueberry cheesecake. This would, normally, be a very pedestrian thing to do; an uneventful event in the normal happenstance of life. Yet, during my afternoon tea, I was joined by a brave little fellow, with whom I ended-up sharing some of my cheesecake (more specifically, the crust) with.

Sadly, I had bought my savouries shortly before they closed but worry not: The little bird had more than a fair share of that cheesecake crust.

Then, it was off to dally about the town, again, until it was time to take the (very late) train home – which is where I’m writing this from. I love living in the future.

Whilst I was about town, I found something that I thought my roommate might enjoy. Wouldn’t you know it: He has one with 20 ports. Living in the future, he is.

I also found an apt quote around town that I think I will just close this off with. It’s not the best quote ever, in the history of ever, but it’s quite fitting.

Until next time. 🙂

Jag är i Sverige igen.

So, as the title infers, I’m back in Sweden again. I took a plane from Dublin to Stockholm and then the train from Stockholm to Linköping (pronounced “len-shōping”).

Back in Linköping, I’m in my regular hotel and life is back into the Swedish modality of things.

For example, in the style of “treat yourself” (see Parks and Rec), I took myself to a semi-fancy dinner at Gula Huset (literally, the golden [or yellow] house) and then a movie, Night School. Can’t say that I recommend the movie but a comedy was definitely in order, what with everything going on.

After the movie, it was stroll around town to take in the visages and off to bed to catch an early bus. The destination? Göteborg (or “Gothenburg” in English).

The Göteborg adventures are soon (still on the way there), so stay posted. 😊

Netlogon: Cross-Forest Delayed Authentication Requests Cause Subsequent (and Continuous) Authentication Failures

NOTE: This post – drafted, composed, written, and published by me – originally appeared on https://blogs.technet.microsoft.com/johnbai and is potentially (c) Microsoft.

One of the longest debugging experiences I’ve ever had to debug, so far, in Exchange was a code bug that exists in the Netlogon code. I hope to cover what this bug was, how it manifested, and the fix that was implemented by the Windows developer to resolve the issue. So, this is going to be a long one….

Picture (Worth 1,000 Words)

Basics
Netlogon sessions use RPC (remote-procedure call) sessions with domain controllers to communicate authentication requests to domains. In the cases of cross-forest authentication requests, regardless of the type of trust created (e.g.: one-way transitive, one-way intransitive, etc.), the cross-forest authentication requests are forwarded (via the trust) to the responsible domain. In this case, the responsible domains exist in the customer’s on-premises environments.

So, in the above example, you’ll see that the client communicates with the Café server. During authentication, the Café passes the request to the managed domain controller. The managed domain controller will see the trust and communicate the authentication request across the trust and receive only an NT status response back for the request from the customer’s domain controllers.

When Repro Cometh
The condition that causes repro to start occurring is when the local domain controller (in this case, the managed domain controller in the illustration above) is awaiting a response from the customer’s domain controller for an authentication request. In the authentication pipeline, if this request times-out, it’s considered a re-triable exception – which is important for later. Because this exception is retriable, a the Café server doesn’t consider that the authentication request has failed. Also, during this same time, the Café server may build a new Netlogon session with a new domain controller, which is where our problem begins to surface.

The Netlogon code has a single object reference for the domain controller’s name for the current Netlogon session on the current RPC session it should be using. (If you’re familiar with native/unmanaged code, the reference to the domain controller’s name is a pointer to a wchar_t value.) But remember: We’ve not disposed of the previous session because it’s considered re-triable. So, since Netlogon can only communicate on one session per one RPC channel, we now have two Netlogon sessions with two RPC channels. The non-disposed of session is in red and the new session is in green in the illustration above.

The Bug
The bug is that all subsequent authentication requests traverse the red authentication path but use the domain controller’s name that was obtained from the creation of the green authentication path (the domain controller’s name is supplied in the authentication request as is defined in the specifications). This causes all subsequent authentication requests to fail, no matter the destination forest, because the domain controller receives a request that it should not process.

Verifying Repro
The best way to verify the repro of this bug is to look at the Netlogon logs. If you see 0xc0000122 (STATUS_INVALID_COMPUTER_NAME), then you’ve hit repro of this specific condition. In Exchange, this will bubble-up via the app pool in IIS as a 401 Unauthorised (which makes chasing the bug a bit more complicated).

The Fix
Windows dev determined that the best way to fix this was to tear down both the Netlogon and RPC sessions, regardless of current status. This has been verified as working in RS3 builds of Windows 10/Server 2016 and is currently being tested in RS1 builds of Windows 10/Server 2016.

Windows 10: Removing Groove, Facebook, and Other Unwanted Apps

NOTE: This post – drafted, composed, written, and published by me – originally appeared on https://blogs.technet.microsoft.com/johnbai and is potentially (c) Microsoft.

A few months ago, someone very dear to me asked why they couldn’t remove unwanted apps from Windows 10 – mainly over privacy and right to decline concerns. I took it up as a sort of personal challenge to find a way to rid these apps for other people, as well, whilst I was attempting to figure out how to do this for them specifically. So, I give you the result – which is still a work in progress.


function Remove-UnwantedApps
{
# Attempt to remove Facebook (if it exists)
$facebookPkg = Get-AppxPackage -AllUsers | Where{$_.Name -like '*Facebook*'}
if($facebookPkg -ne $null)
{
Remove-AppxPackage $facebookPkg.PackageFullName -Confirm:$FALSE
}

# Attempt to remove Groove Music
$grooveMusicPkg = Get-AppxPackage -AllUsers | Where{$_.PackageFullName -ilike ‘*ZuneMusic*’}
if($grooveMusicPkg -ne $null)
{
Remove-AppxPackage $grooveMusicPkg.PackageFullName -Confirm:$FALSE
}

# Attempt to remove Groove Video
$grooveVideoPkg = Get-AppxPackage -AllUsers | Where{$_.Name -like ‘*ZuneVideo*’}
if($grooveVideoPkg -ne $null)
{
Remove-AppxPackage $grooveVideoPkg.PackageFullName -Confirm:$FALSE
}

# Attempt to remove all things XBox.
$xboxPkgs = Get-AppxPackage -AllUsers | Where{$_.Name -like ‘*Xbox*’}
foreach($xboxPkg in $xboxPkgs)
{
Remove-AppxPackage $xboxPkg.PackageFullName -Confirm:$FALSE
}

# Attempt to remove the Advertising apps
$advertPkgs = Get-AppxPackage -AllUsers | Where{$_.Name -like ‘*Microsoft.Advertising*’}
foreach($advertPkg in $advertPkgs)
{
Remove-AppxPackage $advertPkg.PackageFullName -Confirm:$FALSE
}

# Attempt to remove the Bing apps
$bingPkgs = Get-AppxPackage -AllUsers | Where{$_.Name -like ‘*Microsoft.Bing*’}
foreach($bingPkg in $bingPkgs)
{
Remove-AppxPackage $bingPkg.PackageFullName -Confirm:$FALSE
}

# Attempt to remove the Messaging package
$msgPkg = Get-AppxPackage -AllUsers | Where{$_.Name -like ‘*Microsoft.Messaging*’}
Remove-AppxPackage $msgPkg.PackageFullName -Confirm:$FALSE

# Attempt to remove Windows Store dependent packages
$storeDepPkgs = Get-AppxPackage -AllUsers | Where{$_.Dependencies -ilike ‘*Store*’ -and $_.Name -inotlike ‘*WindowsStore*’}
foreach($sdPkg in $storeDepPkgs)
{
Remove-AppxPackage $sdPkg.PackageFullName -Confirm:$FALSE
}

# Attempt to remove Windows Store package
$storePkg = Get-AppxPackage -AllUsers | Where{$_.Name -ilike ‘*WindowsStore*’}
if($storePkg -ne $null)
{
Remove-AppxPackage $storePkg.PackageFullName -Confirm:$FALSE
}

# Attempt to disable Cortana via the Registry
$searchRegistyPath = Test-Path “HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search”
if($searchRegistyPath -eq $FALSE)
{
# Create the Windows Search Registry Key
New-Item -Path “HKLM:\SOFTWARE\Policies\Microsoft\Windows” -Name “Windows Search”

# Create the AllowCortana Registry Key
New-Item -Path “HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search” -Name “AllowCortana”

# Disable Cortana via the path
Set-Item -Path “HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search\AllowCortana” -Value 0
}
else
{
# Let’s ensure the child item exists.
$allowCortanaRegistryPath = Test-Path “HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search\AllowCortana”
if($allowCortanaRegistryPath -eq $FALSE)
{
# Create the AllowCortana Registry Key
New-Item -Path “HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search” -Name “AllowCortana”
}

# Disable Cortana via the path
Set-Item -Path “HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search\AllowCortana” -Value 0
}

# Stop the Windows Search Service
$searchService = Get-Service WSearch
Stop-Service -InputObject $searchService -Force

# Attempt to remove Cortana via the App Package
$cortanaPkg = Get-AppxPackage -AllUsers | Where{$_.PackageFullName -ilike ‘*Cort*’}
foreach($cPkg in $cortanaPkg)
{
Remove-AppxPackage $cPkg.PackageFullName -Confirm:$FALSE
}

# Restart the system, so the registy changes take effect in the Windows Search Service’s OnStart() method body.
}

Please note that this has only been tested on a local machine and, so far, validates. This can produce undesired results, such as not being able to install packages from the Windows Store in the future, since the Windows Store is removed via this script. YOU HAVE BEEN WARNED.

To use: Copy the red text into an Administrative session in PowerShell (right-click the PowerShell icon –> Run as Administrator). Run ‘Remove-UnwantedApps’ at the new line, after the red code lines from above have been pasted into the PowerShell session. Restart your machine. Profit.

O365 and Exchange 2016/Exchange 2013: Understanding the UserPhoto API

NOTE: This post – drafted, composed, written, and published by me – originally appeared on https://blogs.technet.microsoft.com/johnbai and is potentially (c) Microsoft.

We recently had an issue for an Enterprise Cloud customer, in which the photo was not rendering for the user – which was uploaded to AD (and synced over via MMSSPP to the managed environment). It was sussed that the issue was customer-caused, as the customer was modifying the photo via the PowerShell commandlets and had deleted the photo.

Despite the fact that the customer had disabled the OWA functionality to change the user photo in OWA, the customer was using the PowerShell commandlets to modify this object, which is the same interface/commands that OWA utilises behind the scenes.

To explain this behaviour in further detail: When you delete a photo from a mailbox in Exchange (or Exchange Online), it changes the UserPhotoCacheId MAPI property value to ‘0’ and this signifies to the UserPhoto API that the photo has been deleted. When this occurs, we will not fall-back to the ADPhotoHandler to call the photo from AD because the user explicitly deleted the photo. This scenario is by-design of the UserPhoto API.

To rectify this behaviour, clear the MAPI property by running ‘Remove-UserPhoto -ClearMailboxPhotoRecord’.

Keep in mind, as well, that Exchange uses a CachingPhotoHandler and that the photos stored on disk have a TTL of 7 days.

I have written a script to help ascertain the MAPI properties on a given mailbox, obtain the location of the cached photos on disk, and obtain the IPM.UserPhoto item from the user’s mailbox (on-premises):


function Get-UserPhotoDataOnPremises
{
param([string]$User)
Write-Warning -Message "The source of our powers comes from a Cracker Jack™ box, so this will take a minute. Please be patient..."
if([System.String]::IsNullOrEmpty($User))
{
throw [System.NullReferenceException]::new("The user value cannot be null.")
}
else
{
$mbx = Get-Mailbox $User
}

[string]$scriptPath = $env:ExchangeInstallPath + “Scripts\ManagedStoreDiagnosticFunctions.ps1”
# Dot-load script into function
. $scriptPath

[GUID]$guid = $mbx.ExchangeGuid.Guid
[int]$mbxNumber = Get-StoreQuery -Database $mbx.Database -Query “SELECT MailboxNumber FROM Mailbox WHERE MailboxGuid=’$guid'” | Select -ExpandProperty MailboxNumber
[string]$folderId = Get-StoreQuery -Database $mbx.Database -Query “SELECT FolderId FROM Folder WHERE MailboxNumber=’$mbxNumber’ AND DisplayName=’$([System.String]::Empty)'” | Select -ExpandProperty FolderId
$global:item = Get-StoreQuery -Database $mbx.Database -Query “SELECT * FROM Message WHERE MailboxNumber=’$mbxNumber’ AND FolderId=’$folderId’ AND MessageClass=’IPM.UserPhoto'” -Unlimited
[string]$previewPhotoCachedId = (Get-StoreQuery -Database $mbx.Database -Query “SELECT UserPhotoPreviewCacheId FROM Mailbox WHERE MailboxNumber=’$mbxNumber'” -Unlimited).p7C1B0003
[string]$photoCacheId = (Get-StoreQuery -Database $mbx.Database -Query “SELECT UserPhotoCacheId FROM Mailbox WHERE MailboxNumber=’$mbxNumber'” -Unlimited).p7C1A0003

# Obtain files on disk (if any)
$smtp = $mbx.WindowsEmailAddress.Address
$smtpAtIndex = $smtp.IndexOf(“@”)
$smtpAtIndexPlusOne = $smtpAtIndex + 1
$smtpDotIndex = $smtp.LastIndexOf(“.”)
$smtpNewLength = $smtpDotIndex – $smtpAtIndexPlusOne
$subString = $smtp.Substring($smtpAtIndexPlusOne, $smtpNewLength)
$queryString = “_$subString”
$preSubString = $smtp.Substring(0, $smtpAtIndex)
$srvr = Get-MailboxDatabaseCopyStatus $mbx.Database.Name | Where{$_.Status -contains ‘Mounted’} | Select -ExpandProperty MailboxServer
$folderPathUnc = “\\$($srvr)\” + $env:ExchangeInstallPath.Replace(“:”, “$”) + “\ClientAccess\photos”
$obj = Get-ChildItem -Path $folderPathUnc -Filter “*$($queryString)*”
$folderPath = $obj.FullName
$obj2 = Get-ChildItem -Path $folderPath
$fullPaths = @()
foreach($o in $obj2)
{
$picObj = Get-ChildItem -Path $o.FullName -Filter “*$($preSubString)*”
$fullPaths += New-Object PSobject -Property @{
Name=$picObj.Name
Size=$picObj.Length
Location=$picObj.FullName
}
}

if([System.String]::IsNullOrEmpty($item.MessageId) -eq $FALSE)
{
$string = “IPM.UserPhoto item found in user’s mailbox. The object can be found in ” + “$” + “item”
Write-Host $string
}
if($previewPhotoCachedId)
{
Write-Host “UserPhotoPreviewCacheId found: $previewPhotoCachedId”
}
if($photoCacheId)
{
Write-Host “UserPhotoCacheId found: $photoCacheId”
}
Write-Host -ForegroundColor Green “Photo files found on disk on $($srvr) for $($smtp):”
$fullPaths | FL
}

Here’s an example as run from my lab:


[PS] E:\>Get-UserPhotoDataOnPremises -User Administrator
WARNING: The source of our powers comes from a Cracker Jack™ box, so this will take a minute. Please be patient...
IPM.UserPhoto item found in user's mailbox. The object can be found in $item
UserPhotoPreviewCacheId found: -88512737
UserPhotoCacheId found: -88512737
Photo files found on disk on [REDACTED] for [email protected]:

Name : _Administrator-8EEDD78A2D804372C17E9FABD151BCD5.jpg
Location : \\[REDACTED]\E$\exchsrvr\ClientAccess\photos\_contoso.se-BBED6250E228D4F38F5F19BF4F1A6823\HR648x648\_Administrator-8EEDD78A2D804372C17E9FABD151BCD5.jpg
Size : 79838

Name : _Administrator-8EEDD78A2D804372C17E9FABD151BCD5.jpg
Location : \\[REDACTED]\E$\exchsrvr\ClientAccess\photos\_contoso.se-BBED6250E228D4F38F5F19BF4F1A6823\HR96x96\_Administrator-8EEDD78A2D804372C17E9FABD151BCD5.jpg
Size : 3224

I’ve also written a method in C# to test obtain the photo via the EWS GetUserPhoto REST method:


///
/// Creates an EWS request for a user's photo at each standard size.
///

/// Vanity name of your endpoint.
/// Smtp Address of the user you’re targeting.
private static void GetPhotos(string vanityName, string username)
{
int[] sizeInts = new[] { 48, 64, 96, 120, 240, 360, 432, 504, 648 };
Parallel.ForEach(sizeInts, delegate (int i)
{
Uri targetUri = new Uri($”https://{vanityName}/EWS/Exchange.asmx/s/GetUserPhoto?email={username}&size=HR{i}x{i}”);
Console.WriteLine($”Targeting: {targetUri}”);
try
{
HttpWebRequest newWebRequest = (HttpWebRequest)WebRequest.Create(targetUri);
newWebRequest.UserAgent = “Enterprise Cloud UserPhoto EWS Client”;
newWebRequest.Credentials = new NetworkCredential(“[UserName]”, “[PassWord]”);
using (HttpWebResponse newWebResponse = (HttpWebResponse)newWebRequest.GetResponse())
{
if (newWebResponse.StatusCode == HttpStatusCode.OK)
{
Console.WriteLine($”Size {i} photo found.”);
}
else if(newWebResponse.StatusCode == HttpStatusCode.NotFound)
{
Console.WriteLine($”Photo API states that a photo cannot be found for the size {i}x{i}”);
}
else
{
Console.WriteLine($”Unexpected http response received: {newWebResponse.StatusCode}”);
}
}

}
catch (Exception e)
{
Console.WriteLine(e.Message);
}

});
}

If you run into any problems with the script or have any questions or concerns around the UserPhoto API, feel free to let know! 🙂

2017 Project: Documented Code Samples

NOTE: This post – drafted, composed, written, and published by me – originally appeared on https://blogs.technet.microsoft.com/johnbai and is potentially (c) Microsoft.

In an effort to empower more people across the planet to learn, but for it not to be an arduous journey in doing so, I’ve started heavily commenting code so that people can learn from it. This will be the first of many code ventures that I attempt to do and then share with comments, so that others can learn from it. The reason for the commenting with the links is because I, myself, have often wondered what ‘x’ does or why ‘y’ may have been used; so, in typical learning fashion, I set off to my favourite search engine and undertake to read more on the class, method, property, etc. To save someone the time and heartache of doing that, I include the .NET MSDN/TechNet documentation with the code – to assist self-driven learning.

In this first of series, DownloadBingImage, Wes (Mills) was making a PowerShell script to download the Bing Search Image. Kevin (Miller) asked him if it was in a service or task and Wes replied that it was a task, so I challenged myself to write it into a Windows Service. I rose to the occasion – mostly, out of self-interest in Windows Services, as it would help me to learn more about coding fundamentals in this area.

And, so, a few months of trial and error and I have a working version of the service installed on my local machine and it downloads the image[s]. This same exact code is what I’m sharing with you.

You can find a copy of the code with in-line comments and links to the classes/methods here. If you want to start at the main service entry point, look here.

It should go without saying that I am not a professional developer (albeit, my role does require understanding all aspects of the SDLC), so if you have comments or are confused as to why I did something a particular way (from a professional developer’s perspective) and it doesn’t quite make sense, that’s why: I’m more of a hobbyist than what others would call a “professional”, at this point.

I hope that this helps at least one person on their journey towards software development. If it’s just one, then the effort was worth it. 🙂

Happy Coding!

EXODSnapIn: Alpha Release

NOTE: This post – drafted, composed, written, and published by me – originally appeared on https://blogs.technet.microsoft.com/johnbai and is potentially (c) Microsoft.

I wanted to write a post about the project I’ve been working on since circa December 2015. It’s approximately 1200 lines of code and 18 commands – all varying in intended design/function. The assembly is meant to be imported into your Exchange Management Shell (EMS) via importing the module: Import-Module .\EXODSnapIn.dll -Verbose The intended audience is any Exchange Administrator with access rights to ‘Update-MailboxDatabaseCopy’ at the most/highest.

It should be important to note that some of these commands will work outside of EMS (e.g.: Get-WhoIsInformation) and do not, implicitly, require importation into EMS.

To add the assembly as a default into PowerShell, browse to C:\Users\your user name\Documents\WindowsPowerShell and edit (or create it if it does not exist) the Microsoft.PowerShell_profile.ps1 file to include Import-Module .\EXODSnapIn.dll -Verbose.

Get-AdObjectProperties
This command uses the System.DirectoryServices.Protocols library to search the current domain context for an object by both the property and property value supplied. In order to prevent overhead, I only return the processed collection of attributes for the first object returned.

$obj = Get-AdObjectProperties -Property mail -PropertyValue [email protected]
$obj.whenCreated
12/20/2011 18:54:22

Get-InternetExchangeStatus
This command will present a new browser (or tab) showing the network graph of the Internet Exchange site specified (via switch parameter). Unfortunately, not all IX have their network status listed publicly; so, if you’re looking for the status for San Antonio, for example, you will not be able to find it with this command.

Get-InternetExchangeStatus -Amsterdam -Dublin -Frankfurt -Hamburg -London -Madrid -Munich

Get-WhoisInformation
This command takes an IPAddress (or array of them) and queries ARIN for the owner. If the owner is found to be RIPE, the command makes a second query to RIPE for the data before displaying it. (APNIC and LACNIC will be coming in the future, assuming they make REST endpoints available.)

Get-WhoisInformation -IpAddresses "158.198.48.206", "4.4.2.2", "88.66.77.11", "1.1.1.1", "23.103.0.0", "80.0.0.0", "157.100.0.0", "8.8.8.8" | FT -AutoSize

Name                   OriginAs StartAddress EndAddress
----                   -------- ------------ ----------
APNIC-ERX-158-198-0-0           158.198.0.0  158.215.255.255
LVLT-STATIC-4-4-16              4.4.0.0      4.4.255.255
ARCOR-DSL-NET15                 88.64.208.0  88.66.79.255
APNIC-1                         1.0.0.0      1.255.255.255
MSFT                   AS8075   23.96.0.0    23.103.255.255
UK-NTLI-20010425                80.0.0.0     80.7.255.255
LACNIC-ERX-157-100-0-0          157.100.0.0  157.100.255.255
LVLT-GOGL-8-8-8                 8.8.8.0      8.8.8.255

Repair-MailboxSecurityDescriptor
This command queries the mailbox security descriptor for a specific user specified, removes the user’s ACE, and re-applies all permissions on the object (without the removed ACE).

Repair-MailboxSecurityDescriptor -Mailbox [email protected] -User "Contoso\Someone2"
WARNING: The ACE for Contoso\Someone2 on [email protected] was not found. Please validate your input[s].

Get-ExchangeProcessDiagnostics
This command parses the XML from the original diagnostics command to only give you the process-related information you may be concerned with, when troubleshooting an issue related to the process (e.g.: working set, mem usage, lifetime, etc.).

Get-ExchangeProcessDiagnostics -ProcessName MSExchangeMailboxAssistants -Server $Server | FT -AutoSize

ProcessName                 LifeTime            ThreadCount HandleCount WorkingSet
-----------                 --------            ----------- ----------- ----------
MSExchangeMailboxAssistants 23.03:50:14.4678669         167        4315 570.8 MB (598,523,904 bytes)

Get-DeletionEventsForMailbox
This command queries for all of the Database Events related to deletions performed on the user’s mailbox.

Get-DeletionEventsForMailbox -SmtpAddress [email protected] | FT -AutoSize
WARNING: This command will take some time to complete. Please be patient.

  Counter CreateTime            ItemType     EventName     ObjectClass                                MailboxGuid                          ClientCategory       UserType ParentEntryId
  ------- ----------            --------     ---------     -----------                                -----------                          --------------       -------- -------------
 99999999 4/28/2016 12:50:27 PM MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100000001 4/28/2016 12:50:27 PM MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100000003 4/28/2016 12:50:27 PM MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100001179 4/28/2016 1:01:31 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 Transport                     00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001BD97D0000
100001180 4/28/2016 1:01:31 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 Transport                     00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100001184 4/28/2016 1:01:34 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100002827 4/28/2016 1:14:04 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100003580 4/28/2016 1:20:23 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 Transport                     00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001BD97D0000
100003581 4/28/2016 1:20:23 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 Transport                     00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100003585 4/28/2016 1:20:24 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100003590 4/28/2016 1:20:24 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100003780 4/28/2016 1:22:37 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100004093 4/28/2016 1:25:30 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 Transport                     00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001BD97D0000
100004094 4/28/2016 1:25:30 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 Transport                     00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100004126 4/28/2016 1:25:48 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100006291 4/28/2016 1:40:06 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100006589 4/28/2016 1:43:47 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100007329 4/28/2016 1:54:20 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 Transport                     00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001BD97D0000
100007330 4/28/2016 1:54:20 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 Transport                     00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100007338 4/28/2016 1:54:22 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100008983 4/28/2016 2:05:57 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 Transport                     00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001BD97D0000
100008984 4/28/2016 2:05:57 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 Transport                     00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100008997 4/28/2016 2:05:58 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100010278 4/28/2016 2:13:29 PM  MAPI_MESSAGE ObjectDeleted IPM.Schedule.Meeting.Request               5081e2de-4bff-422a-9601-eff4bd04fab3 EventBasedAssistants          00000000DA58A48EAD04D14E83249194E7B36105010022F02B7771143E4B8B48ABD43107FC9300000AF544800000
100010279 4/28/2016 2:13:29 PM  MAPI_MESSAGE ObjectDeleted IPM.Schedule.Meeting.Request               5081e2de-4bff-422a-9601-eff4bd04fab3 EventBasedAssistants          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100010424 4/28/2016 2:14:04 PM  MAPI_MESSAGE ObjectDeleted IPM.Appointment                            5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001CD03C0000
100010643 4/28/2016 2:16:15 PM  MAPI_MESSAGE ObjectDeleted IPM.Appointment                            5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010022F02B7771143E4B8B48ABD43107FC9300000AF544800000
100010644 4/28/2016 2:16:15 PM  MAPI_MESSAGE ObjectDeleted IPM.Appointment                            5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100010662 4/28/2016 2:16:16 PM  MAPI_MESSAGE ObjectDeleted IPM.Schedule.Meeting.Canceled              5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010022F02B7771143E4B8B48ABD43107FC9300000AF544800000
100010663 4/28/2016 2:16:16 PM  MAPI_MESSAGE ObjectDeleted IPM.Schedule.Meeting.Canceled              5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100010745 4/28/2016 2:16:37 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100010806 4/28/2016 2:16:56 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100015172 4/28/2016 2:43:27 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 Transport                     00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001BD97D0000
100015173 4/28/2016 2:43:27 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 Transport                     00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100015177 4/28/2016 2:43:29 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100015286 4/28/2016 2:44:14 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100022263 4/28/2016 3:13:05 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100023147 4/28/2016 3:17:52 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100023157 4/28/2016 3:17:53 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 Transport                     00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001BD97D0000
100023158 4/28/2016 3:17:53 PM  MAPI_MESSAGE ObjectDeleted IPM.Note                                   5081e2de-4bff-422a-9601-eff4bd04fab3 Transport                     00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001C60AF0000
100026697 4/28/2016 3:32:15 PM  MAPI_MESSAGE ObjectDeleted IPM.Appointment.MP                         5081e2de-4bff-422a-9601-eff4bd04fab3 MOMT                          00000000DA58A48EAD04D14E83249194E7B36105010025A7CA50FD477849BFCCB20CBA662EF20000001CD03C0000
100037710 4/28/2016 4:02:45 PM  MAPI_MESSAGE ObjectDeleted IPM.Contact                                5081e2de-4bff-422a-9601-eff4bd04fab3 TimeBasedAssistants           00000000DA58A48EAD04D14E83249194E7B36105010022F02B7771143E4B8B48ABD43107FC930000000060550000
100037711 4/28/2016 4:02:45 PM  MAPI_MESSAGE ObjectDeleted IPM.Contact                                5081e2de-4bff-422a-9601-eff4bd04fab3 TimeBasedAssistants           00000000DA58A48EAD04D14E83249194E7B36105010022F02B7771143E4B8B48ABD43107FC93000078A453560000
100037712 4/28/2016 4:02:45 PM  MAPI_MESSAGE ObjectDeleted IPM.Contact                                5081e2de-4bff-422a-9601-eff4bd04fab3 TimeBasedAssistants           00000000DA58A48EAD04D14E83249194E7B36105010022F02B7771143E4B8B48ABD43107FC93000078A457400000

Get-ImpactedUserCount
This command gets the total number of mailboxes on the database, as is listed in AD.

$dbs = Get-MailboxDatabase | Select -ExpandProperty Name
Get-ImpactedUserCount -Database $dbs
The total mailboxes on Database1 are 21
The total mailboxes on Database2 are 162
The total mailboxes on Database3 are 41
The total mailboxes on Database4 are 43
The total mailboxes are 267

Get-MailboxQuotaStatus
This command provides the current quota statistics for the mailbox in question.

Get-MailboxQuotaStatus -Identity [email protected] | FT -AutoSize

ExchangeGuid                         Quarantined UseDbDefaults TotItemSize                     MsgTblTotalSize                TotDelItemSize
------------                         ----------- ------------- -----------                     ---------------                --------------
594274b1-9e6f-45aa-b912-9ddb3797b57c       False         False 19.04 GB (20,447,468,845 bytes) 7.134 GB (7,659,716,608 bytes) 2.269 GB (2,435,837,443 bytes)


Get-MailboxQuotaStatus -Identity [email protected] -Archive | FT -AutoSize

ExchangeGuid                         Quarantined UseDbDefaults TotItemSize                     MsgTblTotalSize                 TotDelItemSize
------------                         ----------- ------------- -----------                     ---------------                 --------------
594274b1-9e6f-45aa-b912-9ddb3797b57c       False         False 60.81 GB (65,289,171,556 bytes) 15.13 GB (16,247,652,352 bytes) 532.7 KB (545,501 bytes)

Get-TotalItemCount
This command returns the total number of items contained within the MAPI message table.

Get-TotalItemCount -PrimarySmtp [email protected]
250194
Get-TotalItemCount -PrimarySmtp [email protected] -IncludeArchive
1249282

Get-TransportSendMomtEvents
This command looks for the MOMT events from a client (e.g.: Outlook) submission to StoreDriver.

Get-TransportSendMomtEvents -SenderSmtpAddress [email protected] -MessageId "<[email protected]>" | FT -AutoSize
WARNING: This command will take some time to complete. Please be patient.

  Counter ItemType     EventName     ObjectClass MailboxGuid                          ClientCategory ParentEntryId
  ------- --------     ---------     ----------- -----------                          -------------- -------------
172362630 MAPI_MESSAGE ObjectCreated IPM.Note    594274b1-9e6f-45aa-b912-9ddb3797b57c MOMT           000000004435FCF3C07DBE4F974F9D7A807901D00100BDCAB4A4117C7547B38E0314FA2AF58900000000000D0000
172362631 MAPI_MESSAGE ObjectCreated IPM.Note    594274b1-9e6f-45aa-b912-9ddb3797b57c MOMT           000000004435FCF3C07DBE4F974F9D7A807901D00100BDCAB4A4117C7547B38E0314FA2AF589000000000BE80000
172362632 MAPI_MESSAGE ObjectCreated IPM.Note    594274b1-9e6f-45aa-b912-9ddb3797b57c MOMT           000000004435FCF3C07DBE4F974F9D7A807901D00100BDCAB4A4117C7547B38E0314FA2AF58900009B0A1F4A0000
172362636 MAPI_MESSAGE MailSubmitted IPM.Note    594274b1-9e6f-45aa-b912-9ddb3797b57c MOMT           000000004435FCF3C07DBE4F974F9D7A807901D00100BDCAB4A4117C7547B38E0314FA2AF58900000000000D0000
172362645 MAPI_MESSAGE ObjectDeleted IPM.Note    594274b1-9e6f-45aa-b912-9ddb3797b57c Transport      000000004435FCF3C07DBE4F974F9D7A807901D00100BDCAB4A4117C7547B38E0314FA2AF58900000000000D0000
172362646 MAPI_MESSAGE ObjectDeleted IPM.Note    594274b1-9e6f-45aa-b912-9ddb3797b57c Transport      000000004435FCF3C07DBE4F974F9D7A807901D00100BDCAB4A4117C7547B38E0314FA2AF589000000000BE80000
172362647 MAPI_MESSAGE ObjectDeleted IPM.Note    594274b1-9e6f-45aa-b912-9ddb3797b57c Transport      000000004435FCF3C07DBE4F974F9D7A807901D00100BDCAB4A4117C7547B38E0314FA2AF58900009B0A1F4A0000

Get-ActiveUserCount
This command checks the perf counters of a specified server for both RPC and OWA user counters.

Get-ActiveUserCount -Server SERVER

ComputerName   	ListSet                    Source               Value
------------   	-------                    ------               -----
SERVER 		MSExchange RpcClientAccess Active User Count        2
SERVER 		MSExchange OWA             Current Unique Users     1

Get-FailedHeathSetItems
This command obtains only the failed HealthSet entries from a query against the server.

Get-FailedHeathSetItems -Server $Server -HealthSet OWA | FT -AutoSize

Server       State         Name                          TargetResource HealthSetName AlertValue ServerComponent
------       -----         ----                          -------------- ------------- ---------- ---------------
SERVER 	     NotApplicable MaintenanceFailureMonitor.OWA                OWA           Unhealthy  None

Get-UserFromSid
This command converts any SID you provide it to a NT Account (e.g.: Forest\user), as long as the SID is discover-able in AD.

Get-UserFromSid -Sid S-1-5-21-2127521184-1604012920-1887927527-8406844
Domain\User
Get-UserFromSid -Sid S-1-5-21-2014436394-2366853861-4082801726-2365144
Domain\User2

Restart-ServiceOnAllNodes
This command will restart a service you specify across all nodes in a DAG (Database Availability Group).

Restart-ServiceOnAllNodes -Dag DAG1 -Service MSExchangeMailboxAssistants
WARNING: The MSExchangeMailboxAssistants service on SERVER1 is stopping.
WARNING: The MSExchangeMailboxAssistants service on SERVER1 is starting.
WARNING: The MSExchangeMailboxAssistants service on SERVER1 is starting.
WARNING: The MSExchangeMailboxAssistants service on SERVER1 is starting.
WARNING: The MSExchangeMailboxAssistants service on SERVER1 is starting.
WARNING: The MSExchangeMailboxAssistants service on SERVER1 is starting.
WARNING: The MSExchangeMailboxAssistants service on SERVER1 is starting.
WARNING: The MSExchangeMailboxAssistants service on SERVER2 is starting.
WARNING: The MSExchangeMailboxAssistants service on SERVER2 is starting.

Start-DatabaseReseed
This command attempts to reseed a database from the mounted copy; which is the preferred (recommended) way to reseed a database, so that a fail-over copy is available for HA (assuming more than two copies exist).

Start-DatabaseReseed -DatabaseCopy $Copy -DeleteExistingFiles:$TRUE

Test-ClientOwaEndPoints
This command obtains the IP address entries for the name specified and attempts to perform an HTTP request against OWA.

Test-ClientOwaEndPoints mail.contoso.com | FT -AutoSize

IpAddress   OwaStatusCode
---------   -------------
38.96.29.10        Unused
38.96.29.10        Unused

Test-TcpConnectivity
This command uses the basic .NET TcpClient to make a TCP connection to the specified host on the specified port.

Test-TcpConnectivity -Endpoint mail.contoso.com -Port 25
True
Test-TcpConnectivity -Endpoint mail.contoso.com -Port 443
True
Test-TcpConnectivity -Endpoint mail.contoso.com -Port 444
Exception Caught: No connection could be made because the target machine actively refused it 10.221.254.5:444

Show-NetlogonImpact
This command shows the Netlogon counters for a specified machine.

Show-NetlogonImpact -Server SERVER -Intervals 3

ComputerName   Source             Value
------------   ------             -----
SERVER 		Semaphore Waiters      0
SERVER 		Semaphore Holders      0
SERVER 		Semaphore TimeOuts     0
SERVER 		Semaphore Acquires 48614

SERVER 		Semaphore Holders      0
SERVER 		Semaphore TimeOuts     0
SERVER 		Semaphore Waiters      0
SERVER 		Semaphore Acquires 48616

SERVER 		Semaphore Waiters      0
SERVER 		Semaphore Acquires 48616
SERVER 		Semaphore TimeOuts     0
SERVER 		Semaphore Holders      0

Download
To download the assembly, please visit the TechNet Gallery here.