May has been announced as the first “National Stop the Bleed” month. The “Stop the Bleed” campaign is trying to empower the general public to know how to deal with life-threatening emergencies usually involving rapid blood loss. There are many situations that this could be useful for a bystander, from car accidents to gardening disasters to gun shot injuries.
Raspberry Pi and the dreaded undervoltage notifications
I’ve been tinkering around a bit with some Raspberry Pi devices for a number of little projects. Most have been related to home automation type stuffs, but I built one with a 7” screen that I was going to be using for radio related things. Originally I had tossed together a small kit with an SDR for use on a camp because I knew we’d be out of range of cell phone service, but knew I could still take advantage of radio frequencies from satellites to get data, specifically weather images.
All seemed to go quite nicely, however I’d sporadically get a lightening bolt in the top right corner of the screen. I later learned that was a sign that the Pi wasn’t getting enough voltage. This baffled me, I was using a decent 5v power source, why would I get a low voltage issue? So I decided to do some research.
Set-DnsServerResourceRecord and OldInputObject not found
While trying to help a co-worker today, I stumbled across a documentation error on Microsoft’s TechNet in relation to Set-DnsServerResourceRecord
. The example uses multiple variable initialization, which unfortunately ends up making pointers.
Powershell and Single vs Double Quotes
There can be a lot of confusion over when to use single and double quotes in PowerShell. Not to worry, this confusion carries over in a lot of programming and scripting languages, such as Perl. I figured, after seeing this tweet, to give a quick run down of when to use which one.
Replace SSL on Office Web Apps Farm and certificate not found
The steps to replace the SSL certificate in your Microsoft Office Web Apps farm seem to be fairly simply, but we stumbled on an odd issue where it was complaining on some of the farm’s member servers that the certificate couldn’t be found.
Powershell and Progress Feedback
We’re in the process of enabling a new password reset portal, which requires additional licensing features in Office 365. There is no “apply all” button in Office 365, so we have to do this via script to tens of thousands of user accounts. The problem with this is some form of feedback to the user running the script. PowerShell has some really handy built in features, such as a progress bar. It’s amazing how something so simple can make you feel a little better, and actively see how things are moving along. Progress bars in PowerShell are incredibly simple.
Custom Windows installs, injecting drivers and features
One of the things about new platforms is you get to learn new technology. One of the bad things about new technology is that a lot of your old methods might not apply anymore, need to be revamped, or redesigned completely. Over the last few months I’ve been working on a Cisco UCS platform deployment for work. This has been quite exciting as it’s all new gear, and it’s implementing stuff that we should have been able to implement with our HP BladeSystem C7000 gear.
vSphere Storage vMotion times out at 32% when crossing SANs
A year or so ago we’d upgraded our vCenter from 4.1 to 5.1, and with this upgrade, and some features built into our SAN, we got access VAAI. For example, removing a VM guest would tell the SAN that the guest had been removed, and if the data store had been thinly provisioned from the SAN, it’d clean up and shrink down the space used (in theory).
Another feature we discovered was something called “fast copy”. In layman’s understanding of this feature, when a storage vMotion request was created, the SAN was notified of the request, and the SAN would process the copying of the bits in the background. This is handy because it stops the data from being sent from SAN to host to SAN again. This causes a good speed up with regards to moving machines around.
Enable-RemoteMailbox - The address is invalid
In the process of migrating our mailboxes from our on-premise Exchange servers to Office 365, we had to rewrite the mailbox enable scripts. This script keys off of our HR database, does some magic, then calls Enable-Mailbox
on Exchange 2010 servers. To update this to support creating mailboxes in Office 365, we needed to set user licenses, and use the Enable-RemoteMailbox
command in Exchange 20131.
One of the quirks we stumbled upon is a bug in the Exchange 2013 tools that didn’t allow it to identify the domain for the remote routing address. This is what we’d get:
[PS] C:\ > Enable-RemoteMailbox Jonathan.Angliss
The address '@mytenant.mail.onmicrosoft.com' is invalid: "@mytenant.mail.onmicrosoft.com" isn't a valid SMTP address. The domain name can't contain spaces and it has to have a prefix and a suffix, such as example.com.
+ CategoryInfo : NotSpecified: (:) [Enable-RemoteMailbox], DataValidationException
+ FullyQualifiedErrorId : [Server=Exchsvr01,RequestId=190c9764-d8bd-446e-ac43-7c80bcc54eea,TimeStamp=6/3/2014 1:19:33 PM] [FailureCategory=Cmdlet-DataValidationException] 730D5E7F,Microsoft.Exchange.Management.RecipientTasks.EnableRemoteMailbox
+ PSComputerName : Exchsvr01
According to the Microsoft documentation for Enable-RemoteMailbox
you should be able to specify just the sAMAccountName as an argument, the rest should be calculated.
The remote routing address doesn’t need to be specified because mail flow between the on-premises organization and the service has been configured. Using this configuration, the Enable-RemoteMailbox cmdlet automatically calculates the SMTP address of the mailbox to be used with the RemoteRoutingAddress parameter. — Microsoft TechNet
This apparently isn’t the case, so some tweaking was needed. We called upon Get-ADUser
to retreive the account, and fill in the rest.
[PS] C:\ > Get-ADUser jonathan.angliss | Enable-RemoteMailbox $_.sAMAccountName -RemoteRoutingAddress "$($_.sAMAccountName)@mytenant.mail.onmicrosoft.com"
As this is part of a script, the content is slightly different, but you can see how it works. We used Get-ADUser
earlier in the script to pull other user data to calculate licensing requirements, but if you’re doing this as a one off and are seeing the error then you could just as easily do this:
[PS] C:\ > Enable-RemoteMailbox jonathan.angliss -RemoteRoutingAddress 'jonathan.angliss@mytenant.mail.onmicrosoft.com'
Hat tip goes to Steve Goodman for posting similar work, and getting me back on track.
-
If you are using a 2010 Exchange environment, you need a 2013 server to act as a Hybrid server to migrate users. ↩
Exchange 2010, 2013, and Office365: Dynamic Distribution List Filters
In our transition to using Offce365 for email services, we’ve had some interesting discoveries. Some of them are revolving around Dynamic Distribution Lists (DDLs). These are groups which have members identified at time of delivery of emails, and are based on various styles of queries. We usually use PowerShell style queries to build the groups, but LDAP works, as does simple queries based on fixed parameters.
One of the interesting observations is that Exchange will tack extra query parameters into the DDL to exclude system mailboxes. For example the following query string:
(RecipientType -eq 'UserMailbox') -and (CustomAttribute4 -eq 'Plano')
Will actually result in the follow query:
((((RecipientType -eq 'UserMailbox') -and (CustomAttribute4 -eq 'Plano')) -and (-not(Name -like 'System{*'))
-and (-not(Name -like 'CAS_{*')) -and )-not(-not(RecintTypeDetailsValue -eq 'MailboxPlan'))
-and (-not(RecipientTypeDetailsValue -eq 'DiscoveryMailbox'))
-and (-not(RecipientTypeDetailsValue -eq 'ArbitrationMailbox')))
This forces Exchange to exclude any of the system mailboxes for delivery, which is what you want it to do. The problem is, this additional data varies from version to version, and it’s not always backwards compatible. One of the observations is that in Exchange 2013 they introduced a RecipientTypeDetailsValue
of PublicFolderMailbox
. This is great, except that value is invalid in 2010. What does that mean?
Let’s try an example. From one of our on-prem 2013 hyrbid servers, we’re going to create a new distribution group with the initial query we gave as an example above…
New-DynamicDistributionGroup -Name 'JATestDist' -RecipientFilter "(RecipientType -eq 'UserMailbox') -and (CustomAttribute4 -eq 'Plano')"
Now it’s created, lets see what we have for a query parameter:
PS C:\> Get-DynamicDistributionGroup -Identity 'JATestDist' | Select RecipientFilter | fl
RecipientFilter : ((((RecipientType -eq 'UserMailbox') -and (CustomAttribute4 -eq 'Plano'))) -and (-not(Name -like
'SystemMailbox{*')) -and (-not(Name -like 'CAS_{*')) -and (-not(RecipientTypeDetailsValue -eq
'MailboxPlan')) -and (-not(RecipientTypeDetailsValue -eq 'DiscoveryMailbox')) -and
(-not(RecipientTypeDetailsValue -eq 'PublicFolderMailbox')) -and (-not(RecipientTypeDetailsValue -eq
'ArbitrationMailbox')))
As we can see, a whole bunch of extra options, including our PublicFolderMailbox
option. Lets test to see what users we get back…
[PS] C:\>$dist1 = Get-DynamicDistributionGroup -Identity 'JATestDist'
[PS] C:\>Get-Recipient -RecipientPreviewFilter $dist1.RecipientFilter
$dist1 = Get-DynamicDistributionGroup -Identity 'JATestDist'
Get-Recipient -RecipientPreviewFilter $dist1.RecipientFilter
Name RecipientType
---- -------------
Angliss, Jon UserMailbox
Okay, so we get results back, no big deal right? Now I’m going to go to a 2010 server, and without changing anything, I’m going to see what results we get back…
[PS] C:\>$dist1 = Get-DynamicDistributionGroup -Identity 'JATestDist'
[PS] C:\>Get-Recipient -RecipientPreviewFilter $dist1.RecipientFilter
The recipient preview filter string "((((RecipientType -eq 'UserMailbox') -and (CustomAttribute4 -eq 'Plano'))) -and (-not(Name -like 'SystemMailbox{*')) -and (-not(Name -like 'CAS_{*')) -and (-not(RecipientTypeDetailsValue -eq 'MailboxPlan')) -and (-not(RecipientTypeDetailsValue -eq 'DiscoveryMailbox')) -and (-not(RecipientTypeDetailsValue -eq 'PublicFolderMailbox')) -and (-not(RecipientTypeDetailsValue -eq 'ArbitrationMailbox')))" is neither a valid OPath filter nor a valid LDAP filter. Use the -RecipientPreviewFilter parameter with either a valid OPath filter string or a valid LDAP filter string.
+ CategoryInfo : InvalidArgument: (:) [Get-Recipient], ArgumentException
+ FullyQualifiedErrorId : 79B22B5B,Microsoft.Exchange.Management.RecipientTasks.GetRecipient
Now we see an error. This is because 2010 doesn’t like PublicFolderMailbox
as a RecipientTypeDetailsValue
, and as such, throws it out as an error. So we have to go back to the 2010 server and edit the query, and reset it to be what we wanted originally:
[PS] C:\>Set-DynamicDistributionGroup -Identity 'JATestDist' -RecipientFilter "(RecipientType -eq 'UserMailbox') -and (CustomAttribute4 -eq 'Plano')"
[PS] C:\>$dist1 = Get-DynamicDistributionGroup -Identity 'JATestDist'
[PS] C:\>Get-Recipient -RecipientPreviewFilter $dist1.RecipientFilter
$dist1 = Get-DynamicDistributionGroup -Identity 'JATestDist'
Get-Recipient -RecipientPreviewFilter $dist1.RecipientFilter
Name RecipientType
---- -------------
Angliss, Jon UserMailbox
This same query is happy on the 2013 servers as well, however, it will attempt delivery to a Public Mailbox if your other query parameters allow for it. In the example above, we set the RecipientType
to be a very specific value, so this shouldn’t allow for this to happen anyway.
One other observation, when migrating your queries to be Office 365 Hybrid complaint, you will also need to include the RecipientType
of MailUser
. For example:
((RecipientType -eq 'UserMailbox') -or (RecipientType -eq 'MailUser')) -and (CustomAttribute4 -eq 'Plano')
Mailboxes that are migrated change their RecipientType
to be MailUser
.
There are lots of other fun things about DDLs that you’ll have to be aware of, which I shall cover in a separate post, but this is one of the fun gotchas I discovered in a mixed environment that’ll impact people using Exchange 2010 and 2013 in the same environment.